LCOV - code coverage report
Current view: top level - drivers - driver_nl80211.c (source / functions) Hit Total Coverage
Test: hostapd hwsim test run 1412854115 Lines: 2856 6140 46.5 %
Date: 2014-10-09 Functions: 199 306 65.0 %

          Line data    Source code
       1             : /*
       2             :  * Driver interaction with Linux nl80211/cfg80211
       3             :  * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
       4             :  * Copyright (c) 2003-2004, Instant802 Networks, Inc.
       5             :  * Copyright (c) 2005-2006, Devicescape Software, Inc.
       6             :  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
       7             :  * Copyright (c) 2009-2010, Atheros Communications
       8             :  *
       9             :  * This software may be distributed under the terms of the BSD license.
      10             :  * See README for more details.
      11             :  */
      12             : 
      13             : #include "includes.h"
      14             : #include <sys/ioctl.h>
      15             : #include <sys/types.h>
      16             : #include <sys/stat.h>
      17             : #include <fcntl.h>
      18             : #include <net/if.h>
      19             : #include <netlink/genl/genl.h>
      20             : #include <netlink/genl/family.h>
      21             : #include <netlink/genl/ctrl.h>
      22             : #ifdef CONFIG_LIBNL3_ROUTE
      23             : #include <netlink/route/neighbour.h>
      24             : #endif /* CONFIG_LIBNL3_ROUTE */
      25             : #include <linux/rtnetlink.h>
      26             : #include <netpacket/packet.h>
      27             : #include <linux/filter.h>
      28             : #include <linux/errqueue.h>
      29             : #include "nl80211_copy.h"
      30             : 
      31             : #include "common.h"
      32             : #include "eloop.h"
      33             : #include "utils/list.h"
      34             : #include "common/qca-vendor.h"
      35             : #include "common/qca-vendor-attr.h"
      36             : #include "common/ieee802_11_defs.h"
      37             : #include "common/ieee802_11_common.h"
      38             : #include "l2_packet/l2_packet.h"
      39             : #include "netlink.h"
      40             : #include "linux_ioctl.h"
      41             : #include "radiotap.h"
      42             : #include "radiotap_iter.h"
      43             : #include "rfkill.h"
      44             : #include "driver.h"
      45             : 
      46             : #ifndef SO_WIFI_STATUS
      47             : # if defined(__sparc__)
      48             : #  define SO_WIFI_STATUS        0x0025
      49             : # elif defined(__parisc__)
      50             : #  define SO_WIFI_STATUS        0x4022
      51             : # else
      52             : #  define SO_WIFI_STATUS        41
      53             : # endif
      54             : 
      55             : # define SCM_WIFI_STATUS        SO_WIFI_STATUS
      56             : #endif
      57             : 
      58             : #ifndef SO_EE_ORIGIN_TXSTATUS
      59             : #define SO_EE_ORIGIN_TXSTATUS   4
      60             : #endif
      61             : 
      62             : #ifndef PACKET_TX_TIMESTAMP
      63             : #define PACKET_TX_TIMESTAMP     16
      64             : #endif
      65             : 
      66             : #ifdef ANDROID
      67             : #include "android_drv.h"
      68             : #endif /* ANDROID */
      69             : #ifdef CONFIG_LIBNL20
      70             : /* libnl 2.0 compatibility code */
      71             : #define nl_handle nl_sock
      72             : #define nl80211_handle_alloc nl_socket_alloc_cb
      73             : #define nl80211_handle_destroy nl_socket_free
      74             : #else
      75             : /*
      76             :  * libnl 1.1 has a bug, it tries to allocate socket numbers densely
      77             :  * but when you free a socket again it will mess up its bitmap and
      78             :  * and use the wrong number the next time it needs a socket ID.
      79             :  * Therefore, we wrap the handle alloc/destroy and add our own pid
      80             :  * accounting.
      81             :  */
      82             : static uint32_t port_bitmap[32] = { 0 };
      83             : 
      84             : static struct nl_handle *nl80211_handle_alloc(void *cb)
      85             : {
      86             :         struct nl_handle *handle;
      87             :         uint32_t pid = getpid() & 0x3FFFFF;
      88             :         int i;
      89             : 
      90             :         handle = nl_handle_alloc_cb(cb);
      91             : 
      92             :         for (i = 0; i < 1024; i++) {
      93             :                 if (port_bitmap[i / 32] & (1 << (i % 32)))
      94             :                         continue;
      95             :                 port_bitmap[i / 32] |= 1 << (i % 32);
      96             :                 pid += i << 22;
      97             :                 break;
      98             :         }
      99             : 
     100             :         nl_socket_set_local_port(handle, pid);
     101             : 
     102             :         return handle;
     103             : }
     104             : 
     105             : static void nl80211_handle_destroy(struct nl_handle *handle)
     106             : {
     107             :         uint32_t port = nl_socket_get_local_port(handle);
     108             : 
     109             :         port >>= 22;
     110             :         port_bitmap[port / 32] &= ~(1 << (port % 32));
     111             : 
     112             :         nl_handle_destroy(handle);
     113             : }
     114             : #endif /* CONFIG_LIBNL20 */
     115             : 
     116             : 
     117             : #ifdef ANDROID
     118             : /* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
     119             : static int android_nl_socket_set_nonblocking(struct nl_handle *handle)
     120             : {
     121             :         return fcntl(nl_socket_get_fd(handle), F_SETFL, O_NONBLOCK);
     122             : }
     123             : #undef nl_socket_set_nonblocking
     124             : #define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h)
     125             : #endif /* ANDROID */
     126             : 
     127             : 
     128        1283 : static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
     129             : {
     130             :         struct nl_handle *handle;
     131             : 
     132        1283 :         handle = nl80211_handle_alloc(cb);
     133        1283 :         if (handle == NULL) {
     134           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
     135             :                            "callbacks (%s)", dbg);
     136           0 :                 return NULL;
     137             :         }
     138             : 
     139        1283 :         if (genl_connect(handle)) {
     140           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
     141             :                            "netlink (%s)", dbg);
     142           0 :                 nl80211_handle_destroy(handle);
     143           0 :                 return NULL;
     144             :         }
     145             : 
     146        1283 :         return handle;
     147             : }
     148             : 
     149             : 
     150        1283 : static void nl_destroy_handles(struct nl_handle **handle)
     151             : {
     152        1283 :         if (*handle == NULL)
     153        1283 :                 return;
     154        1283 :         nl80211_handle_destroy(*handle);
     155        1283 :         *handle = NULL;
     156             : }
     157             : 
     158             : 
     159             : #if __WORDSIZE == 64
     160             : #define ELOOP_SOCKET_INVALID    (intptr_t) 0x8888888888888889ULL
     161             : #else
     162             : #define ELOOP_SOCKET_INVALID    (intptr_t) 0x88888889ULL
     163             : #endif
     164             : 
     165        1282 : static void nl80211_register_eloop_read(struct nl_handle **handle,
     166             :                                         eloop_sock_handler handler,
     167             :                                         void *eloop_data)
     168             : {
     169        1282 :         nl_socket_set_nonblocking(*handle);
     170        1282 :         eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
     171             :                                  eloop_data, *handle);
     172        1282 :         *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
     173        1282 : }
     174             : 
     175             : 
     176        1282 : static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
     177             : {
     178        1282 :         *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
     179        1282 :         eloop_unregister_read_sock(nl_socket_get_fd(*handle));
     180        1282 :         nl_destroy_handles(handle);
     181        1282 : }
     182             : 
     183             : 
     184             : #ifndef IFF_LOWER_UP
     185             : #define IFF_LOWER_UP   0x10000         /* driver signals L1 up         */
     186             : #endif
     187             : #ifndef IFF_DORMANT
     188             : #define IFF_DORMANT    0x20000         /* driver signals dormant       */
     189             : #endif
     190             : 
     191             : #ifndef IF_OPER_DORMANT
     192             : #define IF_OPER_DORMANT 5
     193             : #endif
     194             : #ifndef IF_OPER_UP
     195             : #define IF_OPER_UP 6
     196             : #endif
     197             : 
     198             : struct nl80211_global {
     199             :         struct dl_list interfaces;
     200             :         int if_add_ifindex;
     201             :         u64 if_add_wdevid;
     202             :         int if_add_wdevid_set;
     203             :         struct netlink_data *netlink;
     204             :         struct nl_cb *nl_cb;
     205             :         struct nl_handle *nl;
     206             :         int nl80211_id;
     207             :         int ioctl_sock; /* socket for ioctl() use */
     208             : 
     209             :         struct nl_handle *nl_event;
     210             : };
     211             : 
     212             : struct nl80211_wiphy_data {
     213             :         struct dl_list list;
     214             :         struct dl_list bsss;
     215             :         struct dl_list drvs;
     216             : 
     217             :         struct nl_handle *nl_beacons;
     218             :         struct nl_cb *nl_cb;
     219             : 
     220             :         int wiphy_idx;
     221             : };
     222             : 
     223             : static void nl80211_global_deinit(void *priv);
     224             : 
     225             : struct i802_bss {
     226             :         struct wpa_driver_nl80211_data *drv;
     227             :         struct i802_bss *next;
     228             :         int ifindex;
     229             :         u64 wdev_id;
     230             :         char ifname[IFNAMSIZ + 1];
     231             :         char brname[IFNAMSIZ];
     232             :         unsigned int beacon_set:1;
     233             :         unsigned int added_if_into_bridge:1;
     234             :         unsigned int added_bridge:1;
     235             :         unsigned int in_deinit:1;
     236             :         unsigned int wdev_id_set:1;
     237             :         unsigned int added_if:1;
     238             :         unsigned int static_ap:1;
     239             : 
     240             :         u8 addr[ETH_ALEN];
     241             : 
     242             :         int freq;
     243             :         int bandwidth;
     244             :         int if_dynamic;
     245             : 
     246             :         void *ctx;
     247             :         struct nl_handle *nl_preq, *nl_mgmt;
     248             :         struct nl_cb *nl_cb;
     249             : 
     250             :         struct nl80211_wiphy_data *wiphy_data;
     251             :         struct dl_list wiphy_list;
     252             : };
     253             : 
     254             : struct wpa_driver_nl80211_data {
     255             :         struct nl80211_global *global;
     256             :         struct dl_list list;
     257             :         struct dl_list wiphy_list;
     258             :         char phyname[32];
     259             :         u8 perm_addr[ETH_ALEN];
     260             :         void *ctx;
     261             :         int ifindex;
     262             :         int if_removed;
     263             :         int if_disabled;
     264             :         int ignore_if_down_event;
     265             :         struct rfkill_data *rfkill;
     266             :         struct wpa_driver_capa capa;
     267             :         u8 *extended_capa, *extended_capa_mask;
     268             :         unsigned int extended_capa_len;
     269             :         int has_capability;
     270             : 
     271             :         int operstate;
     272             : 
     273             :         int scan_complete_events;
     274             :         enum scan_states {
     275             :                 NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
     276             :                 SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
     277             :                 SCHED_SCAN_RESULTS
     278             :         } scan_state;
     279             : 
     280             :         struct nl_cb *nl_cb;
     281             : 
     282             :         u8 auth_bssid[ETH_ALEN];
     283             :         u8 auth_attempt_bssid[ETH_ALEN];
     284             :         u8 bssid[ETH_ALEN];
     285             :         u8 prev_bssid[ETH_ALEN];
     286             :         int associated;
     287             :         u8 ssid[32];
     288             :         size_t ssid_len;
     289             :         enum nl80211_iftype nlmode;
     290             :         enum nl80211_iftype ap_scan_as_station;
     291             :         unsigned int assoc_freq;
     292             : 
     293             :         int monitor_sock;
     294             :         int monitor_ifidx;
     295             :         int monitor_refcount;
     296             : 
     297             :         unsigned int disabled_11b_rates:1;
     298             :         unsigned int pending_remain_on_chan:1;
     299             :         unsigned int in_interface_list:1;
     300             :         unsigned int device_ap_sme:1;
     301             :         unsigned int poll_command_supported:1;
     302             :         unsigned int data_tx_status:1;
     303             :         unsigned int scan_for_auth:1;
     304             :         unsigned int retry_auth:1;
     305             :         unsigned int use_monitor:1;
     306             :         unsigned int ignore_next_local_disconnect:1;
     307             :         unsigned int ignore_next_local_deauth:1;
     308             :         unsigned int allow_p2p_device:1;
     309             :         unsigned int hostapd:1;
     310             :         unsigned int start_mode_ap:1;
     311             :         unsigned int start_iface_up:1;
     312             :         unsigned int test_use_roc_tx:1;
     313             :         unsigned int ignore_deauth_event:1;
     314             :         unsigned int roaming_vendor_cmd_avail:1;
     315             :         unsigned int dfs_vendor_cmd_avail:1;
     316             :         unsigned int have_low_prio_scan:1;
     317             :         unsigned int force_connect_cmd:1;
     318             :         unsigned int addr_changed:1;
     319             : 
     320             :         u64 remain_on_chan_cookie;
     321             :         u64 send_action_cookie;
     322             : 
     323             :         unsigned int last_mgmt_freq;
     324             : 
     325             :         struct wpa_driver_scan_filter *filter_ssids;
     326             :         size_t num_filter_ssids;
     327             : 
     328             :         struct i802_bss *first_bss;
     329             : 
     330             :         int eapol_tx_sock;
     331             : 
     332             :         int eapol_sock; /* socket for EAPOL frames */
     333             : 
     334             :         struct nl_handle *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
     335             : 
     336             :         int default_if_indices[16];
     337             :         int *if_indices;
     338             :         int num_if_indices;
     339             : 
     340             :         /* From failed authentication command */
     341             :         int auth_freq;
     342             :         u8 auth_bssid_[ETH_ALEN];
     343             :         u8 auth_ssid[32];
     344             :         size_t auth_ssid_len;
     345             :         int auth_alg;
     346             :         u8 *auth_ie;
     347             :         size_t auth_ie_len;
     348             :         u8 auth_wep_key[4][16];
     349             :         size_t auth_wep_key_len[4];
     350             :         int auth_wep_tx_keyidx;
     351             :         int auth_local_state_change;
     352             :         int auth_p2p;
     353             : };
     354             : 
     355             : 
     356             : static void wpa_driver_nl80211_deinit(struct i802_bss *bss);
     357             : static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
     358             :                                             void *timeout_ctx);
     359             : static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
     360             :                                        enum nl80211_iftype nlmode);
     361             : static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
     362             :                                             struct hostapd_freq_params *freq);
     363             : 
     364             : static int
     365             : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
     366             :                                    const u8 *set_addr, int first);
     367             : static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
     368             :                                    const u8 *addr, int cmd, u16 reason_code,
     369             :                                    int local_state_change);
     370             : static void nl80211_remove_monitor_interface(
     371             :         struct wpa_driver_nl80211_data *drv);
     372             : static int nl80211_send_frame_cmd(struct i802_bss *bss,
     373             :                                   unsigned int freq, unsigned int wait,
     374             :                                   const u8 *buf, size_t buf_len, u64 *cookie,
     375             :                                   int no_cck, int no_ack, int offchanok);
     376             : static int nl80211_register_frame(struct i802_bss *bss,
     377             :                                   struct nl_handle *hl_handle,
     378             :                                   u16 type, const u8 *match, size_t match_len);
     379             : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
     380             :                                                int report);
     381             : #ifdef ANDROID
     382             : static int android_pno_start(struct i802_bss *bss,
     383             :                              struct wpa_driver_scan_params *params);
     384             : static int android_pno_stop(struct i802_bss *bss);
     385             : extern int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
     386             :                                          size_t buf_len);
     387             : #endif /* ANDROID */
     388             : #ifdef ANDROID_P2P
     389             : #ifdef ANDROID_P2P_STUB
     390             : int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration) {
     391             :         return 0;
     392             : }
     393             : int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len) {
     394             :         return 0;
     395             : }
     396             : int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow) {
     397             :         return -1;
     398             : }
     399             : int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
     400             :                                  const struct wpabuf *proberesp,
     401             :                                  const struct wpabuf *assocresp) {
     402             :         return 0;
     403             : }
     404             : #else /* ANDROID_P2P_STUB */
     405             : int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration);
     406             : int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len);
     407             : int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow);
     408             : int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
     409             :                                  const struct wpabuf *proberesp,
     410             :                                  const struct wpabuf *assocresp);
     411             : #endif /* ANDROID_P2P_STUB */
     412             : #endif /* ANDROID_P2P */
     413             : 
     414             : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
     415             : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
     416             : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
     417             : static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
     418             :                                         enum wpa_driver_if_type type,
     419             :                                         const char *ifname);
     420             : 
     421             : static int nl80211_set_channel(struct i802_bss *bss,
     422             :                                struct hostapd_freq_params *freq, int set_chan);
     423             : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
     424             :                                      int ifindex, int disabled);
     425             : 
     426             : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
     427             : static int wpa_driver_nl80211_authenticate_retry(
     428             :         struct wpa_driver_nl80211_data *drv);
     429             : 
     430             : static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
     431             : static int i802_set_iface_flags(struct i802_bss *bss, int up);
     432             : 
     433             : 
     434       21648 : static const char * nl80211_command_to_string(enum nl80211_commands cmd)
     435             : {
     436             : #define C2S(x) case x: return #x;
     437       21648 :         switch (cmd) {
     438           0 :         C2S(NL80211_CMD_UNSPEC)
     439           0 :         C2S(NL80211_CMD_GET_WIPHY)
     440           0 :         C2S(NL80211_CMD_SET_WIPHY)
     441           0 :         C2S(NL80211_CMD_NEW_WIPHY)
     442           0 :         C2S(NL80211_CMD_DEL_WIPHY)
     443           0 :         C2S(NL80211_CMD_GET_INTERFACE)
     444           0 :         C2S(NL80211_CMD_SET_INTERFACE)
     445           0 :         C2S(NL80211_CMD_NEW_INTERFACE)
     446           0 :         C2S(NL80211_CMD_DEL_INTERFACE)
     447           0 :         C2S(NL80211_CMD_GET_KEY)
     448           0 :         C2S(NL80211_CMD_SET_KEY)
     449           0 :         C2S(NL80211_CMD_NEW_KEY)
     450           0 :         C2S(NL80211_CMD_DEL_KEY)
     451           0 :         C2S(NL80211_CMD_GET_BEACON)
     452           0 :         C2S(NL80211_CMD_SET_BEACON)
     453           0 :         C2S(NL80211_CMD_START_AP)
     454           0 :         C2S(NL80211_CMD_STOP_AP)
     455           0 :         C2S(NL80211_CMD_GET_STATION)
     456           0 :         C2S(NL80211_CMD_SET_STATION)
     457        1299 :         C2S(NL80211_CMD_NEW_STATION)
     458        1252 :         C2S(NL80211_CMD_DEL_STATION)
     459           0 :         C2S(NL80211_CMD_GET_MPATH)
     460           0 :         C2S(NL80211_CMD_SET_MPATH)
     461           0 :         C2S(NL80211_CMD_NEW_MPATH)
     462           0 :         C2S(NL80211_CMD_DEL_MPATH)
     463           0 :         C2S(NL80211_CMD_SET_BSS)
     464           0 :         C2S(NL80211_CMD_SET_REG)
     465           0 :         C2S(NL80211_CMD_REQ_SET_REG)
     466           0 :         C2S(NL80211_CMD_GET_MESH_CONFIG)
     467           0 :         C2S(NL80211_CMD_SET_MESH_CONFIG)
     468           0 :         C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
     469           0 :         C2S(NL80211_CMD_GET_REG)
     470           0 :         C2S(NL80211_CMD_GET_SCAN)
     471          68 :         C2S(NL80211_CMD_TRIGGER_SCAN)
     472          63 :         C2S(NL80211_CMD_NEW_SCAN_RESULTS)
     473           0 :         C2S(NL80211_CMD_SCAN_ABORTED)
     474         794 :         C2S(NL80211_CMD_REG_CHANGE)
     475           0 :         C2S(NL80211_CMD_AUTHENTICATE)
     476           0 :         C2S(NL80211_CMD_ASSOCIATE)
     477           0 :         C2S(NL80211_CMD_DEAUTHENTICATE)
     478           0 :         C2S(NL80211_CMD_DISASSOCIATE)
     479           2 :         C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
     480           6 :         C2S(NL80211_CMD_REG_BEACON_HINT)
     481           0 :         C2S(NL80211_CMD_JOIN_IBSS)
     482           0 :         C2S(NL80211_CMD_LEAVE_IBSS)
     483           0 :         C2S(NL80211_CMD_TESTMODE)
     484           0 :         C2S(NL80211_CMD_CONNECT)
     485           0 :         C2S(NL80211_CMD_ROAM)
     486           0 :         C2S(NL80211_CMD_DISCONNECT)
     487           0 :         C2S(NL80211_CMD_SET_WIPHY_NETNS)
     488           0 :         C2S(NL80211_CMD_GET_SURVEY)
     489           0 :         C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
     490           0 :         C2S(NL80211_CMD_SET_PMKSA)
     491           0 :         C2S(NL80211_CMD_DEL_PMKSA)
     492           0 :         C2S(NL80211_CMD_FLUSH_PMKSA)
     493           0 :         C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
     494           0 :         C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
     495           0 :         C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
     496           0 :         C2S(NL80211_CMD_REGISTER_FRAME)
     497       11124 :         C2S(NL80211_CMD_FRAME)
     498        7022 :         C2S(NL80211_CMD_FRAME_TX_STATUS)
     499           0 :         C2S(NL80211_CMD_SET_POWER_SAVE)
     500           0 :         C2S(NL80211_CMD_GET_POWER_SAVE)
     501           0 :         C2S(NL80211_CMD_SET_CQM)
     502           0 :         C2S(NL80211_CMD_NOTIFY_CQM)
     503           0 :         C2S(NL80211_CMD_SET_CHANNEL)
     504           0 :         C2S(NL80211_CMD_SET_WDS_PEER)
     505           0 :         C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
     506           0 :         C2S(NL80211_CMD_JOIN_MESH)
     507           0 :         C2S(NL80211_CMD_LEAVE_MESH)
     508           2 :         C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
     509           0 :         C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
     510           0 :         C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
     511           0 :         C2S(NL80211_CMD_GET_WOWLAN)
     512           0 :         C2S(NL80211_CMD_SET_WOWLAN)
     513           0 :         C2S(NL80211_CMD_START_SCHED_SCAN)
     514           0 :         C2S(NL80211_CMD_STOP_SCHED_SCAN)
     515           0 :         C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
     516           0 :         C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
     517           0 :         C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
     518           0 :         C2S(NL80211_CMD_PMKSA_CANDIDATE)
     519           0 :         C2S(NL80211_CMD_TDLS_OPER)
     520           0 :         C2S(NL80211_CMD_TDLS_MGMT)
     521           6 :         C2S(NL80211_CMD_UNEXPECTED_FRAME)
     522           2 :         C2S(NL80211_CMD_PROBE_CLIENT)
     523           0 :         C2S(NL80211_CMD_REGISTER_BEACONS)
     524           1 :         C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
     525           0 :         C2S(NL80211_CMD_SET_NOACK_MAP)
     526           1 :         C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
     527           0 :         C2S(NL80211_CMD_START_P2P_DEVICE)
     528           0 :         C2S(NL80211_CMD_STOP_P2P_DEVICE)
     529           0 :         C2S(NL80211_CMD_CONN_FAILED)
     530           0 :         C2S(NL80211_CMD_SET_MCAST_RATE)
     531           0 :         C2S(NL80211_CMD_SET_MAC_ACL)
     532           6 :         C2S(NL80211_CMD_RADAR_DETECT)
     533           0 :         C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
     534           0 :         C2S(NL80211_CMD_UPDATE_FT_IES)
     535           0 :         C2S(NL80211_CMD_FT_EVENT)
     536           0 :         C2S(NL80211_CMD_CRIT_PROTOCOL_START)
     537           0 :         C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
     538           0 :         C2S(NL80211_CMD_GET_COALESCE)
     539           0 :         C2S(NL80211_CMD_SET_COALESCE)
     540           0 :         C2S(NL80211_CMD_CHANNEL_SWITCH)
     541           0 :         C2S(NL80211_CMD_VENDOR)
     542           0 :         C2S(NL80211_CMD_SET_QOS_MAP)
     543             :         default:
     544           0 :                 return "NL80211_CMD_UNKNOWN";
     545             :         }
     546             : #undef C2S
     547             : }
     548             : 
     549             : 
     550             : /* Converts nl80211_chan_width to a common format */
     551           7 : static enum chan_width convert2width(int width)
     552             : {
     553           7 :         switch (width) {
     554             :         case NL80211_CHAN_WIDTH_20_NOHT:
     555           0 :                 return CHAN_WIDTH_20_NOHT;
     556             :         case NL80211_CHAN_WIDTH_20:
     557           5 :                 return CHAN_WIDTH_20;
     558             :         case NL80211_CHAN_WIDTH_40:
     559           0 :                 return CHAN_WIDTH_40;
     560             :         case NL80211_CHAN_WIDTH_80:
     561           0 :                 return CHAN_WIDTH_80;
     562             :         case NL80211_CHAN_WIDTH_80P80:
     563           0 :                 return CHAN_WIDTH_80P80;
     564             :         case NL80211_CHAN_WIDTH_160:
     565           2 :                 return CHAN_WIDTH_160;
     566             :         }
     567           0 :         return CHAN_WIDTH_UNKNOWN;
     568             : }
     569             : 
     570             : 
     571       12117 : static int is_ap_interface(enum nl80211_iftype nlmode)
     572             : {
     573       12117 :         return nlmode == NL80211_IFTYPE_AP ||
     574             :                 nlmode == NL80211_IFTYPE_P2P_GO;
     575             : }
     576             : 
     577             : 
     578        6020 : static int is_sta_interface(enum nl80211_iftype nlmode)
     579             : {
     580        6020 :         return nlmode == NL80211_IFTYPE_STATION ||
     581             :                 nlmode == NL80211_IFTYPE_P2P_CLIENT;
     582             : }
     583             : 
     584             : 
     585        1293 : static int is_p2p_net_interface(enum nl80211_iftype nlmode)
     586             : {
     587        1293 :         return nlmode == NL80211_IFTYPE_P2P_CLIENT ||
     588             :                 nlmode == NL80211_IFTYPE_P2P_GO;
     589             : }
     590             : 
     591             : 
     592           1 : static struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
     593             :                                          int ifindex)
     594             : {
     595             :         struct i802_bss *bss;
     596             : 
     597           1 :         for (bss = drv->first_bss; bss; bss = bss->next) {
     598           1 :                 if (bss->ifindex == ifindex)
     599           1 :                         return bss;
     600             :         }
     601             : 
     602           0 :         return NULL;
     603             : }
     604             : 
     605             : 
     606           0 : static void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
     607             : {
     608           0 :         if (drv->associated)
     609           0 :                 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
     610           0 :         drv->associated = 0;
     611           0 :         os_memset(drv->bssid, 0, ETH_ALEN);
     612           0 : }
     613             : 
     614             : 
     615             : struct nl80211_bss_info_arg {
     616             :         struct wpa_driver_nl80211_data *drv;
     617             :         struct wpa_scan_results *res;
     618             :         unsigned int assoc_freq;
     619             :         unsigned int ibss_freq;
     620             :         u8 assoc_bssid[ETH_ALEN];
     621             : };
     622             : 
     623             : static int bss_info_handler(struct nl_msg *msg, void *arg);
     624             : 
     625             : 
     626             : /* nl80211 code */
     627       33956 : static int ack_handler(struct nl_msg *msg, void *arg)
     628             : {
     629       33956 :         int *err = arg;
     630       33956 :         *err = 0;
     631       33956 :         return NL_STOP;
     632             : }
     633             : 
     634        1353 : static int finish_handler(struct nl_msg *msg, void *arg)
     635             : {
     636        1353 :         int *ret = arg;
     637        1353 :         *ret = 0;
     638        1353 :         return NL_SKIP;
     639             : }
     640             : 
     641        8991 : static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
     642             :                          void *arg)
     643             : {
     644        8991 :         int *ret = arg;
     645        8991 :         *ret = err->error;
     646        8991 :         return NL_SKIP;
     647             : }
     648             : 
     649             : 
     650      160170 : static int no_seq_check(struct nl_msg *msg, void *arg)
     651             : {
     652      160170 :         return NL_OK;
     653             : }
     654             : 
     655             : 
     656       44300 : static int send_and_recv(struct nl80211_global *global,
     657             :                          struct nl_handle *nl_handle, struct nl_msg *msg,
     658             :                          int (*valid_handler)(struct nl_msg *, void *),
     659             :                          void *valid_data)
     660             : {
     661             :         struct nl_cb *cb;
     662       44300 :         int err = -ENOMEM;
     663             : 
     664       44300 :         cb = nl_cb_clone(global->nl_cb);
     665       44300 :         if (!cb)
     666           0 :                 goto out;
     667             : 
     668       44300 :         err = nl_send_auto_complete(nl_handle, msg);
     669       44300 :         if (err < 0)
     670           0 :                 goto out;
     671             : 
     672       44300 :         err = 1;
     673             : 
     674       44300 :         nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
     675       44300 :         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
     676       44300 :         nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
     677             : 
     678       44300 :         if (valid_handler)
     679       13365 :                 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
     680             :                           valid_handler, valid_data);
     681             : 
     682      143055 :         while (err > 0) {
     683       54455 :                 int res = nl_recvmsgs(nl_handle, cb);
     684       54455 :                 if (res < 0) {
     685           0 :                         wpa_printf(MSG_INFO,
     686             :                                    "nl80211: %s->nl_recvmsgs failed: %d",
     687             :                                    __func__, res);
     688             :                 }
     689             :         }
     690             :  out:
     691       44300 :         nl_cb_put(cb);
     692       44300 :         nlmsg_free(msg);
     693       44300 :         return err;
     694             : }
     695             : 
     696             : 
     697           4 : static int send_and_recv_msgs_global(struct nl80211_global *global,
     698             :                                      struct nl_msg *msg,
     699             :                                      int (*valid_handler)(struct nl_msg *, void *),
     700             :                                      void *valid_data)
     701             : {
     702           4 :         return send_and_recv(global, global->nl, msg, valid_handler,
     703             :                              valid_data);
     704             : }
     705             : 
     706             : 
     707       38465 : static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
     708             :                               struct nl_msg *msg,
     709             :                               int (*valid_handler)(struct nl_msg *, void *),
     710             :                               void *valid_data)
     711             : {
     712       38465 :         return send_and_recv(drv->global, drv->global->nl, msg,
     713             :                              valid_handler, valid_data);
     714             : }
     715             : 
     716             : 
     717             : struct family_data {
     718             :         const char *group;
     719             :         int id;
     720             : };
     721             : 
     722             : 
     723       16331 : static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
     724             : {
     725       16331 :         if (bss->wdev_id_set)
     726           0 :                 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
     727             :         else
     728       16331 :                 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
     729       16331 :         return 0;
     730             : 
     731             : nla_put_failure:
     732           0 :         return -1;
     733             : }
     734             : 
     735             : 
     736           4 : static int family_handler(struct nl_msg *msg, void *arg)
     737             : {
     738           4 :         struct family_data *res = arg;
     739             :         struct nlattr *tb[CTRL_ATTR_MAX + 1];
     740           4 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
     741             :         struct nlattr *mcgrp;
     742             :         int i;
     743             : 
     744           4 :         nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
     745             :                   genlmsg_attrlen(gnlh, 0), NULL);
     746           4 :         if (!tb[CTRL_ATTR_MCAST_GROUPS])
     747           0 :                 return NL_SKIP;
     748             : 
     749          28 :         nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
     750             :                 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
     751          14 :                 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
     752             :                           nla_len(mcgrp), NULL);
     753          28 :                 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
     754          28 :                     !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
     755          14 :                     os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
     756             :                                res->group,
     757             :                                nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
     758          10 :                         continue;
     759           4 :                 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
     760           4 :                 break;
     761             :         };
     762             : 
     763           4 :         return NL_SKIP;
     764             : }
     765             : 
     766             : 
     767           4 : static int nl_get_multicast_id(struct nl80211_global *global,
     768             :                                const char *family, const char *group)
     769             : {
     770             :         struct nl_msg *msg;
     771           4 :         int ret = -1;
     772           4 :         struct family_data res = { group, -ENOENT };
     773             : 
     774           4 :         msg = nlmsg_alloc();
     775           4 :         if (!msg)
     776           0 :                 return -ENOMEM;
     777           4 :         genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
     778             :                     0, 0, CTRL_CMD_GETFAMILY, 0);
     779           4 :         NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
     780             : 
     781           4 :         ret = send_and_recv_msgs_global(global, msg, family_handler, &res);
     782           4 :         msg = NULL;
     783           4 :         if (ret == 0)
     784           4 :                 ret = res.id;
     785             : 
     786             : nla_put_failure:
     787           4 :         nlmsg_free(msg);
     788           4 :         return ret;
     789             : }
     790             : 
     791             : 
     792       44297 : static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
     793             :                           struct nl_msg *msg, int flags, uint8_t cmd)
     794             : {
     795       44297 :         return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
     796             :                            0, flags, cmd, 0);
     797             : }
     798             : 
     799             : 
     800             : struct wiphy_idx_data {
     801             :         int wiphy_idx;
     802             :         enum nl80211_iftype nlmode;
     803             :         u8 *macaddr;
     804             : };
     805             : 
     806             : 
     807        3176 : static int netdev_info_handler(struct nl_msg *msg, void *arg)
     808             : {
     809             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
     810        3176 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
     811        3176 :         struct wiphy_idx_data *info = arg;
     812             : 
     813        3176 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
     814             :                   genlmsg_attrlen(gnlh, 0), NULL);
     815             : 
     816        3176 :         if (tb[NL80211_ATTR_WIPHY])
     817        3176 :                 info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
     818             : 
     819        3176 :         if (tb[NL80211_ATTR_IFTYPE])
     820        3176 :                 info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
     821             : 
     822        3176 :         if (tb[NL80211_ATTR_MAC] && info->macaddr)
     823           0 :                 os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
     824             :                           ETH_ALEN);
     825             : 
     826        3176 :         return NL_SKIP;
     827             : }
     828             : 
     829             : 
     830         650 : static int nl80211_get_wiphy_index(struct i802_bss *bss)
     831             : {
     832             :         struct nl_msg *msg;
     833         650 :         struct wiphy_idx_data data = {
     834             :                 .wiphy_idx = -1,
     835             :                 .macaddr = NULL,
     836             :         };
     837             : 
     838         650 :         msg = nlmsg_alloc();
     839         650 :         if (!msg)
     840           0 :                 return NL80211_IFTYPE_UNSPECIFIED;
     841             : 
     842         650 :         nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
     843             : 
     844         650 :         if (nl80211_set_iface_id(msg, bss) < 0)
     845           0 :                 goto nla_put_failure;
     846             : 
     847         650 :         if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
     848         650 :                 return data.wiphy_idx;
     849           0 :         msg = NULL;
     850             : nla_put_failure:
     851           0 :         nlmsg_free(msg);
     852           0 :         return -1;
     853             : }
     854             : 
     855             : 
     856        2526 : static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
     857             : {
     858             :         struct nl_msg *msg;
     859        2526 :         struct wiphy_idx_data data = {
     860             :                 .nlmode = NL80211_IFTYPE_UNSPECIFIED,
     861             :                 .macaddr = NULL,
     862             :         };
     863             : 
     864        2526 :         msg = nlmsg_alloc();
     865        2526 :         if (!msg)
     866           0 :                 return -1;
     867             : 
     868        2526 :         nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
     869             : 
     870        2526 :         if (nl80211_set_iface_id(msg, bss) < 0)
     871           0 :                 goto nla_put_failure;
     872             : 
     873        2526 :         if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
     874        2526 :                 return data.nlmode;
     875           0 :         msg = NULL;
     876             : nla_put_failure:
     877           0 :         nlmsg_free(msg);
     878           0 :         return NL80211_IFTYPE_UNSPECIFIED;
     879             : }
     880             : 
     881             : 
     882           0 : static int nl80211_get_macaddr(struct i802_bss *bss)
     883             : {
     884             :         struct nl_msg *msg;
     885           0 :         struct wiphy_idx_data data = {
     886           0 :                 .macaddr = bss->addr,
     887             :         };
     888             : 
     889           0 :         msg = nlmsg_alloc();
     890           0 :         if (!msg)
     891           0 :                 return NL80211_IFTYPE_UNSPECIFIED;
     892             : 
     893           0 :         nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
     894           0 :         if (nl80211_set_iface_id(msg, bss) < 0)
     895           0 :                 goto nla_put_failure;
     896             : 
     897           0 :         return send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data);
     898             : 
     899             : nla_put_failure:
     900           0 :         nlmsg_free(msg);
     901           0 :         return NL80211_IFTYPE_UNSPECIFIED;
     902             : }
     903             : 
     904             : 
     905         631 : static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
     906             :                                     struct nl80211_wiphy_data *w)
     907             : {
     908             :         struct nl_msg *msg;
     909         631 :         int ret = -1;
     910             : 
     911         631 :         msg = nlmsg_alloc();
     912         631 :         if (!msg)
     913           0 :                 return -1;
     914             : 
     915         631 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_BEACONS);
     916             : 
     917         631 :         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, w->wiphy_idx);
     918             : 
     919         631 :         ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL);
     920         631 :         msg = NULL;
     921         631 :         if (ret) {
     922           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
     923             :                            "failed: ret=%d (%s)",
     924             :                            ret, strerror(-ret));
     925           0 :                 goto nla_put_failure;
     926             :         }
     927         631 :         ret = 0;
     928             : nla_put_failure:
     929         631 :         nlmsg_free(msg);
     930         631 :         return ret;
     931             : }
     932             : 
     933             : 
     934        2683 : static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
     935             : {
     936        2683 :         struct nl80211_wiphy_data *w = eloop_ctx;
     937             :         int res;
     938             : 
     939        2683 :         wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
     940             : 
     941        2683 :         res = nl_recvmsgs(handle, w->nl_cb);
     942        2683 :         if (res < 0) {
     943           0 :                 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
     944             :                            __func__, res);
     945             :         }
     946        2683 : }
     947             : 
     948             : 
     949        2683 : static int process_beacon_event(struct nl_msg *msg, void *arg)
     950             : {
     951        2683 :         struct nl80211_wiphy_data *w = arg;
     952             :         struct wpa_driver_nl80211_data *drv;
     953        2683 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
     954             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
     955             :         union wpa_event_data event;
     956             : 
     957        2683 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
     958             :                   genlmsg_attrlen(gnlh, 0), NULL);
     959             : 
     960        2683 :         if (gnlh->cmd != NL80211_CMD_FRAME) {
     961           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Unexpected beacon event? (%d)",
     962           0 :                            gnlh->cmd);
     963           0 :                 return NL_SKIP;
     964             :         }
     965             : 
     966        2683 :         if (!tb[NL80211_ATTR_FRAME])
     967           0 :                 return NL_SKIP;
     968             : 
     969        5366 :         dl_list_for_each(drv, &w->drvs, struct wpa_driver_nl80211_data,
     970             :                          wiphy_list) {
     971        2683 :                 os_memset(&event, 0, sizeof(event));
     972        2683 :                 event.rx_mgmt.frame = nla_data(tb[NL80211_ATTR_FRAME]);
     973        2683 :                 event.rx_mgmt.frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
     974        2683 :                 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
     975             :         }
     976             : 
     977        2683 :         return NL_SKIP;
     978             : }
     979             : 
     980             : 
     981             : static struct nl80211_wiphy_data *
     982         650 : nl80211_get_wiphy_data_ap(struct i802_bss *bss)
     983             : {
     984             :         static DEFINE_DL_LIST(nl80211_wiphys);
     985             :         struct nl80211_wiphy_data *w;
     986         650 :         int wiphy_idx, found = 0;
     987             :         struct i802_bss *tmp_bss;
     988             : 
     989         650 :         if (bss->wiphy_data != NULL)
     990           0 :                 return bss->wiphy_data;
     991             : 
     992         650 :         wiphy_idx = nl80211_get_wiphy_index(bss);
     993             : 
     994         729 :         dl_list_for_each(w, &nl80211_wiphys, struct nl80211_wiphy_data, list) {
     995          98 :                 if (w->wiphy_idx == wiphy_idx)
     996          19 :                         goto add;
     997             :         }
     998             : 
     999             :         /* alloc new one */
    1000         631 :         w = os_zalloc(sizeof(*w));
    1001         631 :         if (w == NULL)
    1002           0 :                 return NULL;
    1003         631 :         w->wiphy_idx = wiphy_idx;
    1004         631 :         dl_list_init(&w->bsss);
    1005         631 :         dl_list_init(&w->drvs);
    1006             : 
    1007         631 :         w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
    1008         631 :         if (!w->nl_cb) {
    1009           0 :                 os_free(w);
    1010           0 :                 return NULL;
    1011             :         }
    1012         631 :         nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
    1013         631 :         nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event,
    1014             :                   w);
    1015             : 
    1016         631 :         w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
    1017             :                                          "wiphy beacons");
    1018         631 :         if (w->nl_beacons == NULL) {
    1019           0 :                 os_free(w);
    1020           0 :                 return NULL;
    1021             :         }
    1022             : 
    1023         631 :         if (nl80211_register_beacons(bss->drv, w)) {
    1024           0 :                 nl_destroy_handles(&w->nl_beacons);
    1025           0 :                 os_free(w);
    1026           0 :                 return NULL;
    1027             :         }
    1028             : 
    1029         631 :         nl80211_register_eloop_read(&w->nl_beacons, nl80211_recv_beacons, w);
    1030             : 
    1031         631 :         dl_list_add(&nl80211_wiphys, &w->list);
    1032             : 
    1033             : add:
    1034             :         /* drv entry for this bss already there? */
    1035         650 :         dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
    1036          19 :                 if (tmp_bss->drv == bss->drv) {
    1037          19 :                         found = 1;
    1038          19 :                         break;
    1039             :                 }
    1040             :         }
    1041             :         /* if not add it */
    1042         650 :         if (!found)
    1043         631 :                 dl_list_add(&w->drvs, &bss->drv->wiphy_list);
    1044             : 
    1045         650 :         dl_list_add(&w->bsss, &bss->wiphy_list);
    1046         650 :         bss->wiphy_data = w;
    1047         650 :         return w;
    1048             : }
    1049             : 
    1050             : 
    1051         650 : static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
    1052             : {
    1053         650 :         struct nl80211_wiphy_data *w = bss->wiphy_data;
    1054             :         struct i802_bss *tmp_bss;
    1055         650 :         int found = 0;
    1056             : 
    1057         650 :         if (w == NULL)
    1058           0 :                 return;
    1059         650 :         bss->wiphy_data = NULL;
    1060         650 :         dl_list_del(&bss->wiphy_list);
    1061             : 
    1062             :         /* still any for this drv present? */
    1063         650 :         dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
    1064          19 :                 if (tmp_bss->drv == bss->drv) {
    1065          19 :                         found = 1;
    1066          19 :                         break;
    1067             :                 }
    1068             :         }
    1069             :         /* if not remove it */
    1070         650 :         if (!found)
    1071         631 :                 dl_list_del(&bss->drv->wiphy_list);
    1072             : 
    1073         650 :         if (!dl_list_empty(&w->bsss))
    1074          19 :                 return;
    1075             : 
    1076         631 :         nl80211_destroy_eloop_handle(&w->nl_beacons);
    1077             : 
    1078         631 :         nl_cb_put(w->nl_cb);
    1079         631 :         dl_list_del(&w->list);
    1080         631 :         os_free(w);
    1081             : }
    1082             : 
    1083             : 
    1084           0 : static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
    1085             : {
    1086           0 :         struct i802_bss *bss = priv;
    1087           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    1088           0 :         if (!drv->associated)
    1089           0 :                 return -1;
    1090           0 :         os_memcpy(bssid, drv->bssid, ETH_ALEN);
    1091           0 :         return 0;
    1092             : }
    1093             : 
    1094             : 
    1095           0 : static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
    1096             : {
    1097           0 :         struct i802_bss *bss = priv;
    1098           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    1099           0 :         if (!drv->associated)
    1100           0 :                 return -1;
    1101           0 :         os_memcpy(ssid, drv->ssid, drv->ssid_len);
    1102           0 :         return drv->ssid_len;
    1103             : }
    1104             : 
    1105             : 
    1106        1476 : static void wpa_driver_nl80211_event_newlink(
    1107             :         struct wpa_driver_nl80211_data *drv, char *ifname)
    1108             : {
    1109             :         union wpa_event_data event;
    1110             : 
    1111        1476 :         if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
    1112        1322 :                 if (if_nametoindex(drv->first_bss->ifname) == 0) {
    1113           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
    1114           0 :                                    drv->first_bss->ifname);
    1115           0 :                         return;
    1116             :                 }
    1117        1322 :                 if (!drv->if_removed)
    1118        1322 :                         return;
    1119           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
    1120           0 :                            drv->first_bss->ifname);
    1121           0 :                 drv->if_removed = 0;
    1122             :         }
    1123             : 
    1124         154 :         os_memset(&event, 0, sizeof(event));
    1125         154 :         os_strlcpy(event.interface_status.ifname, ifname,
    1126             :                    sizeof(event.interface_status.ifname));
    1127         154 :         event.interface_status.ievent = EVENT_INTERFACE_ADDED;
    1128         154 :         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
    1129             : }
    1130             : 
    1131             : 
    1132           0 : static void wpa_driver_nl80211_event_dellink(
    1133             :         struct wpa_driver_nl80211_data *drv, char *ifname)
    1134             : {
    1135             :         union wpa_event_data event;
    1136             : 
    1137           0 :         if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
    1138           0 :                 if (drv->if_removed) {
    1139           0 :                         wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
    1140             :                                    ifname);
    1141           0 :                         return;
    1142             :                 }
    1143           0 :                 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
    1144             :                            ifname);
    1145           0 :                 drv->if_removed = 1;
    1146             :         } else {
    1147           0 :                 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
    1148             :                            ifname);
    1149             :         }
    1150             : 
    1151           0 :         os_memset(&event, 0, sizeof(event));
    1152           0 :         os_strlcpy(event.interface_status.ifname, ifname,
    1153             :                    sizeof(event.interface_status.ifname));
    1154           0 :         event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
    1155           0 :         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
    1156             : }
    1157             : 
    1158             : 
    1159           0 : static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
    1160             :                                          u8 *buf, size_t len)
    1161             : {
    1162             :         int attrlen, rta_len;
    1163             :         struct rtattr *attr;
    1164             : 
    1165           0 :         attrlen = len;
    1166           0 :         attr = (struct rtattr *) buf;
    1167             : 
    1168           0 :         rta_len = RTA_ALIGN(sizeof(struct rtattr));
    1169           0 :         while (RTA_OK(attr, attrlen)) {
    1170           0 :                 if (attr->rta_type == IFLA_IFNAME) {
    1171           0 :                         if (os_strcmp(((char *) attr) + rta_len,
    1172             :                                       drv->first_bss->ifname) == 0)
    1173           0 :                                 return 1;
    1174             :                         else
    1175           0 :                                 break;
    1176             :                 }
    1177           0 :                 attr = RTA_NEXT(attr, attrlen);
    1178             :         }
    1179             : 
    1180           0 :         return 0;
    1181             : }
    1182             : 
    1183             : 
    1184        5662 : static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
    1185             :                                           int ifindex, u8 *buf, size_t len)
    1186             : {
    1187        5662 :         if (drv->ifindex == ifindex)
    1188        1335 :                 return 1;
    1189             : 
    1190        4327 :         if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
    1191           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
    1192             :                            "interface");
    1193           0 :                 wpa_driver_nl80211_finish_drv_init(drv, NULL, 0);
    1194           0 :                 return 1;
    1195             :         }
    1196             : 
    1197        4327 :         return 0;
    1198             : }
    1199             : 
    1200             : 
    1201             : static struct wpa_driver_nl80211_data *
    1202        7353 : nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
    1203             : {
    1204             :         struct wpa_driver_nl80211_data *drv;
    1205       11447 :         dl_list_for_each(drv, &global->interfaces,
    1206             :                          struct wpa_driver_nl80211_data, list) {
    1207        9989 :                 if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
    1208        4327 :                     have_ifidx(drv, idx))
    1209        1568 :                         return drv;
    1210             :         }
    1211        5785 :         return NULL;
    1212             : }
    1213             : 
    1214             : 
    1215        7238 : static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
    1216             :                                                  struct ifinfomsg *ifi,
    1217             :                                                  u8 *buf, size_t len)
    1218             : {
    1219        7238 :         struct nl80211_global *global = ctx;
    1220             :         struct wpa_driver_nl80211_data *drv;
    1221             :         int attrlen;
    1222             :         struct rtattr *attr;
    1223        7238 :         u32 brid = 0;
    1224             :         char namebuf[IFNAMSIZ];
    1225             :         char ifname[IFNAMSIZ + 1];
    1226             :         char extra[100], *pos, *end;
    1227             : 
    1228        7238 :         drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
    1229        7238 :         if (!drv) {
    1230        5676 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_NEWLINK event for foreign ifindex %d",
    1231             :                            ifi->ifi_index);
    1232        5676 :                 return;
    1233             :         }
    1234             : 
    1235        1562 :         extra[0] = '\0';
    1236        1562 :         pos = extra;
    1237        1562 :         end = pos + sizeof(extra);
    1238        1562 :         ifname[0] = '\0';
    1239             : 
    1240        1562 :         attrlen = len;
    1241        1562 :         attr = (struct rtattr *) buf;
    1242       30414 :         while (RTA_OK(attr, attrlen)) {
    1243       27290 :                 switch (attr->rta_type) {
    1244             :                 case IFLA_IFNAME:
    1245        1562 :                         if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
    1246           0 :                                 break;
    1247        1562 :                         os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
    1248        1562 :                         ifname[RTA_PAYLOAD(attr)] = '\0';
    1249        1562 :                         break;
    1250             :                 case IFLA_MASTER:
    1251         126 :                         brid = nla_get_u32((struct nlattr *) attr);
    1252         126 :                         pos += os_snprintf(pos, end - pos, " master=%u", brid);
    1253         126 :                         break;
    1254             :                 case IFLA_WIRELESS:
    1255           0 :                         pos += os_snprintf(pos, end - pos, " wext");
    1256           0 :                         break;
    1257             :                 case IFLA_OPERSTATE:
    1258        1562 :                         pos += os_snprintf(pos, end - pos, " operstate=%u",
    1259             :                                            nla_get_u32((struct nlattr *) attr));
    1260        1562 :                         break;
    1261             :                 case IFLA_LINKMODE:
    1262        1482 :                         pos += os_snprintf(pos, end - pos, " linkmode=%u",
    1263             :                                            nla_get_u32((struct nlattr *) attr));
    1264        1482 :                         break;
    1265             :                 }
    1266       27290 :                 attr = RTA_NEXT(attr, attrlen);
    1267             :         }
    1268        1562 :         extra[sizeof(extra) - 1] = '\0';
    1269             : 
    1270        7810 :         wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
    1271        1562 :                    ifi->ifi_index, ifname, extra, ifi->ifi_family,
    1272             :                    ifi->ifi_flags,
    1273        1562 :                    (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
    1274        1562 :                    (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
    1275        1562 :                    (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
    1276        1562 :                    (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
    1277             : 
    1278        1562 :         if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
    1279         172 :                 if (if_indextoname(ifi->ifi_index, namebuf) &&
    1280          86 :                     linux_iface_up(drv->global->ioctl_sock,
    1281          86 :                                    drv->first_bss->ifname) > 0) {
    1282          86 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
    1283             :                                    "event since interface %s is up", namebuf);
    1284          86 :                         return;
    1285             :                 }
    1286           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface down");
    1287           0 :                 if (drv->ignore_if_down_event) {
    1288           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
    1289             :                                    "event generated by mode change");
    1290           0 :                         drv->ignore_if_down_event = 0;
    1291             :                 } else {
    1292           0 :                         drv->if_disabled = 1;
    1293           0 :                         wpa_supplicant_event(drv->ctx,
    1294             :                                              EVENT_INTERFACE_DISABLED, NULL);
    1295             : 
    1296             :                         /*
    1297             :                          * Try to get drv again, since it may be removed as
    1298             :                          * part of the EVENT_INTERFACE_DISABLED handling for
    1299             :                          * dynamic interfaces
    1300             :                          */
    1301           0 :                         drv = nl80211_find_drv(global, ifi->ifi_index,
    1302             :                                                buf, len);
    1303           0 :                         if (!drv)
    1304           0 :                                 return;
    1305             :                 }
    1306             :         }
    1307             : 
    1308        1476 :         if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
    1309           0 :                 if (if_indextoname(ifi->ifi_index, namebuf) &&
    1310           0 :                     linux_iface_up(drv->global->ioctl_sock,
    1311           0 :                                    drv->first_bss->ifname) == 0) {
    1312           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
    1313             :                                    "event since interface %s is down",
    1314             :                                    namebuf);
    1315           0 :                 } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
    1316           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
    1317             :                                    "event since interface %s does not exist",
    1318           0 :                                    drv->first_bss->ifname);
    1319           0 :                 } else if (drv->if_removed) {
    1320           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
    1321             :                                    "event since interface %s is marked "
    1322           0 :                                    "removed", drv->first_bss->ifname);
    1323             :                 } else {
    1324             :                         struct i802_bss *bss;
    1325             :                         u8 addr[ETH_ALEN];
    1326             : 
    1327             :                         /* Re-read MAC address as it may have changed */
    1328           0 :                         bss = get_bss_ifindex(drv, ifi->ifi_index);
    1329           0 :                         if (bss &&
    1330           0 :                             linux_get_ifhwaddr(drv->global->ioctl_sock,
    1331           0 :                                                bss->ifname, addr) < 0) {
    1332           0 :                                 wpa_printf(MSG_DEBUG,
    1333             :                                            "nl80211: %s: failed to re-read MAC address",
    1334           0 :                                            bss->ifname);
    1335           0 :                         } else if (bss &&
    1336           0 :                                    os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
    1337           0 :                                 wpa_printf(MSG_DEBUG,
    1338             :                                            "nl80211: Own MAC address on ifindex %d (%s) changed from "
    1339             :                                            MACSTR " to " MACSTR,
    1340           0 :                                            ifi->ifi_index, bss->ifname,
    1341           0 :                                            MAC2STR(bss->addr),
    1342           0 :                                            MAC2STR(addr));
    1343           0 :                                 os_memcpy(bss->addr, addr, ETH_ALEN);
    1344             :                         }
    1345             : 
    1346           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Interface up");
    1347           0 :                         drv->if_disabled = 0;
    1348           0 :                         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
    1349             :                                              NULL);
    1350             :                 }
    1351             :         }
    1352             : 
    1353             :         /*
    1354             :          * Some drivers send the association event before the operup event--in
    1355             :          * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
    1356             :          * fails. This will hit us when wpa_supplicant does not need to do
    1357             :          * IEEE 802.1X authentication
    1358             :          */
    1359        2897 :         if (drv->operstate == 1 &&
    1360        2203 :             (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
    1361         782 :             !(ifi->ifi_flags & IFF_RUNNING)) {
    1362           1 :                 wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
    1363           1 :                 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
    1364             :                                        -1, IF_OPER_UP);
    1365             :         }
    1366             : 
    1367        1476 :         if (ifname[0])
    1368        1476 :                 wpa_driver_nl80211_event_newlink(drv, ifname);
    1369             : 
    1370        1476 :         if (ifi->ifi_family == AF_BRIDGE && brid) {
    1371             :                 /* device has been added to bridge */
    1372          79 :                 if_indextoname(brid, namebuf);
    1373          79 :                 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
    1374             :                            brid, namebuf);
    1375          79 :                 add_ifidx(drv, brid);
    1376             :         }
    1377             : }
    1378             : 
    1379             : 
    1380         115 : static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
    1381             :                                                  struct ifinfomsg *ifi,
    1382             :                                                  u8 *buf, size_t len)
    1383             : {
    1384         115 :         struct nl80211_global *global = ctx;
    1385             :         struct wpa_driver_nl80211_data *drv;
    1386             :         int attrlen;
    1387             :         struct rtattr *attr;
    1388         115 :         u32 brid = 0;
    1389             :         char ifname[IFNAMSIZ + 1];
    1390             :         char extra[100], *pos, *end;
    1391             : 
    1392         115 :         drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
    1393         115 :         if (!drv) {
    1394         109 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_DELLINK event for foreign ifindex %d",
    1395             :                            ifi->ifi_index);
    1396         224 :                 return;
    1397             :         }
    1398             : 
    1399           6 :         extra[0] = '\0';
    1400           6 :         pos = extra;
    1401           6 :         end = pos + sizeof(extra);
    1402           6 :         ifname[0] = '\0';
    1403             : 
    1404           6 :         attrlen = len;
    1405           6 :         attr = (struct rtattr *) buf;
    1406          42 :         while (RTA_OK(attr, attrlen)) {
    1407          30 :                 switch (attr->rta_type) {
    1408             :                 case IFLA_IFNAME:
    1409           6 :                         if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
    1410           0 :                                 break;
    1411           6 :                         os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
    1412           6 :                         ifname[RTA_PAYLOAD(attr)] = '\0';
    1413           6 :                         break;
    1414             :                 case IFLA_MASTER:
    1415           6 :                         brid = nla_get_u32((struct nlattr *) attr);
    1416           6 :                         pos += os_snprintf(pos, end - pos, " master=%u", brid);
    1417           6 :                         break;
    1418             :                 case IFLA_OPERSTATE:
    1419           6 :                         pos += os_snprintf(pos, end - pos, " operstate=%u",
    1420             :                                            nla_get_u32((struct nlattr *) attr));
    1421           6 :                         break;
    1422             :                 case IFLA_LINKMODE:
    1423           0 :                         pos += os_snprintf(pos, end - pos, " linkmode=%u",
    1424             :                                            nla_get_u32((struct nlattr *) attr));
    1425           0 :                         break;
    1426             :                 }
    1427          30 :                 attr = RTA_NEXT(attr, attrlen);
    1428             :         }
    1429           6 :         extra[sizeof(extra) - 1] = '\0';
    1430             : 
    1431          30 :         wpa_printf(MSG_DEBUG, "RTM_DELLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
    1432           6 :                    ifi->ifi_index, ifname, extra, ifi->ifi_family,
    1433             :                    ifi->ifi_flags,
    1434           6 :                    (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
    1435           6 :                    (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
    1436           6 :                    (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
    1437           6 :                    (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
    1438             : 
    1439           6 :         if (ifname[0] && (ifi->ifi_family != AF_BRIDGE || !brid))
    1440           0 :                 wpa_driver_nl80211_event_dellink(drv, ifname);
    1441             : 
    1442           6 :         if (ifi->ifi_family == AF_BRIDGE && brid) {
    1443             :                 /* device has been removed from bridge */
    1444             :                 char namebuf[IFNAMSIZ];
    1445           6 :                 if_indextoname(brid, namebuf);
    1446           6 :                 wpa_printf(MSG_DEBUG, "nl80211: Remove ifindex %u for bridge "
    1447             :                            "%s", brid, namebuf);
    1448           6 :                 del_ifidx(drv, brid);
    1449             :         }
    1450             : }
    1451             : 
    1452             : 
    1453           0 : static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
    1454             :                             const u8 *frame, size_t len)
    1455             : {
    1456             :         const struct ieee80211_mgmt *mgmt;
    1457             :         union wpa_event_data event;
    1458             : 
    1459           0 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
    1460             :             drv->force_connect_cmd) {
    1461             :                 /*
    1462             :                  * Avoid reporting two association events that would confuse
    1463             :                  * the core code.
    1464             :                  */
    1465           0 :                 wpa_printf(MSG_DEBUG,
    1466             :                            "nl80211: Ignore auth event when using driver SME");
    1467           0 :                 return;
    1468             :         }
    1469             : 
    1470           0 :         wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
    1471           0 :         mgmt = (const struct ieee80211_mgmt *) frame;
    1472           0 :         if (len < 24 + sizeof(mgmt->u.auth)) {
    1473           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
    1474             :                            "frame");
    1475           0 :                 return;
    1476             :         }
    1477             : 
    1478           0 :         os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
    1479           0 :         os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
    1480           0 :         os_memset(&event, 0, sizeof(event));
    1481           0 :         os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
    1482           0 :         event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
    1483           0 :         event.auth.auth_transaction =
    1484           0 :                 le_to_host16(mgmt->u.auth.auth_transaction);
    1485           0 :         event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
    1486           0 :         if (len > 24 + sizeof(mgmt->u.auth)) {
    1487           0 :                 event.auth.ies = mgmt->u.auth.variable;
    1488           0 :                 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
    1489             :         }
    1490             : 
    1491           0 :         wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
    1492             : }
    1493             : 
    1494             : 
    1495           0 : static unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
    1496             : {
    1497             :         struct nl_msg *msg;
    1498             :         int ret;
    1499             :         struct nl80211_bss_info_arg arg;
    1500             : 
    1501           0 :         os_memset(&arg, 0, sizeof(arg));
    1502           0 :         msg = nlmsg_alloc();
    1503           0 :         if (!msg)
    1504           0 :                 goto nla_put_failure;
    1505             : 
    1506           0 :         nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
    1507           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    1508             : 
    1509           0 :         arg.drv = drv;
    1510           0 :         ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
    1511           0 :         msg = NULL;
    1512           0 :         if (ret == 0) {
    1513           0 :                 unsigned int freq = drv->nlmode == NL80211_IFTYPE_ADHOC ?
    1514           0 :                         arg.ibss_freq : arg.assoc_freq;
    1515           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
    1516             :                            "associated BSS from scan results: %u MHz", freq);
    1517           0 :                 if (freq)
    1518           0 :                         drv->assoc_freq = freq;
    1519           0 :                 return drv->assoc_freq;
    1520             :         }
    1521           0 :         wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
    1522             :                    "(%s)", ret, strerror(-ret));
    1523             : nla_put_failure:
    1524           0 :         nlmsg_free(msg);
    1525           0 :         return drv->assoc_freq;
    1526             : }
    1527             : 
    1528             : 
    1529           0 : static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
    1530             :                             const u8 *frame, size_t len)
    1531             : {
    1532             :         const struct ieee80211_mgmt *mgmt;
    1533             :         union wpa_event_data event;
    1534             :         u16 status;
    1535             : 
    1536           0 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
    1537             :             drv->force_connect_cmd) {
    1538             :                 /*
    1539             :                  * Avoid reporting two association events that would confuse
    1540             :                  * the core code.
    1541             :                  */
    1542           0 :                 wpa_printf(MSG_DEBUG,
    1543             :                            "nl80211: Ignore assoc event when using driver SME");
    1544           0 :                 return;
    1545             :         }
    1546             : 
    1547           0 :         wpa_printf(MSG_DEBUG, "nl80211: Associate event");
    1548           0 :         mgmt = (const struct ieee80211_mgmt *) frame;
    1549           0 :         if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
    1550           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
    1551             :                            "frame");
    1552           0 :                 return;
    1553             :         }
    1554             : 
    1555           0 :         status = le_to_host16(mgmt->u.assoc_resp.status_code);
    1556           0 :         if (status != WLAN_STATUS_SUCCESS) {
    1557           0 :                 os_memset(&event, 0, sizeof(event));
    1558           0 :                 event.assoc_reject.bssid = mgmt->bssid;
    1559           0 :                 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
    1560           0 :                         event.assoc_reject.resp_ies =
    1561           0 :                                 (u8 *) mgmt->u.assoc_resp.variable;
    1562           0 :                         event.assoc_reject.resp_ies_len =
    1563           0 :                                 len - 24 - sizeof(mgmt->u.assoc_resp);
    1564             :                 }
    1565           0 :                 event.assoc_reject.status_code = status;
    1566             : 
    1567           0 :                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
    1568           0 :                 return;
    1569             :         }
    1570             : 
    1571           0 :         drv->associated = 1;
    1572           0 :         os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
    1573           0 :         os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
    1574             : 
    1575           0 :         os_memset(&event, 0, sizeof(event));
    1576           0 :         if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
    1577           0 :                 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
    1578           0 :                 event.assoc_info.resp_ies_len =
    1579           0 :                         len - 24 - sizeof(mgmt->u.assoc_resp);
    1580             :         }
    1581             : 
    1582           0 :         event.assoc_info.freq = drv->assoc_freq;
    1583             : 
    1584           0 :         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
    1585             : }
    1586             : 
    1587             : 
    1588           0 : static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
    1589             :                                enum nl80211_commands cmd, struct nlattr *status,
    1590             :                                struct nlattr *addr, struct nlattr *req_ie,
    1591             :                                struct nlattr *resp_ie)
    1592             : {
    1593             :         union wpa_event_data event;
    1594             : 
    1595           0 :         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
    1596             :                 /*
    1597             :                  * Avoid reporting two association events that would confuse
    1598             :                  * the core code.
    1599             :                  */
    1600           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
    1601             :                            "when using userspace SME", cmd);
    1602           0 :                 return;
    1603             :         }
    1604             : 
    1605           0 :         if (cmd == NL80211_CMD_CONNECT)
    1606           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Connect event");
    1607           0 :         else if (cmd == NL80211_CMD_ROAM)
    1608           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Roam event");
    1609             : 
    1610           0 :         os_memset(&event, 0, sizeof(event));
    1611           0 :         if (cmd == NL80211_CMD_CONNECT &&
    1612           0 :             nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
    1613           0 :                 if (addr)
    1614           0 :                         event.assoc_reject.bssid = nla_data(addr);
    1615           0 :                 if (resp_ie) {
    1616           0 :                         event.assoc_reject.resp_ies = nla_data(resp_ie);
    1617           0 :                         event.assoc_reject.resp_ies_len = nla_len(resp_ie);
    1618             :                 }
    1619           0 :                 event.assoc_reject.status_code = nla_get_u16(status);
    1620           0 :                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
    1621           0 :                 return;
    1622             :         }
    1623             : 
    1624           0 :         drv->associated = 1;
    1625           0 :         if (addr) {
    1626           0 :                 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
    1627           0 :                 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
    1628             :         }
    1629             : 
    1630           0 :         if (req_ie) {
    1631           0 :                 event.assoc_info.req_ies = nla_data(req_ie);
    1632           0 :                 event.assoc_info.req_ies_len = nla_len(req_ie);
    1633             :         }
    1634           0 :         if (resp_ie) {
    1635           0 :                 event.assoc_info.resp_ies = nla_data(resp_ie);
    1636           0 :                 event.assoc_info.resp_ies_len = nla_len(resp_ie);
    1637             :         }
    1638             : 
    1639           0 :         event.assoc_info.freq = nl80211_get_assoc_freq(drv);
    1640             : 
    1641           0 :         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
    1642             : }
    1643             : 
    1644             : 
    1645           0 : static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
    1646             :                                   struct nlattr *reason, struct nlattr *addr,
    1647             :                                   struct nlattr *by_ap)
    1648             : {
    1649             :         union wpa_event_data data;
    1650           0 :         unsigned int locally_generated = by_ap == NULL;
    1651             : 
    1652           0 :         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
    1653             :                 /*
    1654             :                  * Avoid reporting two disassociation events that could
    1655             :                  * confuse the core code.
    1656             :                  */
    1657           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
    1658             :                            "event when using userspace SME");
    1659           0 :                 return;
    1660             :         }
    1661             : 
    1662           0 :         if (drv->ignore_next_local_disconnect) {
    1663           0 :                 drv->ignore_next_local_disconnect = 0;
    1664           0 :                 if (locally_generated) {
    1665           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
    1666             :                                    "event triggered during reassociation");
    1667           0 :                         return;
    1668             :                 }
    1669           0 :                 wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
    1670             :                            "disconnect but got another disconnect "
    1671             :                            "event first");
    1672             :         }
    1673             : 
    1674           0 :         wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
    1675           0 :         nl80211_mark_disconnected(drv);
    1676           0 :         os_memset(&data, 0, sizeof(data));
    1677           0 :         if (reason)
    1678           0 :                 data.deauth_info.reason_code = nla_get_u16(reason);
    1679           0 :         data.deauth_info.locally_generated = by_ap == NULL;
    1680           0 :         wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
    1681             : }
    1682             : 
    1683             : 
    1684           0 : static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
    1685             : {
    1686           0 :         int freq1 = 0;
    1687             : 
    1688           0 :         switch (convert2width(width)) {
    1689             :         case CHAN_WIDTH_20_NOHT:
    1690             :         case CHAN_WIDTH_20:
    1691           0 :                 return 0;
    1692             :         case CHAN_WIDTH_40:
    1693           0 :                 freq1 = cf1 - 10;
    1694           0 :                 break;
    1695             :         case CHAN_WIDTH_80:
    1696           0 :                 freq1 = cf1 - 30;
    1697           0 :                 break;
    1698             :         case CHAN_WIDTH_160:
    1699           0 :                 freq1 = cf1 - 70;
    1700           0 :                 break;
    1701             :         case CHAN_WIDTH_UNKNOWN:
    1702             :         case CHAN_WIDTH_80P80:
    1703             :                 /* FIXME: implement this */
    1704           0 :                 return 0;
    1705             :         }
    1706             : 
    1707           0 :         return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
    1708             : }
    1709             : 
    1710             : 
    1711           1 : static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
    1712             :                                  struct nlattr *ifindex, struct nlattr *freq,
    1713             :                                  struct nlattr *type, struct nlattr *bw,
    1714             :                                  struct nlattr *cf1, struct nlattr *cf2)
    1715             : {
    1716             :         struct i802_bss *bss;
    1717             :         union wpa_event_data data;
    1718           1 :         int ht_enabled = 1;
    1719           1 :         int chan_offset = 0;
    1720             :         int ifidx;
    1721             : 
    1722           1 :         wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
    1723             : 
    1724           1 :         if (!freq)
    1725           0 :                 return;
    1726             : 
    1727           1 :         ifidx = nla_get_u32(ifindex);
    1728           1 :         bss = get_bss_ifindex(drv, ifidx);
    1729           1 :         if (bss == NULL) {
    1730           0 :                 wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
    1731             :                            ifidx);
    1732           0 :                 return;
    1733             :         }
    1734             : 
    1735           1 :         if (type) {
    1736           1 :                 switch (nla_get_u32(type)) {
    1737             :                 case NL80211_CHAN_NO_HT:
    1738           0 :                         ht_enabled = 0;
    1739           0 :                         break;
    1740             :                 case NL80211_CHAN_HT20:
    1741           1 :                         break;
    1742             :                 case NL80211_CHAN_HT40PLUS:
    1743           0 :                         chan_offset = 1;
    1744           0 :                         break;
    1745             :                 case NL80211_CHAN_HT40MINUS:
    1746           0 :                         chan_offset = -1;
    1747           0 :                         break;
    1748             :                 }
    1749           0 :         } else if (bw && cf1) {
    1750             :                 /* This can happen for example with VHT80 ch switch */
    1751           0 :                 chan_offset = calculate_chan_offset(nla_get_u32(bw),
    1752           0 :                                                     nla_get_u32(freq),
    1753           0 :                                                     nla_get_u32(cf1),
    1754           0 :                                                     cf2 ? nla_get_u32(cf2) : 0);
    1755             :         } else {
    1756           0 :                 wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
    1757             :         }
    1758             : 
    1759           1 :         os_memset(&data, 0, sizeof(data));
    1760           1 :         data.ch_switch.freq = nla_get_u32(freq);
    1761           1 :         data.ch_switch.ht_enabled = ht_enabled;
    1762           1 :         data.ch_switch.ch_offset = chan_offset;
    1763           1 :         if (bw)
    1764           1 :                 data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
    1765           1 :         if (cf1)
    1766           1 :                 data.ch_switch.cf1 = nla_get_u32(cf1);
    1767           1 :         if (cf2)
    1768           0 :                 data.ch_switch.cf2 = nla_get_u32(cf2);
    1769             : 
    1770           1 :         bss->freq = data.ch_switch.freq;
    1771             : 
    1772           1 :         wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data);
    1773             : }
    1774             : 
    1775             : 
    1776           0 : static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
    1777             :                                enum nl80211_commands cmd, struct nlattr *addr)
    1778             : {
    1779             :         union wpa_event_data event;
    1780             :         enum wpa_event_type ev;
    1781             : 
    1782           0 :         if (nla_len(addr) != ETH_ALEN)
    1783           0 :                 return;
    1784             : 
    1785           0 :         wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
    1786           0 :                    cmd, MAC2STR((u8 *) nla_data(addr)));
    1787             : 
    1788           0 :         if (cmd == NL80211_CMD_AUTHENTICATE)
    1789           0 :                 ev = EVENT_AUTH_TIMED_OUT;
    1790           0 :         else if (cmd == NL80211_CMD_ASSOCIATE)
    1791           0 :                 ev = EVENT_ASSOC_TIMED_OUT;
    1792             :         else
    1793           0 :                 return;
    1794             : 
    1795           0 :         os_memset(&event, 0, sizeof(event));
    1796           0 :         os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
    1797           0 :         wpa_supplicant_event(drv->ctx, ev, &event);
    1798             : }
    1799             : 
    1800             : 
    1801        5562 : static void mlme_event_mgmt(struct i802_bss *bss,
    1802             :                             struct nlattr *freq, struct nlattr *sig,
    1803             :                             const u8 *frame, size_t len)
    1804             : {
    1805        5562 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    1806             :         const struct ieee80211_mgmt *mgmt;
    1807             :         union wpa_event_data event;
    1808             :         u16 fc, stype;
    1809        5562 :         int ssi_signal = 0;
    1810        5562 :         int rx_freq = 0;
    1811             : 
    1812        5562 :         wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
    1813        5562 :         mgmt = (const struct ieee80211_mgmt *) frame;
    1814        5562 :         if (len < 24) {
    1815           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
    1816        5562 :                 return;
    1817             :         }
    1818             : 
    1819        5562 :         fc = le_to_host16(mgmt->frame_control);
    1820        5562 :         stype = WLAN_FC_GET_STYPE(fc);
    1821             : 
    1822        5562 :         if (sig)
    1823        5562 :                 ssi_signal = (s32) nla_get_u32(sig);
    1824             : 
    1825        5562 :         os_memset(&event, 0, sizeof(event));
    1826        5562 :         if (freq) {
    1827        5562 :                 event.rx_mgmt.freq = nla_get_u32(freq);
    1828        5562 :                 rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
    1829             :         }
    1830       38934 :         wpa_printf(MSG_DEBUG,
    1831             :                    "nl80211: RX frame sa=" MACSTR
    1832             :                    " freq=%d ssi_signal=%d stype=%u (%s) len=%u",
    1833       33372 :                    MAC2STR(mgmt->sa), rx_freq, ssi_signal, stype, fc2str(fc),
    1834             :                    (unsigned int) len);
    1835        5562 :         event.rx_mgmt.frame = frame;
    1836        5562 :         event.rx_mgmt.frame_len = len;
    1837        5562 :         event.rx_mgmt.ssi_signal = ssi_signal;
    1838        5562 :         event.rx_mgmt.drv_priv = bss;
    1839        5562 :         wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
    1840             : }
    1841             : 
    1842             : 
    1843        3511 : static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
    1844             :                                       struct nlattr *cookie, const u8 *frame,
    1845             :                                       size_t len, struct nlattr *ack)
    1846             : {
    1847             :         union wpa_event_data event;
    1848             :         const struct ieee80211_hdr *hdr;
    1849             :         u16 fc;
    1850             : 
    1851        3511 :         wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
    1852        3511 :         if (!is_ap_interface(drv->nlmode)) {
    1853             :                 u64 cookie_val;
    1854             : 
    1855           0 :                 if (!cookie)
    1856           0 :                         return;
    1857             : 
    1858           0 :                 cookie_val = nla_get_u64(cookie);
    1859           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
    1860             :                            " cookie=0%llx%s (ack=%d)",
    1861             :                            (long long unsigned int) cookie_val,
    1862           0 :                            cookie_val == drv->send_action_cookie ?
    1863             :                            " (match)" : " (unknown)", ack != NULL);
    1864           0 :                 if (cookie_val != drv->send_action_cookie)
    1865           0 :                         return;
    1866             :         }
    1867             : 
    1868        3511 :         hdr = (const struct ieee80211_hdr *) frame;
    1869        3511 :         fc = le_to_host16(hdr->frame_control);
    1870             : 
    1871        3511 :         os_memset(&event, 0, sizeof(event));
    1872        3511 :         event.tx_status.type = WLAN_FC_GET_TYPE(fc);
    1873        3511 :         event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
    1874        3511 :         event.tx_status.dst = hdr->addr1;
    1875        3511 :         event.tx_status.data = frame;
    1876        3511 :         event.tx_status.data_len = len;
    1877        3511 :         event.tx_status.ack = ack != NULL;
    1878        3511 :         wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
    1879             : }
    1880             : 
    1881             : 
    1882           0 : static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
    1883             :                                        enum wpa_event_type type,
    1884             :                                        const u8 *frame, size_t len)
    1885             : {
    1886             :         const struct ieee80211_mgmt *mgmt;
    1887             :         union wpa_event_data event;
    1888           0 :         const u8 *bssid = NULL;
    1889           0 :         u16 reason_code = 0;
    1890             : 
    1891           0 :         if (type == EVENT_DEAUTH)
    1892           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
    1893             :         else
    1894           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
    1895             : 
    1896           0 :         mgmt = (const struct ieee80211_mgmt *) frame;
    1897           0 :         if (len >= 24) {
    1898           0 :                 bssid = mgmt->bssid;
    1899             : 
    1900           0 :                 if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
    1901           0 :                     !drv->associated &&
    1902           0 :                     os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
    1903           0 :                     os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
    1904           0 :                     os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
    1905             :                         /*
    1906             :                          * Avoid issues with some roaming cases where
    1907             :                          * disconnection event for the old AP may show up after
    1908             :                          * we have started connection with the new AP.
    1909             :                          */
    1910           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
    1911           0 :                                    MAC2STR(bssid),
    1912           0 :                                    MAC2STR(drv->auth_attempt_bssid));
    1913           0 :                         return;
    1914             :                 }
    1915             : 
    1916           0 :                 if (drv->associated != 0 &&
    1917           0 :                     os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
    1918           0 :                     os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
    1919             :                         /*
    1920             :                          * We have presumably received this deauth as a
    1921             :                          * response to a clear_state_mismatch() outgoing
    1922             :                          * deauth.  Don't let it take us offline!
    1923             :                          */
    1924           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
    1925             :                                    "from Unknown BSSID " MACSTR " -- ignoring",
    1926           0 :                                    MAC2STR(bssid));
    1927           0 :                         return;
    1928             :                 }
    1929             :         }
    1930             : 
    1931           0 :         nl80211_mark_disconnected(drv);
    1932           0 :         os_memset(&event, 0, sizeof(event));
    1933             : 
    1934             :         /* Note: Same offset for Reason Code in both frame subtypes */
    1935           0 :         if (len >= 24 + sizeof(mgmt->u.deauth))
    1936           0 :                 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
    1937             : 
    1938           0 :         if (type == EVENT_DISASSOC) {
    1939           0 :                 event.disassoc_info.locally_generated =
    1940           0 :                         !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
    1941           0 :                 event.disassoc_info.addr = bssid;
    1942           0 :                 event.disassoc_info.reason_code = reason_code;
    1943           0 :                 if (frame + len > mgmt->u.disassoc.variable) {
    1944           0 :                         event.disassoc_info.ie = mgmt->u.disassoc.variable;
    1945           0 :                         event.disassoc_info.ie_len = frame + len -
    1946             :                                 mgmt->u.disassoc.variable;
    1947             :                 }
    1948             :         } else {
    1949           0 :                 if (drv->ignore_deauth_event) {
    1950           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
    1951           0 :                         drv->ignore_deauth_event = 0;
    1952           0 :                         return;
    1953             :                 }
    1954           0 :                 event.deauth_info.locally_generated =
    1955           0 :                         !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
    1956           0 :                 if (drv->ignore_next_local_deauth) {
    1957           0 :                         drv->ignore_next_local_deauth = 0;
    1958           0 :                         if (event.deauth_info.locally_generated) {
    1959           0 :                                 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
    1960           0 :                                 return;
    1961             :                         }
    1962           0 :                         wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
    1963             :                 }
    1964           0 :                 event.deauth_info.addr = bssid;
    1965           0 :                 event.deauth_info.reason_code = reason_code;
    1966           0 :                 if (frame + len > mgmt->u.deauth.variable) {
    1967           0 :                         event.deauth_info.ie = mgmt->u.deauth.variable;
    1968           0 :                         event.deauth_info.ie_len = frame + len -
    1969             :                                 mgmt->u.deauth.variable;
    1970             :                 }
    1971             :         }
    1972             : 
    1973           0 :         wpa_supplicant_event(drv->ctx, type, &event);
    1974             : }
    1975             : 
    1976             : 
    1977           1 : static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
    1978             :                                          enum wpa_event_type type,
    1979             :                                          const u8 *frame, size_t len)
    1980             : {
    1981             :         const struct ieee80211_mgmt *mgmt;
    1982             :         union wpa_event_data event;
    1983           1 :         u16 reason_code = 0;
    1984             : 
    1985           1 :         if (type == EVENT_UNPROT_DEAUTH)
    1986           1 :                 wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
    1987             :         else
    1988           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
    1989             : 
    1990           1 :         if (len < 24)
    1991           1 :                 return;
    1992             : 
    1993           1 :         mgmt = (const struct ieee80211_mgmt *) frame;
    1994             : 
    1995           1 :         os_memset(&event, 0, sizeof(event));
    1996             :         /* Note: Same offset for Reason Code in both frame subtypes */
    1997           1 :         if (len >= 24 + sizeof(mgmt->u.deauth))
    1998           1 :                 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
    1999             : 
    2000           1 :         if (type == EVENT_UNPROT_DISASSOC) {
    2001           0 :                 event.unprot_disassoc.sa = mgmt->sa;
    2002           0 :                 event.unprot_disassoc.da = mgmt->da;
    2003           0 :                 event.unprot_disassoc.reason_code = reason_code;
    2004             :         } else {
    2005           1 :                 event.unprot_deauth.sa = mgmt->sa;
    2006           1 :                 event.unprot_deauth.da = mgmt->da;
    2007           1 :                 event.unprot_deauth.reason_code = reason_code;
    2008             :         }
    2009             : 
    2010           1 :         wpa_supplicant_event(drv->ctx, type, &event);
    2011             : }
    2012             : 
    2013             : 
    2014        9074 : static void mlme_event(struct i802_bss *bss,
    2015             :                        enum nl80211_commands cmd, struct nlattr *frame,
    2016             :                        struct nlattr *addr, struct nlattr *timed_out,
    2017             :                        struct nlattr *freq, struct nlattr *ack,
    2018             :                        struct nlattr *cookie, struct nlattr *sig)
    2019             : {
    2020        9074 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    2021             :         const u8 *data;
    2022             :         size_t len;
    2023             : 
    2024        9074 :         if (timed_out && addr) {
    2025           0 :                 mlme_timeout_event(drv, cmd, addr);
    2026           0 :                 return;
    2027             :         }
    2028             : 
    2029        9074 :         if (frame == NULL) {
    2030           0 :                 wpa_printf(MSG_DEBUG,
    2031             :                            "nl80211: MLME event %d (%s) without frame data",
    2032             :                            cmd, nl80211_command_to_string(cmd));
    2033           0 :                 return;
    2034             :         }
    2035             : 
    2036        9074 :         data = nla_data(frame);
    2037        9074 :         len = nla_len(frame);
    2038        9074 :         if (len < 4 + 2 * ETH_ALEN) {
    2039           0 :                 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
    2040             :                            MACSTR ") - too short",
    2041           0 :                            cmd, nl80211_command_to_string(cmd), bss->ifname,
    2042           0 :                            MAC2STR(bss->addr));
    2043           0 :                 return;
    2044             :         }
    2045      172406 :         wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
    2046             :                    ") A1=" MACSTR " A2=" MACSTR, cmd,
    2047        9074 :                    nl80211_command_to_string(cmd), bss->ifname,
    2048      108888 :                    MAC2STR(bss->addr), MAC2STR(data + 4),
    2049       54444 :                    MAC2STR(data + 4 + ETH_ALEN));
    2050       13252 :         if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
    2051        4178 :             os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
    2052           0 :             os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
    2053           0 :                 wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
    2054           0 :                            "for foreign address", bss->ifname);
    2055           0 :                 return;
    2056             :         }
    2057       18148 :         wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
    2058       18148 :                     nla_data(frame), nla_len(frame));
    2059             : 
    2060        9074 :         switch (cmd) {
    2061             :         case NL80211_CMD_AUTHENTICATE:
    2062           0 :                 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
    2063           0 :                 break;
    2064             :         case NL80211_CMD_ASSOCIATE:
    2065           0 :                 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
    2066           0 :                 break;
    2067             :         case NL80211_CMD_DEAUTHENTICATE:
    2068           0 :                 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
    2069           0 :                                            nla_data(frame), nla_len(frame));
    2070           0 :                 break;
    2071             :         case NL80211_CMD_DISASSOCIATE:
    2072           0 :                 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
    2073           0 :                                            nla_data(frame), nla_len(frame));
    2074           0 :                 break;
    2075             :         case NL80211_CMD_FRAME:
    2076        5562 :                 mlme_event_mgmt(bss, freq, sig, nla_data(frame),
    2077        5562 :                                 nla_len(frame));
    2078        5562 :                 break;
    2079             :         case NL80211_CMD_FRAME_TX_STATUS:
    2080        3511 :                 mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
    2081        3511 :                                           nla_len(frame), ack);
    2082        3511 :                 break;
    2083             :         case NL80211_CMD_UNPROT_DEAUTHENTICATE:
    2084           2 :                 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
    2085           2 :                                              nla_data(frame), nla_len(frame));
    2086           1 :                 break;
    2087             :         case NL80211_CMD_UNPROT_DISASSOCIATE:
    2088           0 :                 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
    2089           0 :                                              nla_data(frame), nla_len(frame));
    2090           0 :                 break;
    2091             :         default:
    2092           0 :                 break;
    2093             :         }
    2094             : }
    2095             : 
    2096             : 
    2097           2 : static void mlme_event_michael_mic_failure(struct i802_bss *bss,
    2098             :                                            struct nlattr *tb[])
    2099             : {
    2100             :         union wpa_event_data data;
    2101             : 
    2102           2 :         wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
    2103           2 :         os_memset(&data, 0, sizeof(data));
    2104           2 :         if (tb[NL80211_ATTR_MAC]) {
    2105           4 :                 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
    2106           2 :                             nla_data(tb[NL80211_ATTR_MAC]),
    2107           2 :                             nla_len(tb[NL80211_ATTR_MAC]));
    2108           2 :                 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
    2109             :         }
    2110           2 :         if (tb[NL80211_ATTR_KEY_SEQ]) {
    2111           0 :                 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
    2112           0 :                             nla_data(tb[NL80211_ATTR_KEY_SEQ]),
    2113           0 :                             nla_len(tb[NL80211_ATTR_KEY_SEQ]));
    2114             :         }
    2115           2 :         if (tb[NL80211_ATTR_KEY_TYPE]) {
    2116           2 :                 enum nl80211_key_type key_type =
    2117           2 :                         nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
    2118           2 :                 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
    2119           2 :                 if (key_type == NL80211_KEYTYPE_PAIRWISE)
    2120           2 :                         data.michael_mic_failure.unicast = 1;
    2121             :         } else
    2122           0 :                 data.michael_mic_failure.unicast = 1;
    2123             : 
    2124           2 :         if (tb[NL80211_ATTR_KEY_IDX]) {
    2125           2 :                 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
    2126           2 :                 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
    2127             :         }
    2128             : 
    2129           2 :         wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
    2130           2 : }
    2131             : 
    2132             : 
    2133           0 : static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
    2134             :                                  struct nlattr *tb[])
    2135             : {
    2136             :         unsigned int freq;
    2137             : 
    2138           0 :         if (tb[NL80211_ATTR_MAC] == NULL) {
    2139           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
    2140             :                            "event");
    2141           0 :                 return;
    2142             :         }
    2143           0 :         os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
    2144             : 
    2145           0 :         drv->associated = 1;
    2146           0 :         wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
    2147           0 :                    MAC2STR(drv->bssid));
    2148             : 
    2149           0 :         freq = nl80211_get_assoc_freq(drv);
    2150           0 :         if (freq) {
    2151           0 :                 wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
    2152             :                            freq);
    2153           0 :                 drv->first_bss->freq = freq;
    2154             :         }
    2155             : 
    2156           0 :         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
    2157             : }
    2158             : 
    2159             : 
    2160           0 : static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
    2161             :                                          int cancel_event, struct nlattr *tb[])
    2162             : {
    2163             :         unsigned int freq, chan_type, duration;
    2164             :         union wpa_event_data data;
    2165             :         u64 cookie;
    2166             : 
    2167           0 :         if (tb[NL80211_ATTR_WIPHY_FREQ])
    2168           0 :                 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
    2169             :         else
    2170           0 :                 freq = 0;
    2171             : 
    2172           0 :         if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
    2173           0 :                 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
    2174             :         else
    2175           0 :                 chan_type = 0;
    2176             : 
    2177           0 :         if (tb[NL80211_ATTR_DURATION])
    2178           0 :                 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
    2179             :         else
    2180           0 :                 duration = 0;
    2181             : 
    2182           0 :         if (tb[NL80211_ATTR_COOKIE])
    2183           0 :                 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
    2184             :         else
    2185           0 :                 cookie = 0;
    2186             : 
    2187           0 :         wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
    2188             :                    "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
    2189             :                    cancel_event, freq, chan_type, duration,
    2190             :                    (long long unsigned int) cookie,
    2191           0 :                    cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
    2192             : 
    2193           0 :         if (cookie != drv->remain_on_chan_cookie)
    2194           0 :                 return; /* not for us */
    2195             : 
    2196           0 :         if (cancel_event)
    2197           0 :                 drv->pending_remain_on_chan = 0;
    2198             : 
    2199           0 :         os_memset(&data, 0, sizeof(data));
    2200           0 :         data.remain_on_channel.freq = freq;
    2201           0 :         data.remain_on_channel.duration = duration;
    2202           0 :         wpa_supplicant_event(drv->ctx, cancel_event ?
    2203             :                              EVENT_CANCEL_REMAIN_ON_CHANNEL :
    2204             :                              EVENT_REMAIN_ON_CHANNEL, &data);
    2205             : }
    2206             : 
    2207             : 
    2208           0 : static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
    2209             :                                 struct nlattr *tb[])
    2210             : {
    2211             :         union wpa_event_data data;
    2212             : 
    2213           0 :         os_memset(&data, 0, sizeof(data));
    2214             : 
    2215           0 :         if (tb[NL80211_ATTR_IE]) {
    2216           0 :                 data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
    2217           0 :                 data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
    2218             :         }
    2219             : 
    2220           0 :         if (tb[NL80211_ATTR_IE_RIC]) {
    2221           0 :                 data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
    2222           0 :                 data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
    2223             :         }
    2224             : 
    2225           0 :         if (tb[NL80211_ATTR_MAC])
    2226           0 :                 os_memcpy(data.ft_ies.target_ap,
    2227             :                           nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
    2228             : 
    2229           0 :         wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
    2230           0 :                    MAC2STR(data.ft_ies.target_ap));
    2231             : 
    2232           0 :         wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
    2233           0 : }
    2234             : 
    2235             : 
    2236          63 : static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
    2237             :                             struct nlattr *tb[])
    2238             : {
    2239             :         union wpa_event_data event;
    2240             :         struct nlattr *nl;
    2241             :         int rem;
    2242             :         struct scan_info *info;
    2243             : #define MAX_REPORT_FREQS 50
    2244             :         int freqs[MAX_REPORT_FREQS];
    2245          63 :         int num_freqs = 0;
    2246             : 
    2247          63 :         if (drv->scan_for_auth) {
    2248           0 :                 drv->scan_for_auth = 0;
    2249           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
    2250             :                            "cfg80211 BSS entry");
    2251           0 :                 wpa_driver_nl80211_authenticate_retry(drv);
    2252          63 :                 return;
    2253             :         }
    2254             : 
    2255          63 :         os_memset(&event, 0, sizeof(event));
    2256          63 :         info = &event.scan_info;
    2257          63 :         info->aborted = aborted;
    2258             : 
    2259          63 :         if (tb[NL80211_ATTR_SCAN_SSIDS]) {
    2260          63 :                 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
    2261           0 :                         struct wpa_driver_scan_ssid *s =
    2262           0 :                                 &info->ssids[info->num_ssids];
    2263           0 :                         s->ssid = nla_data(nl);
    2264           0 :                         s->ssid_len = nla_len(nl);
    2265           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
    2266             :                                    wpa_ssid_txt(s->ssid, s->ssid_len));
    2267           0 :                         info->num_ssids++;
    2268           0 :                         if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
    2269           0 :                                 break;
    2270             :                 }
    2271             :         }
    2272          63 :         if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
    2273             :                 char msg[200], *pos, *end;
    2274             :                 int res;
    2275             : 
    2276          63 :                 pos = msg;
    2277          63 :                 end = pos + sizeof(msg);
    2278          63 :                 *pos = '\0';
    2279             : 
    2280         570 :                 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
    2281             :                 {
    2282         507 :                         freqs[num_freqs] = nla_get_u32(nl);
    2283         507 :                         res = os_snprintf(pos, end - pos, " %d",
    2284             :                                           freqs[num_freqs]);
    2285         507 :                         if (res > 0 && end - pos > res)
    2286         507 :                                 pos += res;
    2287         507 :                         num_freqs++;
    2288         507 :                         if (num_freqs == MAX_REPORT_FREQS - 1)
    2289           0 :                                 break;
    2290             :                 }
    2291          63 :                 info->freqs = freqs;
    2292          63 :                 info->num_freqs = num_freqs;
    2293          63 :                 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
    2294             :                            msg);
    2295             :         }
    2296          63 :         wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
    2297             : }
    2298             : 
    2299             : 
    2300           0 : static int get_link_signal(struct nl_msg *msg, void *arg)
    2301             : {
    2302             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    2303           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    2304             :         struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
    2305             :         static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
    2306             :                 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
    2307             :                 [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
    2308             :         };
    2309             :         struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
    2310             :         static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
    2311             :                 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
    2312             :                 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
    2313             :                 [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
    2314             :                 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
    2315             :         };
    2316           0 :         struct wpa_signal_info *sig_change = arg;
    2317             : 
    2318           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    2319             :                   genlmsg_attrlen(gnlh, 0), NULL);
    2320           0 :         if (!tb[NL80211_ATTR_STA_INFO] ||
    2321           0 :             nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
    2322             :                              tb[NL80211_ATTR_STA_INFO], policy))
    2323           0 :                 return NL_SKIP;
    2324           0 :         if (!sinfo[NL80211_STA_INFO_SIGNAL])
    2325           0 :                 return NL_SKIP;
    2326             : 
    2327           0 :         sig_change->current_signal =
    2328           0 :                 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
    2329             : 
    2330           0 :         if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
    2331           0 :                 sig_change->avg_signal =
    2332           0 :                         (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
    2333             :         else
    2334           0 :                 sig_change->avg_signal = 0;
    2335             : 
    2336           0 :         if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
    2337           0 :                 if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
    2338             :                                      sinfo[NL80211_STA_INFO_TX_BITRATE],
    2339             :                                      rate_policy)) {
    2340           0 :                         sig_change->current_txrate = 0;
    2341             :                 } else {
    2342           0 :                         if (rinfo[NL80211_RATE_INFO_BITRATE]) {
    2343           0 :                                 sig_change->current_txrate =
    2344           0 :                                         nla_get_u16(rinfo[
    2345           0 :                                              NL80211_RATE_INFO_BITRATE]) * 100;
    2346             :                         }
    2347             :                 }
    2348             :         }
    2349             : 
    2350           0 :         return NL_SKIP;
    2351             : }
    2352             : 
    2353             : 
    2354           0 : static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
    2355             :                                    struct wpa_signal_info *sig)
    2356             : {
    2357             :         struct nl_msg *msg;
    2358             : 
    2359           0 :         sig->current_signal = -9999;
    2360           0 :         sig->current_txrate = 0;
    2361             : 
    2362           0 :         msg = nlmsg_alloc();
    2363           0 :         if (!msg)
    2364           0 :                 return -ENOMEM;
    2365             : 
    2366           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
    2367             : 
    2368           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    2369           0 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
    2370             : 
    2371           0 :         return send_and_recv_msgs(drv, msg, get_link_signal, sig);
    2372             :  nla_put_failure:
    2373           0 :         nlmsg_free(msg);
    2374           0 :         return -ENOBUFS;
    2375             : }
    2376             : 
    2377             : 
    2378           0 : static int get_link_noise(struct nl_msg *msg, void *arg)
    2379             : {
    2380             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    2381           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    2382             :         struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
    2383             :         static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
    2384             :                 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
    2385             :                 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
    2386             :         };
    2387           0 :         struct wpa_signal_info *sig_change = arg;
    2388             : 
    2389           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    2390             :                   genlmsg_attrlen(gnlh, 0), NULL);
    2391             : 
    2392           0 :         if (!tb[NL80211_ATTR_SURVEY_INFO]) {
    2393           0 :                 wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
    2394           0 :                 return NL_SKIP;
    2395             :         }
    2396             : 
    2397           0 :         if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
    2398             :                              tb[NL80211_ATTR_SURVEY_INFO],
    2399             :                              survey_policy)) {
    2400           0 :                 wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
    2401             :                            "attributes!");
    2402           0 :                 return NL_SKIP;
    2403             :         }
    2404             : 
    2405           0 :         if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
    2406           0 :                 return NL_SKIP;
    2407             : 
    2408           0 :         if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
    2409           0 :             sig_change->frequency)
    2410           0 :                 return NL_SKIP;
    2411             : 
    2412           0 :         if (!sinfo[NL80211_SURVEY_INFO_NOISE])
    2413           0 :                 return NL_SKIP;
    2414             : 
    2415           0 :         sig_change->current_noise =
    2416           0 :                 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
    2417             : 
    2418           0 :         return NL_SKIP;
    2419             : }
    2420             : 
    2421             : 
    2422           0 : static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
    2423             :                                   struct wpa_signal_info *sig_change)
    2424             : {
    2425             :         struct nl_msg *msg;
    2426             : 
    2427           0 :         sig_change->current_noise = 9999;
    2428           0 :         sig_change->frequency = drv->assoc_freq;
    2429             : 
    2430           0 :         msg = nlmsg_alloc();
    2431           0 :         if (!msg)
    2432           0 :                 return -ENOMEM;
    2433             : 
    2434           0 :         nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
    2435             : 
    2436           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    2437             : 
    2438           0 :         return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
    2439             :  nla_put_failure:
    2440           0 :         nlmsg_free(msg);
    2441           0 :         return -ENOBUFS;
    2442             : }
    2443             : 
    2444             : 
    2445          27 : static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
    2446             : {
    2447             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    2448          27 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    2449             :         struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
    2450             :         static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
    2451             :                 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
    2452             :                 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
    2453             :         };
    2454          27 :         struct wpa_scan_results *scan_results = arg;
    2455             :         struct wpa_scan_res *scan_res;
    2456             :         size_t i;
    2457             : 
    2458          27 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    2459             :                   genlmsg_attrlen(gnlh, 0), NULL);
    2460             : 
    2461          27 :         if (!tb[NL80211_ATTR_SURVEY_INFO]) {
    2462           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Survey data missing");
    2463           0 :                 return NL_SKIP;
    2464             :         }
    2465             : 
    2466          27 :         if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
    2467             :                              tb[NL80211_ATTR_SURVEY_INFO],
    2468             :                              survey_policy)) {
    2469           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to parse nested "
    2470             :                            "attributes");
    2471           0 :                 return NL_SKIP;
    2472             :         }
    2473             : 
    2474          27 :         if (!sinfo[NL80211_SURVEY_INFO_NOISE])
    2475           0 :                 return NL_SKIP;
    2476             : 
    2477          27 :         if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
    2478           0 :                 return NL_SKIP;
    2479             : 
    2480          34 :         for (i = 0; i < scan_results->num; ++i) {
    2481           7 :                 scan_res = scan_results->res[i];
    2482           7 :                 if (!scan_res)
    2483           0 :                         continue;
    2484          14 :                 if ((int) nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
    2485           7 :                     scan_res->freq)
    2486           4 :                         continue;
    2487           3 :                 if (!(scan_res->flags & WPA_SCAN_NOISE_INVALID))
    2488           0 :                         continue;
    2489           3 :                 scan_res->noise = (s8)
    2490           3 :                         nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
    2491           3 :                 scan_res->flags &= ~WPA_SCAN_NOISE_INVALID;
    2492             :         }
    2493             : 
    2494          27 :         return NL_SKIP;
    2495             : }
    2496             : 
    2497             : 
    2498          28 : static int nl80211_get_noise_for_scan_results(
    2499             :         struct wpa_driver_nl80211_data *drv,
    2500             :         struct wpa_scan_results *scan_res)
    2501             : {
    2502             :         struct nl_msg *msg;
    2503             : 
    2504          28 :         msg = nlmsg_alloc();
    2505          28 :         if (!msg)
    2506           0 :                 return -ENOMEM;
    2507             : 
    2508          28 :         nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
    2509             : 
    2510          28 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    2511             : 
    2512          28 :         return send_and_recv_msgs(drv, msg, get_noise_for_scan_results,
    2513             :                                   scan_res);
    2514             :  nla_put_failure:
    2515           0 :         nlmsg_free(msg);
    2516           0 :         return -ENOBUFS;
    2517             : }
    2518             : 
    2519             : 
    2520           0 : static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
    2521             :                               struct nlattr *tb[])
    2522             : {
    2523             :         static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
    2524             :                 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
    2525             :                 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
    2526             :                 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
    2527             :                 [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
    2528             :         };
    2529             :         struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
    2530             :         enum nl80211_cqm_rssi_threshold_event event;
    2531             :         union wpa_event_data ed;
    2532             :         struct wpa_signal_info sig;
    2533             :         int res;
    2534             : 
    2535           0 :         if (tb[NL80211_ATTR_CQM] == NULL ||
    2536           0 :             nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
    2537             :                              cqm_policy)) {
    2538           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
    2539           0 :                 return;
    2540             :         }
    2541             : 
    2542           0 :         os_memset(&ed, 0, sizeof(ed));
    2543             : 
    2544           0 :         if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
    2545           0 :                 if (!tb[NL80211_ATTR_MAC])
    2546           0 :                         return;
    2547           0 :                 os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
    2548             :                           ETH_ALEN);
    2549           0 :                 wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
    2550           0 :                 return;
    2551             :         }
    2552             : 
    2553           0 :         if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
    2554           0 :                 return;
    2555           0 :         event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
    2556             : 
    2557           0 :         if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
    2558           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
    2559             :                            "event: RSSI high");
    2560           0 :                 ed.signal_change.above_threshold = 1;
    2561           0 :         } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
    2562           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
    2563             :                            "event: RSSI low");
    2564           0 :                 ed.signal_change.above_threshold = 0;
    2565             :         } else
    2566           0 :                 return;
    2567             : 
    2568           0 :         res = nl80211_get_link_signal(drv, &sig);
    2569           0 :         if (res == 0) {
    2570           0 :                 ed.signal_change.current_signal = sig.current_signal;
    2571           0 :                 ed.signal_change.current_txrate = sig.current_txrate;
    2572           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm  txrate: %d",
    2573             :                            sig.current_signal, sig.current_txrate);
    2574             :         }
    2575             : 
    2576           0 :         res = nl80211_get_link_noise(drv, &sig);
    2577           0 :         if (res == 0) {
    2578           0 :                 ed.signal_change.current_noise = sig.current_noise;
    2579           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
    2580             :                            sig.current_noise);
    2581             :         }
    2582             : 
    2583           0 :         wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
    2584             : }
    2585             : 
    2586             : 
    2587        1299 : static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
    2588             :                                       struct nlattr **tb)
    2589             : {
    2590             :         u8 *addr;
    2591             :         union wpa_event_data data;
    2592             : 
    2593        1299 :         if (tb[NL80211_ATTR_MAC] == NULL)
    2594        1299 :                 return;
    2595        1299 :         addr = nla_data(tb[NL80211_ATTR_MAC]);
    2596        1299 :         wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
    2597             : 
    2598        1299 :         if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
    2599           0 :                 u8 *ies = NULL;
    2600           0 :                 size_t ies_len = 0;
    2601           0 :                 if (tb[NL80211_ATTR_IE]) {
    2602           0 :                         ies = nla_data(tb[NL80211_ATTR_IE]);
    2603           0 :                         ies_len = nla_len(tb[NL80211_ATTR_IE]);
    2604             :                 }
    2605           0 :                 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
    2606           0 :                 drv_event_assoc(drv->ctx, addr, ies, ies_len, 0);
    2607           0 :                 return;
    2608             :         }
    2609             : 
    2610        1299 :         if (drv->nlmode != NL80211_IFTYPE_ADHOC)
    2611        1299 :                 return;
    2612             : 
    2613           0 :         os_memset(&data, 0, sizeof(data));
    2614           0 :         os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
    2615           0 :         wpa_supplicant_event(drv->ctx, EVENT_IBSS_RSN_START, &data);
    2616             : }
    2617             : 
    2618             : 
    2619        1252 : static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
    2620             :                                       struct nlattr **tb)
    2621             : {
    2622             :         u8 *addr;
    2623             :         union wpa_event_data data;
    2624             : 
    2625        1252 :         if (tb[NL80211_ATTR_MAC] == NULL)
    2626        1252 :                 return;
    2627        1252 :         addr = nla_data(tb[NL80211_ATTR_MAC]);
    2628        7512 :         wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
    2629        7512 :                    MAC2STR(addr));
    2630             : 
    2631        1252 :         if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
    2632           0 :                 drv_event_disassoc(drv->ctx, addr);
    2633           0 :                 return;
    2634             :         }
    2635             : 
    2636        1252 :         if (drv->nlmode != NL80211_IFTYPE_ADHOC)
    2637        1252 :                 return;
    2638             : 
    2639           0 :         os_memset(&data, 0, sizeof(data));
    2640           0 :         os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
    2641           0 :         wpa_supplicant_event(drv->ctx, EVENT_IBSS_PEER_LOST, &data);
    2642             : }
    2643             : 
    2644             : 
    2645           0 : static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
    2646             :                                         struct nlattr **tb)
    2647             : {
    2648             :         struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
    2649             :         static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
    2650             :                 [NL80211_REKEY_DATA_KEK] = {
    2651             :                         .minlen = NL80211_KEK_LEN,
    2652             :                         .maxlen = NL80211_KEK_LEN,
    2653             :                 },
    2654             :                 [NL80211_REKEY_DATA_KCK] = {
    2655             :                         .minlen = NL80211_KCK_LEN,
    2656             :                         .maxlen = NL80211_KCK_LEN,
    2657             :                 },
    2658             :                 [NL80211_REKEY_DATA_REPLAY_CTR] = {
    2659             :                         .minlen = NL80211_REPLAY_CTR_LEN,
    2660             :                         .maxlen = NL80211_REPLAY_CTR_LEN,
    2661             :                 },
    2662             :         };
    2663             :         union wpa_event_data data;
    2664             : 
    2665           0 :         if (!tb[NL80211_ATTR_MAC])
    2666           0 :                 return;
    2667           0 :         if (!tb[NL80211_ATTR_REKEY_DATA])
    2668           0 :                 return;
    2669           0 :         if (nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
    2670           0 :                              tb[NL80211_ATTR_REKEY_DATA], rekey_policy))
    2671           0 :                 return;
    2672           0 :         if (!rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
    2673           0 :                 return;
    2674             : 
    2675           0 :         os_memset(&data, 0, sizeof(data));
    2676           0 :         data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
    2677           0 :         wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
    2678           0 :                    MAC2STR(data.driver_gtk_rekey.bssid));
    2679           0 :         data.driver_gtk_rekey.replay_ctr =
    2680           0 :                 nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
    2681           0 :         wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
    2682           0 :                     data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
    2683           0 :         wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
    2684             : }
    2685             : 
    2686             : 
    2687           0 : static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
    2688             :                                           struct nlattr **tb)
    2689             : {
    2690             :         struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
    2691             :         static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
    2692             :                 [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
    2693             :                 [NL80211_PMKSA_CANDIDATE_BSSID] = {
    2694             :                         .minlen = ETH_ALEN,
    2695             :                         .maxlen = ETH_ALEN,
    2696             :                 },
    2697             :                 [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
    2698             :         };
    2699             :         union wpa_event_data data;
    2700             : 
    2701           0 :         wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
    2702             : 
    2703           0 :         if (!tb[NL80211_ATTR_PMKSA_CANDIDATE])
    2704           0 :                 return;
    2705           0 :         if (nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
    2706           0 :                              tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy))
    2707           0 :                 return;
    2708           0 :         if (!cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
    2709           0 :             !cand[NL80211_PMKSA_CANDIDATE_BSSID])
    2710           0 :                 return;
    2711             : 
    2712           0 :         os_memset(&data, 0, sizeof(data));
    2713           0 :         os_memcpy(data.pmkid_candidate.bssid,
    2714             :                   nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
    2715           0 :         data.pmkid_candidate.index =
    2716           0 :                 nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
    2717           0 :         data.pmkid_candidate.preauth =
    2718           0 :                 cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
    2719           0 :         wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
    2720             : }
    2721             : 
    2722             : 
    2723           2 : static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
    2724             :                                        struct nlattr **tb)
    2725             : {
    2726             :         union wpa_event_data data;
    2727             : 
    2728           2 :         wpa_printf(MSG_DEBUG, "nl80211: Probe client event");
    2729             : 
    2730           2 :         if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
    2731           4 :                 return;
    2732             : 
    2733           0 :         os_memset(&data, 0, sizeof(data));
    2734           0 :         os_memcpy(data.client_poll.addr,
    2735             :                   nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
    2736             : 
    2737           0 :         wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
    2738             : }
    2739             : 
    2740             : 
    2741           0 : static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
    2742             :                                     struct nlattr **tb)
    2743             : {
    2744             :         union wpa_event_data data;
    2745             : 
    2746           0 :         wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
    2747             : 
    2748           0 :         if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
    2749           0 :                 return;
    2750             : 
    2751           0 :         os_memset(&data, 0, sizeof(data));
    2752           0 :         os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
    2753           0 :         switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
    2754             :         case NL80211_TDLS_SETUP:
    2755           0 :                 wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
    2756           0 :                            MACSTR, MAC2STR(data.tdls.peer));
    2757           0 :                 data.tdls.oper = TDLS_REQUEST_SETUP;
    2758           0 :                 break;
    2759             :         case NL80211_TDLS_TEARDOWN:
    2760           0 :                 wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
    2761           0 :                            MACSTR, MAC2STR(data.tdls.peer));
    2762           0 :                 data.tdls.oper = TDLS_REQUEST_TEARDOWN;
    2763           0 :                 break;
    2764             :         default:
    2765           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
    2766             :                            "event");
    2767           0 :                 return;
    2768             :         }
    2769           0 :         if (tb[NL80211_ATTR_REASON_CODE]) {
    2770           0 :                 data.tdls.reason_code =
    2771           0 :                         nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
    2772             :         }
    2773             : 
    2774           0 :         wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
    2775             : }
    2776             : 
    2777             : 
    2778           0 : static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
    2779             :                             struct nlattr **tb)
    2780             : {
    2781           0 :         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
    2782           0 : }
    2783             : 
    2784             : 
    2785           0 : static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
    2786             :                                          struct nlattr **tb)
    2787             : {
    2788             :         union wpa_event_data data;
    2789             :         u32 reason;
    2790             : 
    2791           0 :         wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
    2792             : 
    2793           0 :         if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
    2794           0 :                 return;
    2795             : 
    2796           0 :         os_memset(&data, 0, sizeof(data));
    2797           0 :         os_memcpy(data.connect_failed_reason.addr,
    2798             :                   nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
    2799             : 
    2800           0 :         reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
    2801           0 :         switch (reason) {
    2802             :         case NL80211_CONN_FAIL_MAX_CLIENTS:
    2803           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
    2804           0 :                 data.connect_failed_reason.code = MAX_CLIENT_REACHED;
    2805           0 :                 break;
    2806             :         case NL80211_CONN_FAIL_BLOCKED_CLIENT:
    2807           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
    2808             :                            " tried to connect",
    2809           0 :                            MAC2STR(data.connect_failed_reason.addr));
    2810           0 :                 data.connect_failed_reason.code = BLOCKED_CLIENT;
    2811           0 :                 break;
    2812             :         default:
    2813           0 :                 wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
    2814             :                            "%u", reason);
    2815           0 :                 return;
    2816             :         }
    2817             : 
    2818           0 :         wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
    2819             : }
    2820             : 
    2821             : 
    2822           6 : static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
    2823             :                                 struct nlattr **tb)
    2824             : {
    2825             :         union wpa_event_data data;
    2826             :         enum nl80211_radar_event event_type;
    2827             : 
    2828           6 :         if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
    2829           6 :                 return;
    2830             : 
    2831           6 :         os_memset(&data, 0, sizeof(data));
    2832           6 :         data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
    2833           6 :         event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
    2834             : 
    2835             :         /* Check HT params */
    2836           6 :         if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
    2837           4 :                 data.dfs_event.ht_enabled = 1;
    2838           4 :                 data.dfs_event.chan_offset = 0;
    2839             : 
    2840           4 :                 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
    2841             :                 case NL80211_CHAN_NO_HT:
    2842           0 :                         data.dfs_event.ht_enabled = 0;
    2843           0 :                         break;
    2844             :                 case NL80211_CHAN_HT20:
    2845           4 :                         break;
    2846             :                 case NL80211_CHAN_HT40PLUS:
    2847           0 :                         data.dfs_event.chan_offset = 1;
    2848           0 :                         break;
    2849             :                 case NL80211_CHAN_HT40MINUS:
    2850           0 :                         data.dfs_event.chan_offset = -1;
    2851           0 :                         break;
    2852             :                 }
    2853             :         }
    2854             : 
    2855             :         /* Get VHT params */
    2856           6 :         if (tb[NL80211_ATTR_CHANNEL_WIDTH])
    2857           6 :                 data.dfs_event.chan_width =
    2858           6 :                         convert2width(nla_get_u32(
    2859           6 :                                               tb[NL80211_ATTR_CHANNEL_WIDTH]));
    2860           6 :         if (tb[NL80211_ATTR_CENTER_FREQ1])
    2861           6 :                 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
    2862           6 :         if (tb[NL80211_ATTR_CENTER_FREQ2])
    2863           0 :                 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
    2864             : 
    2865          12 :         wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
    2866             :                    data.dfs_event.freq, data.dfs_event.ht_enabled,
    2867           6 :                    data.dfs_event.chan_offset, data.dfs_event.chan_width,
    2868             :                    data.dfs_event.cf1, data.dfs_event.cf2);
    2869             : 
    2870           6 :         switch (event_type) {
    2871             :         case NL80211_RADAR_DETECTED:
    2872           1 :                 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
    2873           1 :                 break;
    2874             :         case NL80211_RADAR_CAC_FINISHED:
    2875           4 :                 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
    2876           4 :                 break;
    2877             :         case NL80211_RADAR_CAC_ABORTED:
    2878           1 :                 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
    2879           1 :                 break;
    2880             :         case NL80211_RADAR_NOP_FINISHED:
    2881           0 :                 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
    2882           0 :                 break;
    2883             :         default:
    2884           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
    2885             :                            "received", event_type);
    2886           0 :                 break;
    2887             :         }
    2888             : }
    2889             : 
    2890             : 
    2891           7 : static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
    2892             :                                    int wds)
    2893             : {
    2894           7 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    2895             :         union wpa_event_data event;
    2896             : 
    2897           7 :         if (!tb[NL80211_ATTR_MAC])
    2898           7 :                 return;
    2899             : 
    2900           7 :         os_memset(&event, 0, sizeof(event));
    2901           7 :         event.rx_from_unknown.bssid = bss->addr;
    2902           7 :         event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
    2903           7 :         event.rx_from_unknown.wds = wds;
    2904             : 
    2905           7 :         wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
    2906             : }
    2907             : 
    2908             : 
    2909           0 : static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
    2910             :                                    const u8 *data, size_t len)
    2911             : {
    2912             :         u32 i, count;
    2913             :         union wpa_event_data event;
    2914           0 :         struct wpa_freq_range *range = NULL;
    2915             :         const struct qca_avoid_freq_list *freq_range;
    2916             : 
    2917           0 :         freq_range = (const struct qca_avoid_freq_list *) data;
    2918           0 :         if (len < sizeof(freq_range->count))
    2919           0 :                 return;
    2920             : 
    2921           0 :         count = freq_range->count;
    2922           0 :         if (len < sizeof(freq_range->count) +
    2923           0 :             count * sizeof(struct qca_avoid_freq_range)) {
    2924           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
    2925             :                            (unsigned int) len);
    2926           0 :                 return;
    2927             :         }
    2928             : 
    2929           0 :         if (count > 0) {
    2930           0 :                 range = os_calloc(count, sizeof(struct wpa_freq_range));
    2931           0 :                 if (range == NULL)
    2932           0 :                         return;
    2933             :         }
    2934             : 
    2935           0 :         os_memset(&event, 0, sizeof(event));
    2936           0 :         for (i = 0; i < count; i++) {
    2937           0 :                 unsigned int idx = event.freq_range.num;
    2938           0 :                 range[idx].min = freq_range->range[i].start_freq;
    2939           0 :                 range[idx].max = freq_range->range[i].end_freq;
    2940           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
    2941           0 :                            range[idx].min, range[idx].max);
    2942           0 :                 if (range[idx].min > range[idx].max) {
    2943           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
    2944           0 :                         continue;
    2945             :                 }
    2946           0 :                 event.freq_range.num++;
    2947             :         }
    2948           0 :         event.freq_range.range = range;
    2949             : 
    2950           0 :         wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
    2951             : 
    2952           0 :         os_free(range);
    2953             : }
    2954             : 
    2955             : 
    2956           0 : static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
    2957             :                                      u32 subcmd, u8 *data, size_t len)
    2958             : {
    2959           0 :         switch (subcmd) {
    2960             :         case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
    2961           0 :                 qca_nl80211_avoid_freq(drv, data, len);
    2962           0 :                 break;
    2963             :         default:
    2964           0 :                 wpa_printf(MSG_DEBUG,
    2965             :                            "nl80211: Ignore unsupported QCA vendor event %u",
    2966             :                            subcmd);
    2967           0 :                 break;
    2968             :         }
    2969           0 : }
    2970             : 
    2971             : 
    2972           0 : static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
    2973             :                                  struct nlattr **tb)
    2974             : {
    2975           0 :         u32 vendor_id, subcmd, wiphy = 0;
    2976             :         int wiphy_idx;
    2977           0 :         u8 *data = NULL;
    2978           0 :         size_t len = 0;
    2979             : 
    2980           0 :         if (!tb[NL80211_ATTR_VENDOR_ID] ||
    2981           0 :             !tb[NL80211_ATTR_VENDOR_SUBCMD])
    2982           0 :                 return;
    2983             : 
    2984           0 :         vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
    2985           0 :         subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
    2986             : 
    2987           0 :         if (tb[NL80211_ATTR_WIPHY])
    2988           0 :                 wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
    2989             : 
    2990           0 :         wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
    2991             :                    wiphy, vendor_id, subcmd);
    2992             : 
    2993           0 :         if (tb[NL80211_ATTR_VENDOR_DATA]) {
    2994           0 :                 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
    2995           0 :                 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
    2996           0 :                 wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
    2997             :         }
    2998             : 
    2999           0 :         wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
    3000           0 :         if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
    3001           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
    3002             :                            wiphy, wiphy_idx);
    3003           0 :                 return;
    3004             :         }
    3005             : 
    3006           0 :         switch (vendor_id) {
    3007             :         case OUI_QCA:
    3008           0 :                 nl80211_vendor_event_qca(drv, subcmd, data, len);
    3009           0 :                 break;
    3010             :         default:
    3011           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
    3012           0 :                 break;
    3013             :         }
    3014             : }
    3015             : 
    3016             : 
    3017         794 : static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
    3018             :                                      struct nlattr *tb[])
    3019             : {
    3020             :         union wpa_event_data data;
    3021             :         enum nl80211_reg_initiator init;
    3022             : 
    3023         794 :         wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
    3024             : 
    3025         794 :         if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
    3026         794 :                 return;
    3027             : 
    3028         794 :         os_memset(&data, 0, sizeof(data));
    3029         794 :         init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
    3030         794 :         wpa_printf(MSG_DEBUG, " * initiator=%d", init);
    3031         794 :         switch (init) {
    3032             :         case NL80211_REGDOM_SET_BY_CORE:
    3033         764 :                 data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
    3034         764 :                 break;
    3035             :         case NL80211_REGDOM_SET_BY_USER:
    3036          25 :                 data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
    3037          25 :                 break;
    3038             :         case NL80211_REGDOM_SET_BY_DRIVER:
    3039           0 :                 data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
    3040           0 :                 break;
    3041             :         case NL80211_REGDOM_SET_BY_COUNTRY_IE:
    3042           5 :                 data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
    3043           5 :                 break;
    3044             :         }
    3045             : 
    3046         794 :         if (tb[NL80211_ATTR_REG_TYPE]) {
    3047             :                 enum nl80211_reg_type type;
    3048         794 :                 type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
    3049         794 :                 wpa_printf(MSG_DEBUG, " * type=%d", type);
    3050         794 :                 switch (type) {
    3051             :                 case NL80211_REGDOM_TYPE_COUNTRY:
    3052          30 :                         data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
    3053          30 :                         break;
    3054             :                 case NL80211_REGDOM_TYPE_WORLD:
    3055         764 :                         data.channel_list_changed.type = REGDOM_TYPE_WORLD;
    3056         764 :                         break;
    3057             :                 case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
    3058           0 :                         data.channel_list_changed.type =
    3059             :                                 REGDOM_TYPE_CUSTOM_WORLD;
    3060           0 :                         break;
    3061             :                 case NL80211_REGDOM_TYPE_INTERSECTION:
    3062           0 :                         data.channel_list_changed.type =
    3063             :                                 REGDOM_TYPE_INTERSECTION;
    3064           0 :                         break;
    3065             :                 }
    3066             :         }
    3067             : 
    3068         794 :         if (tb[NL80211_ATTR_REG_ALPHA2]) {
    3069          30 :                 os_strlcpy(data.channel_list_changed.alpha2,
    3070          30 :                            nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
    3071             :                            sizeof(data.channel_list_changed.alpha2));
    3072          30 :                 wpa_printf(MSG_DEBUG, " * alpha2=%s",
    3073             :                            data.channel_list_changed.alpha2);
    3074             :         }
    3075             : 
    3076         794 :         wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
    3077             : }
    3078             : 
    3079             : 
    3080        7005 : static void do_process_drv_event(struct i802_bss *bss, int cmd,
    3081             :                                  struct nlattr **tb)
    3082             : {
    3083        7005 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3084             :         union wpa_event_data data;
    3085             : 
    3086        7005 :         wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
    3087        7005 :                    cmd, nl80211_command_to_string(cmd), bss->ifname);
    3088             : 
    3089        7005 :         if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
    3090           0 :             (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
    3091             :              cmd == NL80211_CMD_SCAN_ABORTED)) {
    3092           0 :                 wpa_driver_nl80211_set_mode(drv->first_bss,
    3093             :                                             drv->ap_scan_as_station);
    3094           0 :                 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
    3095             :         }
    3096             : 
    3097        7005 :         switch (cmd) {
    3098             :         case NL80211_CMD_TRIGGER_SCAN:
    3099          68 :                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
    3100          68 :                 drv->scan_state = SCAN_STARTED;
    3101          68 :                 if (drv->scan_for_auth) {
    3102             :                         /*
    3103             :                          * Cannot indicate EVENT_SCAN_STARTED here since we skip
    3104             :                          * EVENT_SCAN_RESULTS in scan_for_auth case and the
    3105             :                          * upper layer implementation could get confused about
    3106             :                          * scanning state.
    3107             :                          */
    3108           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
    3109           0 :                         break;
    3110             :                 }
    3111          68 :                 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
    3112          68 :                 break;
    3113             :         case NL80211_CMD_START_SCHED_SCAN:
    3114           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
    3115           0 :                 drv->scan_state = SCHED_SCAN_STARTED;
    3116           0 :                 break;
    3117             :         case NL80211_CMD_SCHED_SCAN_STOPPED:
    3118           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
    3119           0 :                 drv->scan_state = SCHED_SCAN_STOPPED;
    3120           0 :                 wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
    3121           0 :                 break;
    3122             :         case NL80211_CMD_NEW_SCAN_RESULTS:
    3123          63 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    3124             :                         "nl80211: New scan results available");
    3125          63 :                 drv->scan_state = SCAN_COMPLETED;
    3126          63 :                 drv->scan_complete_events = 1;
    3127          63 :                 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
    3128             :                                      drv->ctx);
    3129          63 :                 send_scan_event(drv, 0, tb);
    3130          63 :                 break;
    3131             :         case NL80211_CMD_SCHED_SCAN_RESULTS:
    3132           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    3133             :                         "nl80211: New sched scan results available");
    3134           0 :                 drv->scan_state = SCHED_SCAN_RESULTS;
    3135           0 :                 send_scan_event(drv, 0, tb);
    3136           0 :                 break;
    3137             :         case NL80211_CMD_SCAN_ABORTED:
    3138           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
    3139           0 :                 drv->scan_state = SCAN_ABORTED;
    3140             :                 /*
    3141             :                  * Need to indicate that scan results are available in order
    3142             :                  * not to make wpa_supplicant stop its scanning.
    3143             :                  */
    3144           0 :                 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
    3145             :                                      drv->ctx);
    3146           0 :                 send_scan_event(drv, 1, tb);
    3147           0 :                 break;
    3148             :         case NL80211_CMD_AUTHENTICATE:
    3149             :         case NL80211_CMD_ASSOCIATE:
    3150             :         case NL80211_CMD_DEAUTHENTICATE:
    3151             :         case NL80211_CMD_DISASSOCIATE:
    3152             :         case NL80211_CMD_FRAME_TX_STATUS:
    3153             :         case NL80211_CMD_UNPROT_DEAUTHENTICATE:
    3154             :         case NL80211_CMD_UNPROT_DISASSOCIATE:
    3155       21072 :                 mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
    3156        7024 :                            tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
    3157        7024 :                            tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
    3158        3512 :                            tb[NL80211_ATTR_COOKIE],
    3159        3512 :                            tb[NL80211_ATTR_RX_SIGNAL_DBM]);
    3160        3512 :                 break;
    3161             :         case NL80211_CMD_CONNECT:
    3162             :         case NL80211_CMD_ROAM:
    3163           0 :                 mlme_event_connect(drv, cmd,
    3164           0 :                                    tb[NL80211_ATTR_STATUS_CODE],
    3165           0 :                                    tb[NL80211_ATTR_MAC],
    3166           0 :                                    tb[NL80211_ATTR_REQ_IE],
    3167           0 :                                    tb[NL80211_ATTR_RESP_IE]);
    3168           0 :                 break;
    3169             :         case NL80211_CMD_CH_SWITCH_NOTIFY:
    3170           6 :                 mlme_event_ch_switch(drv,
    3171           1 :                                      tb[NL80211_ATTR_IFINDEX],
    3172           1 :                                      tb[NL80211_ATTR_WIPHY_FREQ],
    3173           1 :                                      tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
    3174           1 :                                      tb[NL80211_ATTR_CHANNEL_WIDTH],
    3175           1 :                                      tb[NL80211_ATTR_CENTER_FREQ1],
    3176           1 :                                      tb[NL80211_ATTR_CENTER_FREQ2]);
    3177           1 :                 break;
    3178             :         case NL80211_CMD_DISCONNECT:
    3179           0 :                 mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
    3180           0 :                                       tb[NL80211_ATTR_MAC],
    3181           0 :                                       tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
    3182           0 :                 break;
    3183             :         case NL80211_CMD_MICHAEL_MIC_FAILURE:
    3184           2 :                 mlme_event_michael_mic_failure(bss, tb);
    3185           2 :                 break;
    3186             :         case NL80211_CMD_JOIN_IBSS:
    3187           0 :                 mlme_event_join_ibss(drv, tb);
    3188           0 :                 break;
    3189             :         case NL80211_CMD_REMAIN_ON_CHANNEL:
    3190           0 :                 mlme_event_remain_on_channel(drv, 0, tb);
    3191           0 :                 break;
    3192             :         case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
    3193           0 :                 mlme_event_remain_on_channel(drv, 1, tb);
    3194           0 :                 break;
    3195             :         case NL80211_CMD_NOTIFY_CQM:
    3196           0 :                 nl80211_cqm_event(drv, tb);
    3197           0 :                 break;
    3198             :         case NL80211_CMD_REG_CHANGE:
    3199         794 :                 nl80211_reg_change_event(drv, tb);
    3200         794 :                 break;
    3201             :         case NL80211_CMD_REG_BEACON_HINT:
    3202           6 :                 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
    3203           6 :                 os_memset(&data, 0, sizeof(data));
    3204           6 :                 data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
    3205           6 :                 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
    3206             :                                      &data);
    3207           6 :                 break;
    3208             :         case NL80211_CMD_NEW_STATION:
    3209        1299 :                 nl80211_new_station_event(drv, tb);
    3210        1299 :                 break;
    3211             :         case NL80211_CMD_DEL_STATION:
    3212        1252 :                 nl80211_del_station_event(drv, tb);
    3213        1252 :                 break;
    3214             :         case NL80211_CMD_SET_REKEY_OFFLOAD:
    3215           0 :                 nl80211_rekey_offload_event(drv, tb);
    3216           0 :                 break;
    3217             :         case NL80211_CMD_PMKSA_CANDIDATE:
    3218           0 :                 nl80211_pmksa_candidate_event(drv, tb);
    3219           0 :                 break;
    3220             :         case NL80211_CMD_PROBE_CLIENT:
    3221           2 :                 nl80211_client_probe_event(drv, tb);
    3222           2 :                 break;
    3223             :         case NL80211_CMD_TDLS_OPER:
    3224           0 :                 nl80211_tdls_oper_event(drv, tb);
    3225           0 :                 break;
    3226             :         case NL80211_CMD_CONN_FAILED:
    3227           0 :                 nl80211_connect_failed_event(drv, tb);
    3228           0 :                 break;
    3229             :         case NL80211_CMD_FT_EVENT:
    3230           0 :                 mlme_event_ft_event(drv, tb);
    3231           0 :                 break;
    3232             :         case NL80211_CMD_RADAR_DETECT:
    3233           6 :                 nl80211_radar_event(drv, tb);
    3234           6 :                 break;
    3235             :         case NL80211_CMD_STOP_AP:
    3236           0 :                 nl80211_stop_ap(drv, tb);
    3237           0 :                 break;
    3238             :         case NL80211_CMD_VENDOR:
    3239           0 :                 nl80211_vendor_event(drv, tb);
    3240           0 :                 break;
    3241             :         default:
    3242           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
    3243             :                         "(cmd=%d)", cmd);
    3244           0 :                 break;
    3245             :         }
    3246        7005 : }
    3247             : 
    3248             : 
    3249           0 : static int process_drv_event(struct nl_msg *msg, void *arg)
    3250             : {
    3251           0 :         struct wpa_driver_nl80211_data *drv = arg;
    3252           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    3253             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    3254             :         struct i802_bss *bss;
    3255           0 :         int ifidx = -1;
    3256             : 
    3257           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    3258             :                   genlmsg_attrlen(gnlh, 0), NULL);
    3259             : 
    3260           0 :         if (tb[NL80211_ATTR_IFINDEX]) {
    3261           0 :                 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
    3262             : 
    3263           0 :                 for (bss = drv->first_bss; bss; bss = bss->next)
    3264           0 :                         if (ifidx == -1 || ifidx == bss->ifindex) {
    3265           0 :                                 do_process_drv_event(bss, gnlh->cmd, tb);
    3266           0 :                                 return NL_SKIP;
    3267             :                         }
    3268           0 :                 wpa_printf(MSG_DEBUG,
    3269             :                            "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d)",
    3270           0 :                            gnlh->cmd, ifidx);
    3271           0 :         } else if (tb[NL80211_ATTR_WDEV]) {
    3272           0 :                 u64 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
    3273           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Process event on P2P device");
    3274           0 :                 for (bss = drv->first_bss; bss; bss = bss->next) {
    3275           0 :                         if (bss->wdev_id_set && wdev_id == bss->wdev_id) {
    3276           0 :                                 do_process_drv_event(bss, gnlh->cmd, tb);
    3277           0 :                                 return NL_SKIP;
    3278             :                         }
    3279             :                 }
    3280           0 :                 wpa_printf(MSG_DEBUG,
    3281             :                            "nl80211: Ignored event (cmd=%d) for foreign interface (wdev 0x%llx)",
    3282           0 :                            gnlh->cmd, (long long unsigned int) wdev_id);
    3283             :         }
    3284             : 
    3285           0 :         return NL_SKIP;
    3286             : }
    3287             : 
    3288             : 
    3289       29286 : static int process_global_event(struct nl_msg *msg, void *arg)
    3290             : {
    3291       29286 :         struct nl80211_global *global = arg;
    3292       29286 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    3293             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    3294             :         struct wpa_driver_nl80211_data *drv, *tmp;
    3295       29286 :         int ifidx = -1;
    3296             :         struct i802_bss *bss;
    3297       29286 :         u64 wdev_id = 0;
    3298       29286 :         int wdev_id_set = 0;
    3299             : 
    3300       29286 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    3301             :                   genlmsg_attrlen(gnlh, 0), NULL);
    3302             : 
    3303       29286 :         if (tb[NL80211_ATTR_IFINDEX])
    3304       27892 :                 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
    3305        1394 :         else if (tb[NL80211_ATTR_WDEV]) {
    3306           0 :                 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
    3307           0 :                 wdev_id_set = 1;
    3308             :         }
    3309             : 
    3310       45963 :         dl_list_for_each_safe(drv, tmp, &global->interfaces,
    3311             :                               struct wpa_driver_nl80211_data, list) {
    3312       41188 :                 for (bss = drv->first_bss; bss; bss = bss->next) {
    3313       48220 :                         if ((ifidx == -1 && !wdev_id_set) ||
    3314       41215 :                             ifidx == bss->ifindex ||
    3315           0 :                             (wdev_id_set && bss->wdev_id_set &&
    3316           0 :                              wdev_id == bss->wdev_id)) {
    3317        7005 :                                 do_process_drv_event(bss, gnlh->cmd, tb);
    3318        7005 :                                 return NL_SKIP;
    3319             :                         }
    3320             :                 }
    3321             :         }
    3322             : 
    3323       22281 :         return NL_SKIP;
    3324             : }
    3325             : 
    3326             : 
    3327        5569 : static int process_bss_event(struct nl_msg *msg, void *arg)
    3328             : {
    3329        5569 :         struct i802_bss *bss = arg;
    3330        5569 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    3331             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    3332             : 
    3333        5569 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    3334             :                   genlmsg_attrlen(gnlh, 0), NULL);
    3335             : 
    3336       11138 :         wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
    3337       11138 :                    gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
    3338        5569 :                    bss->ifname);
    3339             : 
    3340        5569 :         switch (gnlh->cmd) {
    3341             :         case NL80211_CMD_FRAME:
    3342             :         case NL80211_CMD_FRAME_TX_STATUS:
    3343        5562 :                 mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
    3344             :                            tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
    3345             :                            tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
    3346             :                            tb[NL80211_ATTR_COOKIE],
    3347             :                            tb[NL80211_ATTR_RX_SIGNAL_DBM]);
    3348        5562 :                 break;
    3349             :         case NL80211_CMD_UNEXPECTED_FRAME:
    3350           6 :                 nl80211_spurious_frame(bss, tb, 0);
    3351           6 :                 break;
    3352             :         case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
    3353           1 :                 nl80211_spurious_frame(bss, tb, 1);
    3354           1 :                 break;
    3355             :         default:
    3356           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
    3357           0 :                            "(cmd=%d)", gnlh->cmd);
    3358           0 :                 break;
    3359             :         }
    3360             : 
    3361        5569 :         return NL_SKIP;
    3362             : }
    3363             : 
    3364             : 
    3365       34823 : static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
    3366             :                                              void *handle)
    3367             : {
    3368       34823 :         struct nl_cb *cb = eloop_ctx;
    3369             :         int res;
    3370             : 
    3371       34823 :         wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
    3372             : 
    3373       34823 :         res = nl_recvmsgs(handle, cb);
    3374       34823 :         if (res < 0) {
    3375           0 :                 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
    3376             :                            __func__, res);
    3377             :         }
    3378       34823 : }
    3379             : 
    3380             : 
    3381             : /**
    3382             :  * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
    3383             :  * @priv: driver_nl80211 private data
    3384             :  * @alpha2_arg: country to which to switch to
    3385             :  * Returns: 0 on success, -1 on failure
    3386             :  *
    3387             :  * This asks nl80211 to set the regulatory domain for given
    3388             :  * country ISO / IEC alpha2.
    3389             :  */
    3390          24 : static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
    3391             : {
    3392          24 :         struct i802_bss *bss = priv;
    3393          24 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3394             :         char alpha2[3];
    3395             :         struct nl_msg *msg;
    3396             : 
    3397          24 :         msg = nlmsg_alloc();
    3398          24 :         if (!msg)
    3399           0 :                 return -ENOMEM;
    3400             : 
    3401          24 :         alpha2[0] = alpha2_arg[0];
    3402          24 :         alpha2[1] = alpha2_arg[1];
    3403          24 :         alpha2[2] = '\0';
    3404             : 
    3405          24 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG);
    3406             : 
    3407          24 :         NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
    3408          24 :         if (send_and_recv_msgs(drv, msg, NULL, NULL))
    3409           0 :                 return -EINVAL;
    3410          24 :         return 0;
    3411             : nla_put_failure:
    3412           0 :         nlmsg_free(msg);
    3413           0 :         return -EINVAL;
    3414             : }
    3415             : 
    3416             : 
    3417          24 : static int nl80211_get_country(struct nl_msg *msg, void *arg)
    3418             : {
    3419          24 :         char *alpha2 = arg;
    3420             :         struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
    3421          24 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    3422             : 
    3423          24 :         nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    3424             :                   genlmsg_attrlen(gnlh, 0), NULL);
    3425          24 :         if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
    3426           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No country information available");
    3427           0 :                 return NL_SKIP;
    3428             :         }
    3429          24 :         os_strlcpy(alpha2, nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]), 3);
    3430          24 :         return NL_SKIP;
    3431             : }
    3432             : 
    3433             : 
    3434          24 : static int wpa_driver_nl80211_get_country(void *priv, char *alpha2)
    3435             : {
    3436          24 :         struct i802_bss *bss = priv;
    3437          24 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    3438             :         struct nl_msg *msg;
    3439             :         int ret;
    3440             : 
    3441          24 :         msg = nlmsg_alloc();
    3442          24 :         if (!msg)
    3443           0 :                 return -ENOMEM;
    3444             : 
    3445          24 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
    3446          24 :         alpha2[0] = '\0';
    3447          24 :         ret = send_and_recv_msgs(drv, msg, nl80211_get_country, alpha2);
    3448          24 :         if (!alpha2[0])
    3449           0 :                 ret = -1;
    3450             : 
    3451          24 :         return ret;
    3452             : }
    3453             : 
    3454             : 
    3455        1262 : static int protocol_feature_handler(struct nl_msg *msg, void *arg)
    3456             : {
    3457        1262 :         u32 *feat = arg;
    3458             :         struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
    3459        1262 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    3460             : 
    3461        1262 :         nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    3462             :                   genlmsg_attrlen(gnlh, 0), NULL);
    3463             : 
    3464        1262 :         if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES])
    3465        1262 :                 *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]);
    3466             : 
    3467        1262 :         return NL_SKIP;
    3468             : }
    3469             : 
    3470             : 
    3471        1262 : static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
    3472             : {
    3473        1262 :         u32 feat = 0;
    3474             :         struct nl_msg *msg;
    3475             : 
    3476        1262 :         msg = nlmsg_alloc();
    3477        1262 :         if (!msg)
    3478           0 :                 goto nla_put_failure;
    3479             : 
    3480        1262 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES);
    3481        1262 :         if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat) == 0)
    3482        1262 :                 return feat;
    3483             : 
    3484           0 :         msg = NULL;
    3485             : nla_put_failure:
    3486           0 :         nlmsg_free(msg);
    3487           0 :         return 0;
    3488             : }
    3489             : 
    3490             : 
    3491             : struct wiphy_info_data {
    3492             :         struct wpa_driver_nl80211_data *drv;
    3493             :         struct wpa_driver_capa *capa;
    3494             : 
    3495             :         unsigned int num_multichan_concurrent;
    3496             : 
    3497             :         unsigned int error:1;
    3498             :         unsigned int device_ap_sme:1;
    3499             :         unsigned int poll_command_supported:1;
    3500             :         unsigned int data_tx_status:1;
    3501             :         unsigned int monitor_supported:1;
    3502             :         unsigned int auth_supported:1;
    3503             :         unsigned int connect_supported:1;
    3504             :         unsigned int p2p_go_supported:1;
    3505             :         unsigned int p2p_client_supported:1;
    3506             :         unsigned int p2p_concurrent:1;
    3507             :         unsigned int channel_switch_supported:1;
    3508             :         unsigned int set_qos_map_supported:1;
    3509             :         unsigned int have_low_prio_scan:1;
    3510             : };
    3511             : 
    3512             : 
    3513           0 : static unsigned int probe_resp_offload_support(int supp_protocols)
    3514             : {
    3515           0 :         unsigned int prot = 0;
    3516             : 
    3517           0 :         if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
    3518           0 :                 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
    3519           0 :         if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
    3520           0 :                 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
    3521           0 :         if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
    3522           0 :                 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
    3523           0 :         if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
    3524           0 :                 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
    3525             : 
    3526           0 :         return prot;
    3527             : }
    3528             : 
    3529             : 
    3530       34074 : static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
    3531             :                                          struct nlattr *tb)
    3532             : {
    3533             :         struct nlattr *nl_mode;
    3534             :         int i;
    3535             : 
    3536       34074 :         if (tb == NULL)
    3537       67517 :                 return;
    3538             : 
    3539        6310 :         nla_for_each_nested(nl_mode, tb, i) {
    3540        5679 :                 switch (nla_type(nl_mode)) {
    3541             :                 case NL80211_IFTYPE_AP:
    3542         631 :                         info->capa->flags |= WPA_DRIVER_FLAGS_AP;
    3543         631 :                         break;
    3544             :                 case NL80211_IFTYPE_ADHOC:
    3545         631 :                         info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
    3546         631 :                         break;
    3547             :                 case NL80211_IFTYPE_P2P_DEVICE:
    3548         631 :                         info->capa->flags |=
    3549             :                                 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
    3550         631 :                         break;
    3551             :                 case NL80211_IFTYPE_P2P_GO:
    3552         631 :                         info->p2p_go_supported = 1;
    3553         631 :                         break;
    3554             :                 case NL80211_IFTYPE_P2P_CLIENT:
    3555         631 :                         info->p2p_client_supported = 1;
    3556         631 :                         break;
    3557             :                 case NL80211_IFTYPE_MONITOR:
    3558         631 :                         info->monitor_supported = 1;
    3559         631 :                         break;
    3560             :                 }
    3561             :         }
    3562             : }
    3563             : 
    3564             : 
    3565        1262 : static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
    3566             :                                          struct nlattr *nl_combi)
    3567             : {
    3568             :         struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
    3569             :         struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
    3570             :         struct nlattr *nl_limit, *nl_mode;
    3571             :         int err, rem_limit, rem_mode;
    3572        1262 :         int combination_has_p2p = 0, combination_has_mgd = 0;
    3573             :         static struct nla_policy
    3574             :         iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
    3575             :                 [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
    3576             :                 [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
    3577             :                 [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
    3578             :                 [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
    3579             :                 [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
    3580             :         },
    3581             :         iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
    3582             :                 [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
    3583             :                 [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
    3584             :         };
    3585             : 
    3586        1262 :         err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
    3587             :                                nl_combi, iface_combination_policy);
    3588        2524 :         if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
    3589        2524 :             !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
    3590        1262 :             !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
    3591           0 :                 return 0; /* broken combination */
    3592             : 
    3593        1262 :         if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
    3594        1262 :                 info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
    3595             : 
    3596        2524 :         nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
    3597             :                             rem_limit) {
    3598        1893 :                 err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
    3599             :                                        nl_limit, iface_limit_policy);
    3600        1893 :                 if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
    3601           0 :                         return 0; /* broken combination */
    3602             : 
    3603        6310 :                 nla_for_each_nested(nl_mode,
    3604             :                                     tb_limit[NL80211_IFACE_LIMIT_TYPES],
    3605             :                                     rem_mode) {
    3606        4417 :                         int ift = nla_type(nl_mode);
    3607        4417 :                         if (ift == NL80211_IFTYPE_P2P_GO ||
    3608             :                             ift == NL80211_IFTYPE_P2P_CLIENT)
    3609        1262 :                                 combination_has_p2p = 1;
    3610        4417 :                         if (ift == NL80211_IFTYPE_STATION)
    3611         631 :                                 combination_has_mgd = 1;
    3612             :                 }
    3613        1893 :                 if (combination_has_p2p && combination_has_mgd)
    3614         631 :                         break;
    3615             :         }
    3616             : 
    3617        1262 :         if (combination_has_p2p && combination_has_mgd) {
    3618         631 :                 unsigned int num_channels =
    3619         631 :                         nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
    3620             : 
    3621         631 :                 info->p2p_concurrent = 1;
    3622         631 :                 if (info->num_multichan_concurrent < num_channels)
    3623         631 :                         info->num_multichan_concurrent = num_channels;
    3624             :         }
    3625             : 
    3626        1262 :         return 0;
    3627             : }
    3628             : 
    3629             : 
    3630       34074 : static void wiphy_info_iface_comb(struct wiphy_info_data *info,
    3631             :                                   struct nlattr *tb)
    3632             : {
    3633             :         struct nlattr *nl_combi;
    3634             :         int rem_combi;
    3635             : 
    3636       34074 :         if (tb == NULL)
    3637       67517 :                 return;
    3638             : 
    3639        1893 :         nla_for_each_nested(nl_combi, tb, rem_combi) {
    3640        1262 :                 if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
    3641           0 :                         break;
    3642             :         }
    3643             : }
    3644             : 
    3645             : 
    3646       34074 : static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
    3647             :                                  struct nlattr *tb)
    3648             : {
    3649             :         struct nlattr *nl_cmd;
    3650             :         int i;
    3651             : 
    3652       34074 :         if (tb == NULL)
    3653       67517 :                 return;
    3654             : 
    3655       20823 :         nla_for_each_nested(nl_cmd, tb, i) {
    3656       20192 :                 switch (nla_get_u32(nl_cmd)) {
    3657             :                 case NL80211_CMD_AUTHENTICATE:
    3658         631 :                         info->auth_supported = 1;
    3659         631 :                         break;
    3660             :                 case NL80211_CMD_CONNECT:
    3661         631 :                         info->connect_supported = 1;
    3662         631 :                         break;
    3663             :                 case NL80211_CMD_START_SCHED_SCAN:
    3664           0 :                         info->capa->sched_scan_supported = 1;
    3665           0 :                         break;
    3666             :                 case NL80211_CMD_PROBE_CLIENT:
    3667         631 :                         info->poll_command_supported = 1;
    3668         631 :                         break;
    3669             :                 case NL80211_CMD_CHANNEL_SWITCH:
    3670         631 :                         info->channel_switch_supported = 1;
    3671         631 :                         break;
    3672             :                 case NL80211_CMD_SET_QOS_MAP:
    3673         631 :                         info->set_qos_map_supported = 1;
    3674         631 :                         break;
    3675             :                 }
    3676             :         }
    3677             : }
    3678             : 
    3679             : 
    3680       34074 : static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
    3681             :                                      struct nlattr *tb)
    3682             : {
    3683             :         int i, num;
    3684             :         u32 *ciphers;
    3685             : 
    3686       34074 :         if (tb == NULL)
    3687       67517 :                 return;
    3688             : 
    3689         631 :         num = nla_len(tb) / sizeof(u32);
    3690         631 :         ciphers = nla_data(tb);
    3691        3786 :         for (i = 0; i < num; i++) {
    3692        3155 :                 u32 c = ciphers[i];
    3693             : 
    3694        9465 :                 wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
    3695        3155 :                            c >> 24, (c >> 16) & 0xff,
    3696        3155 :                            (c >> 8) & 0xff, c & 0xff);
    3697        3155 :                 switch (c) {
    3698             :                 case WLAN_CIPHER_SUITE_CCMP_256:
    3699           0 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
    3700           0 :                         break;
    3701             :                 case WLAN_CIPHER_SUITE_GCMP_256:
    3702           0 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
    3703           0 :                         break;
    3704             :                 case WLAN_CIPHER_SUITE_CCMP:
    3705         631 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
    3706         631 :                         break;
    3707             :                 case WLAN_CIPHER_SUITE_GCMP:
    3708           0 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
    3709           0 :                         break;
    3710             :                 case WLAN_CIPHER_SUITE_TKIP:
    3711         631 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
    3712         631 :                         break;
    3713             :                 case WLAN_CIPHER_SUITE_WEP104:
    3714         631 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
    3715         631 :                         break;
    3716             :                 case WLAN_CIPHER_SUITE_WEP40:
    3717         631 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
    3718         631 :                         break;
    3719             :                 case WLAN_CIPHER_SUITE_AES_CMAC:
    3720         631 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
    3721         631 :                         break;
    3722             :                 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
    3723           0 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
    3724           0 :                         break;
    3725             :                 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
    3726           0 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
    3727           0 :                         break;
    3728             :                 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
    3729           0 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
    3730           0 :                         break;
    3731             :                 case WLAN_CIPHER_SUITE_NO_GROUP_ADDR:
    3732           0 :                         info->capa->enc |= WPA_DRIVER_CAPA_ENC_GTK_NOT_USED;
    3733           0 :                         break;
    3734             :                 }
    3735             :         }
    3736             : }
    3737             : 
    3738             : 
    3739       34074 : static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
    3740             :                                struct nlattr *tb)
    3741             : {
    3742       34074 :         if (tb)
    3743         631 :                 capa->max_remain_on_chan = nla_get_u32(tb);
    3744       34074 : }
    3745             : 
    3746             : 
    3747       34074 : static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
    3748             :                             struct nlattr *ext_setup)
    3749             : {
    3750       34074 :         if (tdls == NULL)
    3751       67517 :                 return;
    3752             : 
    3753         631 :         wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
    3754         631 :         capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
    3755             : 
    3756         631 :         if (ext_setup) {
    3757         631 :                 wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
    3758         631 :                 capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
    3759             :         }
    3760             : }
    3761             : 
    3762             : 
    3763       34074 : static void wiphy_info_feature_flags(struct wiphy_info_data *info,
    3764             :                                      struct nlattr *tb)
    3765             : {
    3766             :         u32 flags;
    3767       34074 :         struct wpa_driver_capa *capa = info->capa;
    3768             : 
    3769       34074 :         if (tb == NULL)
    3770       67517 :                 return;
    3771             : 
    3772         631 :         flags = nla_get_u32(tb);
    3773             : 
    3774         631 :         if (flags & NL80211_FEATURE_SK_TX_STATUS)
    3775         631 :                 info->data_tx_status = 1;
    3776             : 
    3777         631 :         if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
    3778           0 :                 capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
    3779             : 
    3780         631 :         if (flags & NL80211_FEATURE_SAE)
    3781         631 :                 capa->flags |= WPA_DRIVER_FLAGS_SAE;
    3782             : 
    3783         631 :         if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
    3784           0 :                 capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
    3785             : 
    3786         631 :         if (flags & NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)
    3787         631 :                 capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
    3788             : 
    3789         631 :         if (flags & NL80211_FEATURE_LOW_PRIORITY_SCAN)
    3790         631 :                 info->have_low_prio_scan = 1;
    3791             : }
    3792             : 
    3793             : 
    3794       34074 : static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
    3795             :                                           struct nlattr *tb)
    3796             : {
    3797             :         u32 protocols;
    3798             : 
    3799       34074 :         if (tb == NULL)
    3800       68148 :                 return;
    3801             : 
    3802           0 :         protocols = nla_get_u32(tb);
    3803           0 :         wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
    3804             :                    "mode");
    3805           0 :         capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
    3806           0 :         capa->probe_resp_offloads = probe_resp_offload_support(protocols);
    3807             : }
    3808             : 
    3809             : 
    3810       34074 : static void wiphy_info_wowlan_triggers(struct wpa_driver_capa *capa,
    3811             :                                        struct nlattr *tb)
    3812             : {
    3813             :         struct nlattr *triggers[MAX_NL80211_WOWLAN_TRIG + 1];
    3814             : 
    3815       34074 :         if (tb == NULL)
    3816       68148 :                 return;
    3817             : 
    3818           0 :         if (nla_parse_nested(triggers, MAX_NL80211_WOWLAN_TRIG,
    3819             :                              tb, NULL))
    3820           0 :                 return;
    3821             : 
    3822           0 :         if (triggers[NL80211_WOWLAN_TRIG_ANY])
    3823           0 :                 capa->wowlan_triggers.any = 1;
    3824           0 :         if (triggers[NL80211_WOWLAN_TRIG_DISCONNECT])
    3825           0 :                 capa->wowlan_triggers.disconnect = 1;
    3826           0 :         if (triggers[NL80211_WOWLAN_TRIG_MAGIC_PKT])
    3827           0 :                 capa->wowlan_triggers.magic_pkt = 1;
    3828           0 :         if (triggers[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
    3829           0 :                 capa->wowlan_triggers.gtk_rekey_failure = 1;
    3830           0 :         if (triggers[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
    3831           0 :                 capa->wowlan_triggers.eap_identity_req = 1;
    3832           0 :         if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
    3833           0 :                 capa->wowlan_triggers.four_way_handshake = 1;
    3834           0 :         if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
    3835           0 :                 capa->wowlan_triggers.rfkill_release = 1;
    3836             : }
    3837             : 
    3838             : 
    3839       34074 : static int wiphy_info_handler(struct nl_msg *msg, void *arg)
    3840             : {
    3841             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    3842       34074 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    3843       34074 :         struct wiphy_info_data *info = arg;
    3844       34074 :         struct wpa_driver_capa *capa = info->capa;
    3845       34074 :         struct wpa_driver_nl80211_data *drv = info->drv;
    3846             : 
    3847       34074 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    3848             :                   genlmsg_attrlen(gnlh, 0), NULL);
    3849             : 
    3850       34074 :         if (tb[NL80211_ATTR_WIPHY_NAME])
    3851       34074 :                 os_strlcpy(drv->phyname,
    3852       34074 :                            nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
    3853             :                            sizeof(drv->phyname));
    3854       34074 :         if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
    3855         631 :                 capa->max_scan_ssids =
    3856         631 :                         nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
    3857             : 
    3858       34074 :         if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
    3859         631 :                 capa->max_sched_scan_ssids =
    3860         631 :                         nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
    3861             : 
    3862       34074 :         if (tb[NL80211_ATTR_MAX_MATCH_SETS])
    3863         631 :                 capa->max_match_sets =
    3864         631 :                         nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
    3865             : 
    3866       34074 :         if (tb[NL80211_ATTR_MAC_ACL_MAX])
    3867           0 :                 capa->max_acl_mac_addrs =
    3868           0 :                         nla_get_u8(tb[NL80211_ATTR_MAC_ACL_MAX]);
    3869             : 
    3870       34074 :         wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
    3871       34074 :         wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
    3872       34074 :         wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
    3873       34074 :         wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
    3874             : 
    3875       34074 :         if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
    3876         631 :                 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
    3877             :                            "off-channel TX");
    3878         631 :                 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
    3879             :         }
    3880             : 
    3881       34074 :         if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
    3882           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
    3883           0 :                 capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
    3884             :         }
    3885             : 
    3886       34074 :         wiphy_info_max_roc(capa,
    3887             :                            tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
    3888             : 
    3889       34074 :         if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
    3890         631 :                 capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
    3891             : 
    3892       34074 :         wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
    3893             :                         tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
    3894             : 
    3895       34074 :         if (tb[NL80211_ATTR_DEVICE_AP_SME])
    3896           0 :                 info->device_ap_sme = 1;
    3897             : 
    3898       34074 :         wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
    3899       34074 :         wiphy_info_probe_resp_offload(capa,
    3900             :                                       tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
    3901             : 
    3902       34705 :         if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
    3903         631 :             drv->extended_capa == NULL) {
    3904         631 :                 drv->extended_capa =
    3905         631 :                         os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
    3906         631 :                 if (drv->extended_capa) {
    3907         631 :                         os_memcpy(drv->extended_capa,
    3908             :                                   nla_data(tb[NL80211_ATTR_EXT_CAPA]),
    3909             :                                   nla_len(tb[NL80211_ATTR_EXT_CAPA]));
    3910         631 :                         drv->extended_capa_len =
    3911         631 :                                 nla_len(tb[NL80211_ATTR_EXT_CAPA]);
    3912             :                 }
    3913         631 :                 drv->extended_capa_mask =
    3914         631 :                         os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
    3915         631 :                 if (drv->extended_capa_mask) {
    3916         631 :                         os_memcpy(drv->extended_capa_mask,
    3917             :                                   nla_data(tb[NL80211_ATTR_EXT_CAPA]),
    3918             :                                   nla_len(tb[NL80211_ATTR_EXT_CAPA]));
    3919             :                 } else {
    3920           0 :                         os_free(drv->extended_capa);
    3921           0 :                         drv->extended_capa = NULL;
    3922           0 :                         drv->extended_capa_len = 0;
    3923             :                 }
    3924             :         }
    3925             : 
    3926       34074 :         if (tb[NL80211_ATTR_VENDOR_DATA]) {
    3927             :                 struct nlattr *nl;
    3928             :                 int rem;
    3929             : 
    3930           0 :                 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
    3931             :                         struct nl80211_vendor_cmd_info *vinfo;
    3932           0 :                         if (nla_len(nl) != sizeof(*vinfo)) {
    3933           0 :                                 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
    3934           0 :                                 continue;
    3935             :                         }
    3936           0 :                         vinfo = nla_data(nl);
    3937           0 :                         switch (vinfo->subcmd) {
    3938             :                         case QCA_NL80211_VENDOR_SUBCMD_ROAMING:
    3939           0 :                                 drv->roaming_vendor_cmd_avail = 1;
    3940           0 :                                 break;
    3941             :                         case QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY:
    3942           0 :                                 drv->dfs_vendor_cmd_avail = 1;
    3943           0 :                                 break;
    3944             :                         }
    3945             : 
    3946           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
    3947             :                                    vinfo->vendor_id, vinfo->subcmd);
    3948             :                 }
    3949             :         }
    3950             : 
    3951       34074 :         if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
    3952             :                 struct nlattr *nl;
    3953             :                 int rem;
    3954             : 
    3955           0 :                 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
    3956             :                         struct nl80211_vendor_cmd_info *vinfo;
    3957           0 :                         if (nla_len(nl) != sizeof(*vinfo)) {
    3958           0 :                                 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
    3959           0 :                                 continue;
    3960             :                         }
    3961           0 :                         vinfo = nla_data(nl);
    3962           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
    3963             :                                    vinfo->vendor_id, vinfo->subcmd);
    3964             :                 }
    3965             :         }
    3966             : 
    3967       34074 :         wiphy_info_wowlan_triggers(capa,
    3968             :                                    tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]);
    3969             : 
    3970       34074 :         if (tb[NL80211_ATTR_MAX_AP_ASSOC_STA])
    3971           0 :                 capa->max_stations =
    3972           0 :                         nla_get_u32(tb[NL80211_ATTR_MAX_AP_ASSOC_STA]);
    3973             : 
    3974       34074 :         return NL_SKIP;
    3975             : }
    3976             : 
    3977             : 
    3978         631 : static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
    3979             :                                        struct wiphy_info_data *info)
    3980             : {
    3981             :         u32 feat;
    3982             :         struct nl_msg *msg;
    3983             : 
    3984         631 :         os_memset(info, 0, sizeof(*info));
    3985         631 :         info->capa = &drv->capa;
    3986         631 :         info->drv = drv;
    3987             : 
    3988         631 :         msg = nlmsg_alloc();
    3989         631 :         if (!msg)
    3990           0 :                 return -1;
    3991             : 
    3992         631 :         feat = get_nl80211_protocol_features(drv);
    3993         631 :         if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
    3994         631 :                 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_WIPHY);
    3995             :         else
    3996           0 :                 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
    3997             : 
    3998         631 :         NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
    3999         631 :         if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
    4000           0 :                 goto nla_put_failure;
    4001             : 
    4002         631 :         if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info))
    4003           0 :                 return -1;
    4004             : 
    4005         631 :         if (info->auth_supported)
    4006         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
    4007           0 :         else if (!info->connect_supported) {
    4008           0 :                 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
    4009             :                            "authentication/association or connect commands");
    4010           0 :                 info->error = 1;
    4011             :         }
    4012             : 
    4013         631 :         if (info->p2p_go_supported && info->p2p_client_supported)
    4014         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
    4015         631 :         if (info->p2p_concurrent) {
    4016         631 :                 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
    4017             :                            "interface (driver advertised support)");
    4018         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
    4019         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
    4020             :         }
    4021         631 :         if (info->num_multichan_concurrent > 1) {
    4022           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Enable multi-channel "
    4023             :                            "concurrent (driver advertised support)");
    4024           0 :                 drv->capa.num_multichan_concurrent =
    4025           0 :                         info->num_multichan_concurrent;
    4026             :         }
    4027             : 
    4028             :         /* default to 5000 since early versions of mac80211 don't set it */
    4029         631 :         if (!drv->capa.max_remain_on_chan)
    4030           0 :                 drv->capa.max_remain_on_chan = 5000;
    4031             : 
    4032         631 :         if (info->channel_switch_supported)
    4033         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
    4034             : 
    4035         631 :         return 0;
    4036             : nla_put_failure:
    4037           0 :         nlmsg_free(msg);
    4038           0 :         return -1;
    4039             : }
    4040             : 
    4041             : 
    4042         631 : static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
    4043             : {
    4044             :         struct wiphy_info_data info;
    4045         631 :         if (wpa_driver_nl80211_get_info(drv, &info))
    4046           0 :                 return -1;
    4047             : 
    4048         631 :         if (info.error)
    4049           0 :                 return -1;
    4050             : 
    4051         631 :         drv->has_capability = 1;
    4052         631 :         drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
    4053             :                 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
    4054             :                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
    4055             :                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
    4056         631 :         drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
    4057             :                 WPA_DRIVER_AUTH_SHARED |
    4058             :                 WPA_DRIVER_AUTH_LEAP;
    4059             : 
    4060         631 :         drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
    4061         631 :         drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
    4062         631 :         drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
    4063             : 
    4064             :         /*
    4065             :          * As all cfg80211 drivers must support cases where the AP interface is
    4066             :          * removed without the knowledge of wpa_supplicant/hostapd, e.g., in
    4067             :          * case that the user space daemon has crashed, they must be able to
    4068             :          * cleanup all stations and key entries in the AP tear down flow. Thus,
    4069             :          * this flag can/should always be set for cfg80211 drivers.
    4070             :          */
    4071         631 :         drv->capa.flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
    4072             : 
    4073         631 :         if (!info.device_ap_sme) {
    4074         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
    4075             : 
    4076             :                 /*
    4077             :                  * No AP SME is currently assumed to also indicate no AP MLME
    4078             :                  * in the driver/firmware.
    4079             :                  */
    4080         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_MLME;
    4081             :         }
    4082             : 
    4083         631 :         drv->device_ap_sme = info.device_ap_sme;
    4084         631 :         drv->poll_command_supported = info.poll_command_supported;
    4085         631 :         drv->data_tx_status = info.data_tx_status;
    4086         631 :         if (info.set_qos_map_supported)
    4087         631 :                 drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
    4088         631 :         drv->have_low_prio_scan = info.have_low_prio_scan;
    4089             : 
    4090             :         /*
    4091             :          * If poll command and tx status are supported, mac80211 is new enough
    4092             :          * to have everything we need to not need monitor interfaces.
    4093             :          */
    4094         631 :         drv->use_monitor = !info.poll_command_supported || !info.data_tx_status;
    4095             : 
    4096         631 :         if (drv->device_ap_sme && drv->use_monitor) {
    4097             :                 /*
    4098             :                  * Non-mac80211 drivers may not support monitor interface.
    4099             :                  * Make sure we do not get stuck with incorrect capability here
    4100             :                  * by explicitly testing this.
    4101             :                  */
    4102           0 :                 if (!info.monitor_supported) {
    4103           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Disable use_monitor "
    4104             :                                    "with device_ap_sme since no monitor mode "
    4105             :                                    "support detected");
    4106           0 :                         drv->use_monitor = 0;
    4107             :                 }
    4108             :         }
    4109             : 
    4110             :         /*
    4111             :          * If we aren't going to use monitor interfaces, but the
    4112             :          * driver doesn't support data TX status, we won't get TX
    4113             :          * status for EAPOL frames.
    4114             :          */
    4115         631 :         if (!drv->use_monitor && !info.data_tx_status)
    4116           0 :                 drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
    4117             : 
    4118         631 :         return 0;
    4119             : }
    4120             : 
    4121             : 
    4122             : #ifdef ANDROID
    4123             : static int android_genl_ctrl_resolve(struct nl_handle *handle,
    4124             :                                      const char *name)
    4125             : {
    4126             :         /*
    4127             :          * Android ICS has very minimal genl_ctrl_resolve() implementation, so
    4128             :          * need to work around that.
    4129             :          */
    4130             :         struct nl_cache *cache = NULL;
    4131             :         struct genl_family *nl80211 = NULL;
    4132             :         int id = -1;
    4133             : 
    4134             :         if (genl_ctrl_alloc_cache(handle, &cache) < 0) {
    4135             :                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
    4136             :                            "netlink cache");
    4137             :                 goto fail;
    4138             :         }
    4139             : 
    4140             :         nl80211 = genl_ctrl_search_by_name(cache, name);
    4141             :         if (nl80211 == NULL)
    4142             :                 goto fail;
    4143             : 
    4144             :         id = genl_family_get_id(nl80211);
    4145             : 
    4146             : fail:
    4147             :         if (nl80211)
    4148             :                 genl_family_put(nl80211);
    4149             :         if (cache)
    4150             :                 nl_cache_free(cache);
    4151             : 
    4152             :         return id;
    4153             : }
    4154             : #define genl_ctrl_resolve android_genl_ctrl_resolve
    4155             : #endif /* ANDROID */
    4156             : 
    4157             : 
    4158           1 : static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
    4159             : {
    4160             :         int ret;
    4161             : 
    4162           1 :         global->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
    4163           1 :         if (global->nl_cb == NULL) {
    4164           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
    4165             :                            "callbacks");
    4166           0 :                 return -1;
    4167             :         }
    4168             : 
    4169           1 :         global->nl = nl_create_handle(global->nl_cb, "nl");
    4170           1 :         if (global->nl == NULL)
    4171           0 :                 goto err;
    4172             : 
    4173           1 :         global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211");
    4174           1 :         if (global->nl80211_id < 0) {
    4175           0 :                 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
    4176             :                            "found");
    4177           0 :                 goto err;
    4178             :         }
    4179             : 
    4180           1 :         global->nl_event = nl_create_handle(global->nl_cb, "event");
    4181           1 :         if (global->nl_event == NULL)
    4182           0 :                 goto err;
    4183             : 
    4184           1 :         ret = nl_get_multicast_id(global, "nl80211", "scan");
    4185           1 :         if (ret >= 0)
    4186           1 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    4187           1 :         if (ret < 0) {
    4188           0 :                 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
    4189             :                            "membership for scan events: %d (%s)",
    4190             :                            ret, strerror(-ret));
    4191           0 :                 goto err;
    4192             :         }
    4193             : 
    4194           1 :         ret = nl_get_multicast_id(global, "nl80211", "mlme");
    4195           1 :         if (ret >= 0)
    4196           1 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    4197           1 :         if (ret < 0) {
    4198           0 :                 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
    4199             :                            "membership for mlme events: %d (%s)",
    4200             :                            ret, strerror(-ret));
    4201           0 :                 goto err;
    4202             :         }
    4203             : 
    4204           1 :         ret = nl_get_multicast_id(global, "nl80211", "regulatory");
    4205           1 :         if (ret >= 0)
    4206           1 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    4207           1 :         if (ret < 0) {
    4208           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
    4209             :                            "membership for regulatory events: %d (%s)",
    4210             :                            ret, strerror(-ret));
    4211             :                 /* Continue without regulatory events */
    4212             :         }
    4213             : 
    4214           1 :         ret = nl_get_multicast_id(global, "nl80211", "vendor");
    4215           1 :         if (ret >= 0)
    4216           1 :                 ret = nl_socket_add_membership(global->nl_event, ret);
    4217           1 :         if (ret < 0) {
    4218           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
    4219             :                            "membership for vendor events: %d (%s)",
    4220             :                            ret, strerror(-ret));
    4221             :                 /* Continue without vendor events */
    4222             :         }
    4223             : 
    4224           1 :         nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
    4225             :                   no_seq_check, NULL);
    4226           1 :         nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
    4227             :                   process_global_event, global);
    4228             : 
    4229           1 :         nl80211_register_eloop_read(&global->nl_event,
    4230             :                                     wpa_driver_nl80211_event_receive,
    4231           1 :                                     global->nl_cb);
    4232             : 
    4233           1 :         return 0;
    4234             : 
    4235             : err:
    4236           0 :         nl_destroy_handles(&global->nl_event);
    4237           0 :         nl_destroy_handles(&global->nl);
    4238           0 :         nl_cb_put(global->nl_cb);
    4239           0 :         global->nl_cb = NULL;
    4240           0 :         return -1;
    4241             : }
    4242             : 
    4243             : 
    4244         631 : static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv)
    4245             : {
    4246         631 :         drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
    4247         631 :         if (!drv->nl_cb) {
    4248           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to alloc cb struct");
    4249           0 :                 return -1;
    4250             :         }
    4251             : 
    4252         631 :         nl_cb_set(drv->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
    4253             :                   no_seq_check, NULL);
    4254         631 :         nl_cb_set(drv->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
    4255             :                   process_drv_event, drv);
    4256             : 
    4257         631 :         return 0;
    4258             : }
    4259             : 
    4260             : 
    4261           2 : static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
    4262             : {
    4263           2 :         wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
    4264             :         /*
    4265             :          * This may be for any interface; use ifdown event to disable
    4266             :          * interface.
    4267             :          */
    4268           2 : }
    4269             : 
    4270             : 
    4271           2 : static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
    4272             : {
    4273           2 :         struct wpa_driver_nl80211_data *drv = ctx;
    4274           2 :         wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
    4275           2 :         if (i802_set_iface_flags(drv->first_bss, 1)) {
    4276           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
    4277             :                            "after rfkill unblock");
    4278           0 :                 return;
    4279             :         }
    4280             :         /* rtnetlink ifup handler will report interface as enabled */
    4281             : }
    4282             : 
    4283             : 
    4284        4775 : static void wpa_driver_nl80211_handle_eapol_tx_status(int sock,
    4285             :                                                       void *eloop_ctx,
    4286             :                                                       void *handle)
    4287             : {
    4288        4775 :         struct wpa_driver_nl80211_data *drv = eloop_ctx;
    4289             :         u8 data[2048];
    4290             :         struct msghdr msg;
    4291             :         struct iovec entry;
    4292             :         u8 control[512];
    4293             :         struct cmsghdr *cmsg;
    4294        4775 :         int res, found_ee = 0, found_wifi = 0, acked = 0;
    4295             :         union wpa_event_data event;
    4296             : 
    4297        4775 :         memset(&msg, 0, sizeof(msg));
    4298        4775 :         msg.msg_iov = &entry;
    4299        4775 :         msg.msg_iovlen = 1;
    4300        4775 :         entry.iov_base = data;
    4301        4775 :         entry.iov_len = sizeof(data);
    4302        4775 :         msg.msg_control = &control;
    4303        4775 :         msg.msg_controllen = sizeof(control);
    4304             : 
    4305        4775 :         res = recvmsg(sock, &msg, MSG_ERRQUEUE);
    4306             :         /* if error or not fitting 802.3 header, return */
    4307        4775 :         if (res < 14)
    4308           0 :                 return;
    4309             : 
    4310       14325 :         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
    4311             :         {
    4312       14325 :                 if (cmsg->cmsg_level == SOL_SOCKET &&
    4313        4775 :                     cmsg->cmsg_type == SCM_WIFI_STATUS) {
    4314             :                         int *ack;
    4315             : 
    4316        4775 :                         found_wifi = 1;
    4317        4775 :                         ack = (void *)CMSG_DATA(cmsg);
    4318        4775 :                         acked = *ack;
    4319             :                 }
    4320             : 
    4321       14325 :                 if (cmsg->cmsg_level == SOL_PACKET &&
    4322        4775 :                     cmsg->cmsg_type == PACKET_TX_TIMESTAMP) {
    4323        4775 :                         struct sock_extended_err *err =
    4324             :                                 (struct sock_extended_err *)CMSG_DATA(cmsg);
    4325             : 
    4326        4775 :                         if (err->ee_origin == SO_EE_ORIGIN_TXSTATUS)
    4327        4775 :                                 found_ee = 1;
    4328             :                 }
    4329             :         }
    4330             : 
    4331        4775 :         if (!found_ee || !found_wifi)
    4332           0 :                 return;
    4333             : 
    4334        4775 :         memset(&event, 0, sizeof(event));
    4335        4775 :         event.eapol_tx_status.dst = data;
    4336        4775 :         event.eapol_tx_status.data = data + 14;
    4337        4775 :         event.eapol_tx_status.data_len = res - 14;
    4338        4775 :         event.eapol_tx_status.ack = acked;
    4339        4775 :         wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
    4340             : }
    4341             : 
    4342             : 
    4343         650 : static int nl80211_init_bss(struct i802_bss *bss)
    4344             : {
    4345         650 :         bss->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
    4346         650 :         if (!bss->nl_cb)
    4347           0 :                 return -1;
    4348             : 
    4349         650 :         nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
    4350             :                   no_seq_check, NULL);
    4351         650 :         nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
    4352             :                   process_bss_event, bss);
    4353             : 
    4354         650 :         return 0;
    4355             : }
    4356             : 
    4357             : 
    4358         650 : static void nl80211_destroy_bss(struct i802_bss *bss)
    4359             : {
    4360         650 :         nl_cb_put(bss->nl_cb);
    4361         650 :         bss->nl_cb = NULL;
    4362         650 : }
    4363             : 
    4364             : 
    4365         631 : static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
    4366             :                                           void *global_priv, int hostapd,
    4367             :                                           const u8 *set_addr)
    4368             : {
    4369             :         struct wpa_driver_nl80211_data *drv;
    4370             :         struct rfkill_config *rcfg;
    4371             :         struct i802_bss *bss;
    4372             : 
    4373         631 :         if (global_priv == NULL)
    4374           0 :                 return NULL;
    4375         631 :         drv = os_zalloc(sizeof(*drv));
    4376         631 :         if (drv == NULL)
    4377           0 :                 return NULL;
    4378         631 :         drv->global = global_priv;
    4379         631 :         drv->ctx = ctx;
    4380         631 :         drv->hostapd = !!hostapd;
    4381         631 :         drv->eapol_sock = -1;
    4382         631 :         drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
    4383         631 :         drv->if_indices = drv->default_if_indices;
    4384             : 
    4385         631 :         drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
    4386         631 :         if (!drv->first_bss) {
    4387           0 :                 os_free(drv);
    4388           0 :                 return NULL;
    4389             :         }
    4390         631 :         bss = drv->first_bss;
    4391         631 :         bss->drv = drv;
    4392         631 :         bss->ctx = ctx;
    4393             : 
    4394         631 :         os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
    4395         631 :         drv->monitor_ifidx = -1;
    4396         631 :         drv->monitor_sock = -1;
    4397         631 :         drv->eapol_tx_sock = -1;
    4398         631 :         drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
    4399             : 
    4400         631 :         if (wpa_driver_nl80211_init_nl(drv)) {
    4401           0 :                 os_free(drv);
    4402           0 :                 return NULL;
    4403             :         }
    4404             : 
    4405         631 :         if (nl80211_init_bss(bss))
    4406           0 :                 goto failed;
    4407             : 
    4408         631 :         rcfg = os_zalloc(sizeof(*rcfg));
    4409         631 :         if (rcfg == NULL)
    4410           0 :                 goto failed;
    4411         631 :         rcfg->ctx = drv;
    4412         631 :         os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
    4413         631 :         rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
    4414         631 :         rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
    4415         631 :         drv->rfkill = rfkill_init(rcfg);
    4416         631 :         if (drv->rfkill == NULL) {
    4417           0 :                 wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
    4418           0 :                 os_free(rcfg);
    4419             :         }
    4420             : 
    4421         631 :         if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0)
    4422           0 :                 drv->start_iface_up = 1;
    4423             : 
    4424         631 :         if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1))
    4425           0 :                 goto failed;
    4426             : 
    4427         631 :         drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
    4428         631 :         if (drv->eapol_tx_sock < 0)
    4429           0 :                 goto failed;
    4430             : 
    4431         631 :         if (drv->data_tx_status) {
    4432         631 :                 int enabled = 1;
    4433             : 
    4434         631 :                 if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
    4435             :                                &enabled, sizeof(enabled)) < 0) {
    4436           0 :                         wpa_printf(MSG_DEBUG,
    4437             :                                 "nl80211: wifi status sockopt failed\n");
    4438           0 :                         drv->data_tx_status = 0;
    4439           0 :                         if (!drv->use_monitor)
    4440           0 :                                 drv->capa.flags &=
    4441             :                                         ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
    4442             :                 } else {
    4443         631 :                         eloop_register_read_sock(drv->eapol_tx_sock,
    4444             :                                 wpa_driver_nl80211_handle_eapol_tx_status,
    4445             :                                 drv, NULL);
    4446             :                 }
    4447             :         }
    4448             : 
    4449         631 :         if (drv->global) {
    4450         631 :                 dl_list_add(&drv->global->interfaces, &drv->list);
    4451         631 :                 drv->in_interface_list = 1;
    4452             :         }
    4453             : 
    4454         631 :         return bss;
    4455             : 
    4456             : failed:
    4457           0 :         wpa_driver_nl80211_deinit(bss);
    4458           0 :         return NULL;
    4459             : }
    4460             : 
    4461             : 
    4462             : /**
    4463             :  * wpa_driver_nl80211_init - Initialize nl80211 driver interface
    4464             :  * @ctx: context to be used when calling wpa_supplicant functions,
    4465             :  * e.g., wpa_supplicant_event()
    4466             :  * @ifname: interface name, e.g., wlan0
    4467             :  * @global_priv: private driver global data from global_init()
    4468             :  * Returns: Pointer to private data, %NULL on failure
    4469             :  */
    4470           0 : static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
    4471             :                                       void *global_priv)
    4472             : {
    4473           0 :         return wpa_driver_nl80211_drv_init(ctx, ifname, global_priv, 0, NULL);
    4474             : }
    4475             : 
    4476             : 
    4477        4550 : static int nl80211_register_frame(struct i802_bss *bss,
    4478             :                                   struct nl_handle *nl_handle,
    4479             :                                   u16 type, const u8 *match, size_t match_len)
    4480             : {
    4481        4550 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4482             :         struct nl_msg *msg;
    4483        4550 :         int ret = -1;
    4484             :         char buf[30];
    4485             : 
    4486        4550 :         msg = nlmsg_alloc();
    4487        4550 :         if (!msg)
    4488           0 :                 return -1;
    4489             : 
    4490        4550 :         buf[0] = '\0';
    4491        4550 :         wpa_snprintf_hex(buf, sizeof(buf), match, match_len);
    4492        4550 :         wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x (%s) nl_handle=%p match=%s",
    4493             :                    type, fc2str(type), nl_handle, buf);
    4494             : 
    4495        4550 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION);
    4496             : 
    4497        4550 :         if (nl80211_set_iface_id(msg, bss) < 0)
    4498           0 :                 goto nla_put_failure;
    4499             : 
    4500        4550 :         NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type);
    4501        4550 :         NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
    4502             : 
    4503        4550 :         ret = send_and_recv(drv->global, nl_handle, msg, NULL, NULL);
    4504        4550 :         msg = NULL;
    4505        4550 :         if (ret) {
    4506           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
    4507             :                            "failed (type=%u): ret=%d (%s)",
    4508             :                            type, ret, strerror(-ret));
    4509           0 :                 wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
    4510             :                             match, match_len);
    4511           0 :                 goto nla_put_failure;
    4512             :         }
    4513        4550 :         ret = 0;
    4514             : nla_put_failure:
    4515        4550 :         nlmsg_free(msg);
    4516        4550 :         return ret;
    4517             : }
    4518             : 
    4519             : 
    4520         650 : static int nl80211_alloc_mgmt_handle(struct i802_bss *bss)
    4521             : {
    4522         650 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4523             : 
    4524         650 :         if (bss->nl_mgmt) {
    4525           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Mgmt reporting "
    4526             :                            "already on! (nl_mgmt=%p)", bss->nl_mgmt);
    4527           0 :                 return -1;
    4528             :         }
    4529             : 
    4530         650 :         bss->nl_mgmt = nl_create_handle(drv->nl_cb, "mgmt");
    4531         650 :         if (bss->nl_mgmt == NULL)
    4532           0 :                 return -1;
    4533             : 
    4534         650 :         return 0;
    4535             : }
    4536             : 
    4537             : 
    4538         650 : static void nl80211_mgmt_handle_register_eloop(struct i802_bss *bss)
    4539             : {
    4540         650 :         nl80211_register_eloop_read(&bss->nl_mgmt,
    4541             :                                     wpa_driver_nl80211_event_receive,
    4542         650 :                                     bss->nl_cb);
    4543         650 : }
    4544             : 
    4545             : 
    4546           0 : static int nl80211_register_action_frame(struct i802_bss *bss,
    4547             :                                          const u8 *match, size_t match_len)
    4548             : {
    4549           0 :         u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
    4550           0 :         return nl80211_register_frame(bss, bss->nl_mgmt,
    4551             :                                       type, match, match_len);
    4552             : }
    4553             : 
    4554             : 
    4555           0 : static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
    4556             : {
    4557           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4558           0 :         int ret = 0;
    4559             : 
    4560           0 :         if (nl80211_alloc_mgmt_handle(bss))
    4561           0 :                 return -1;
    4562           0 :         wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
    4563             :                    "handle %p", bss->nl_mgmt);
    4564             : 
    4565           0 :         if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
    4566           0 :                 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
    4567             : 
    4568             :                 /* register for any AUTH message */
    4569           0 :                 nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0);
    4570             :         }
    4571             : 
    4572             : #ifdef CONFIG_INTERWORKING
    4573             :         /* QoS Map Configure */
    4574           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
    4575           0 :                 ret = -1;
    4576             : #endif /* CONFIG_INTERWORKING */
    4577             : #if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
    4578             :         /* GAS Initial Request */
    4579           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
    4580           0 :                 ret = -1;
    4581             :         /* GAS Initial Response */
    4582           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
    4583           0 :                 ret = -1;
    4584             :         /* GAS Comeback Request */
    4585           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
    4586           0 :                 ret = -1;
    4587             :         /* GAS Comeback Response */
    4588           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
    4589           0 :                 ret = -1;
    4590             :         /* Protected GAS Initial Request */
    4591           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
    4592           0 :                 ret = -1;
    4593             :         /* Protected GAS Initial Response */
    4594           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
    4595           0 :                 ret = -1;
    4596             :         /* Protected GAS Comeback Request */
    4597           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
    4598           0 :                 ret = -1;
    4599             :         /* Protected GAS Comeback Response */
    4600           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
    4601           0 :                 ret = -1;
    4602             : #endif /* CONFIG_P2P || CONFIG_INTERWORKING */
    4603             : #ifdef CONFIG_P2P
    4604             :         /* P2P Public Action */
    4605             :         if (nl80211_register_action_frame(bss,
    4606             :                                           (u8 *) "\x04\x09\x50\x6f\x9a\x09",
    4607             :                                           6) < 0)
    4608             :                 ret = -1;
    4609             :         /* P2P Action */
    4610             :         if (nl80211_register_action_frame(bss,
    4611             :                                           (u8 *) "\x7f\x50\x6f\x9a\x09",
    4612             :                                           5) < 0)
    4613             :                 ret = -1;
    4614             : #endif /* CONFIG_P2P */
    4615             : #ifdef CONFIG_IEEE80211W
    4616             :         /* SA Query Response */
    4617           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
    4618           0 :                 ret = -1;
    4619             : #endif /* CONFIG_IEEE80211W */
    4620             : #ifdef CONFIG_TDLS
    4621             :         if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
    4622             :                 /* TDLS Discovery Response */
    4623             :                 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
    4624             :                     0)
    4625             :                         ret = -1;
    4626             :         }
    4627             : #endif /* CONFIG_TDLS */
    4628             : 
    4629             :         /* FT Action frames */
    4630           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
    4631           0 :                 ret = -1;
    4632             :         else
    4633           0 :                 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
    4634             :                         WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
    4635             : 
    4636             :         /* WNM - BSS Transition Management Request */
    4637           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
    4638           0 :                 ret = -1;
    4639             :         /* WNM-Sleep Mode Response */
    4640           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
    4641           0 :                 ret = -1;
    4642             : 
    4643             : #ifdef CONFIG_HS20
    4644             :         /* WNM-Notification */
    4645           0 :         if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x1a", 2) < 0)
    4646           0 :                 ret = -1;
    4647             : #endif /* CONFIG_HS20 */
    4648             : 
    4649           0 :         nl80211_mgmt_handle_register_eloop(bss);
    4650             : 
    4651           0 :         return ret;
    4652             : }
    4653             : 
    4654             : 
    4655         650 : static int nl80211_register_spurious_class3(struct i802_bss *bss)
    4656             : {
    4657         650 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4658             :         struct nl_msg *msg;
    4659         650 :         int ret = -1;
    4660             : 
    4661         650 :         msg = nlmsg_alloc();
    4662         650 :         if (!msg)
    4663           0 :                 return -1;
    4664             : 
    4665         650 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_UNEXPECTED_FRAME);
    4666             : 
    4667         650 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
    4668             : 
    4669         650 :         ret = send_and_recv(drv->global, bss->nl_mgmt, msg, NULL, NULL);
    4670         650 :         msg = NULL;
    4671         650 :         if (ret) {
    4672           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Register spurious class3 "
    4673             :                            "failed: ret=%d (%s)",
    4674             :                            ret, strerror(-ret));
    4675           0 :                 goto nla_put_failure;
    4676             :         }
    4677         650 :         ret = 0;
    4678             : nla_put_failure:
    4679         650 :         nlmsg_free(msg);
    4680         650 :         return ret;
    4681             : }
    4682             : 
    4683             : 
    4684         650 : static int nl80211_mgmt_subscribe_ap(struct i802_bss *bss)
    4685             : {
    4686             :         static const int stypes[] = {
    4687             :                 WLAN_FC_STYPE_AUTH,
    4688             :                 WLAN_FC_STYPE_ASSOC_REQ,
    4689             :                 WLAN_FC_STYPE_REASSOC_REQ,
    4690             :                 WLAN_FC_STYPE_DISASSOC,
    4691             :                 WLAN_FC_STYPE_DEAUTH,
    4692             :                 WLAN_FC_STYPE_ACTION,
    4693             :                 WLAN_FC_STYPE_PROBE_REQ,
    4694             : /* Beacon doesn't work as mac80211 doesn't currently allow
    4695             :  * it, but it wouldn't really be the right thing anyway as
    4696             :  * it isn't per interface ... maybe just dump the scan
    4697             :  * results periodically for OLBC?
    4698             :  */
    4699             :                 /* WLAN_FC_STYPE_BEACON, */
    4700             :         };
    4701             :         unsigned int i;
    4702             : 
    4703         650 :         if (nl80211_alloc_mgmt_handle(bss))
    4704           0 :                 return -1;
    4705         650 :         wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
    4706             :                    "handle %p", bss->nl_mgmt);
    4707             : 
    4708        5200 :         for (i = 0; i < ARRAY_SIZE(stypes); i++) {
    4709        4550 :                 if (nl80211_register_frame(bss, bss->nl_mgmt,
    4710             :                                            (WLAN_FC_TYPE_MGMT << 2) |
    4711        4550 :                                            (stypes[i] << 4),
    4712             :                                            NULL, 0) < 0) {
    4713           0 :                         goto out_err;
    4714             :                 }
    4715             :         }
    4716             : 
    4717         650 :         if (nl80211_register_spurious_class3(bss))
    4718           0 :                 goto out_err;
    4719             : 
    4720         650 :         if (nl80211_get_wiphy_data_ap(bss) == NULL)
    4721           0 :                 goto out_err;
    4722             : 
    4723         650 :         nl80211_mgmt_handle_register_eloop(bss);
    4724         650 :         return 0;
    4725             : 
    4726             : out_err:
    4727           0 :         nl_destroy_handles(&bss->nl_mgmt);
    4728           0 :         return -1;
    4729             : }
    4730             : 
    4731             : 
    4732           0 : static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
    4733             : {
    4734           0 :         if (nl80211_alloc_mgmt_handle(bss))
    4735           0 :                 return -1;
    4736           0 :         wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
    4737             :                    "handle %p (device SME)", bss->nl_mgmt);
    4738             : 
    4739           0 :         if (nl80211_register_frame(bss, bss->nl_mgmt,
    4740             :                                    (WLAN_FC_TYPE_MGMT << 2) |
    4741             :                                    (WLAN_FC_STYPE_ACTION << 4),
    4742             :                                    NULL, 0) < 0)
    4743           0 :                 goto out_err;
    4744             : 
    4745           0 :         nl80211_mgmt_handle_register_eloop(bss);
    4746           0 :         return 0;
    4747             : 
    4748             : out_err:
    4749           0 :         nl_destroy_handles(&bss->nl_mgmt);
    4750           0 :         return -1;
    4751             : }
    4752             : 
    4753             : 
    4754        1912 : static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
    4755             : {
    4756        1912 :         if (bss->nl_mgmt == NULL)
    4757        3174 :                 return;
    4758         650 :         wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
    4759             :                    "(%s)", bss->nl_mgmt, reason);
    4760         650 :         nl80211_destroy_eloop_handle(&bss->nl_mgmt);
    4761             : 
    4762         650 :         nl80211_put_wiphy_data_ap(bss);
    4763             : }
    4764             : 
    4765             : 
    4766           0 : static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
    4767             : {
    4768           0 :         wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
    4769           0 : }
    4770             : 
    4771             : 
    4772           0 : static void nl80211_del_p2pdev(struct i802_bss *bss)
    4773             : {
    4774           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4775             :         struct nl_msg *msg;
    4776             :         int ret;
    4777             : 
    4778           0 :         msg = nlmsg_alloc();
    4779           0 :         if (!msg)
    4780           0 :                 return;
    4781             : 
    4782           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
    4783           0 :         NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
    4784             : 
    4785           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    4786           0 :         msg = NULL;
    4787             : 
    4788           0 :         wpa_printf(MSG_DEBUG, "nl80211: Delete P2P Device %s (0x%llx): %s",
    4789           0 :                    bss->ifname, (long long unsigned int) bss->wdev_id,
    4790             :                    strerror(-ret));
    4791             : 
    4792             : nla_put_failure:
    4793           0 :         nlmsg_free(msg);
    4794             : }
    4795             : 
    4796             : 
    4797           0 : static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
    4798             : {
    4799           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4800             :         struct nl_msg *msg;
    4801           0 :         int ret = -1;
    4802             : 
    4803           0 :         msg = nlmsg_alloc();
    4804           0 :         if (!msg)
    4805           0 :                 return -1;
    4806             : 
    4807           0 :         if (start)
    4808           0 :                 nl80211_cmd(drv, msg, 0, NL80211_CMD_START_P2P_DEVICE);
    4809             :         else
    4810           0 :                 nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_P2P_DEVICE);
    4811             : 
    4812           0 :         NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
    4813             : 
    4814           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    4815           0 :         msg = NULL;
    4816             : 
    4817           0 :         wpa_printf(MSG_DEBUG, "nl80211: %s P2P Device %s (0x%llx): %s",
    4818             :                    start ? "Start" : "Stop",
    4819           0 :                    bss->ifname, (long long unsigned int) bss->wdev_id,
    4820             :                    strerror(-ret));
    4821             : 
    4822             : nla_put_failure:
    4823           0 :         nlmsg_free(msg);
    4824           0 :         return ret;
    4825             : }
    4826             : 
    4827             : 
    4828        1264 : static int i802_set_iface_flags(struct i802_bss *bss, int up)
    4829             : {
    4830             :         enum nl80211_iftype nlmode;
    4831             : 
    4832        1264 :         nlmode = nl80211_get_ifmode(bss);
    4833        1264 :         if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
    4834        1264 :                 return linux_set_iface_flags(bss->drv->global->ioctl_sock,
    4835        1264 :                                              bss->ifname, up);
    4836             :         }
    4837             : 
    4838             :         /* P2P Device has start/stop which is equivalent */
    4839           0 :         return nl80211_set_p2pdev(bss, up);
    4840             : }
    4841             : 
    4842             : 
    4843             : static int
    4844         631 : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
    4845             :                                    const u8 *set_addr, int first)
    4846             : {
    4847         631 :         struct i802_bss *bss = drv->first_bss;
    4848         631 :         int send_rfkill_event = 0;
    4849             :         enum nl80211_iftype nlmode;
    4850             : 
    4851         631 :         drv->ifindex = if_nametoindex(bss->ifname);
    4852         631 :         bss->ifindex = drv->ifindex;
    4853         631 :         bss->wdev_id = drv->global->if_add_wdevid;
    4854         631 :         bss->wdev_id_set = drv->global->if_add_wdevid_set;
    4855             : 
    4856         631 :         bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
    4857         631 :         bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
    4858         631 :         drv->global->if_add_wdevid_set = 0;
    4859             : 
    4860         631 :         if (!bss->if_dynamic && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
    4861           0 :                 bss->static_ap = 1;
    4862             : 
    4863         631 :         if (wpa_driver_nl80211_capa(drv))
    4864           0 :                 return -1;
    4865             : 
    4866         631 :         wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
    4867         631 :                    bss->ifname, drv->phyname);
    4868             : 
    4869         639 :         if (set_addr &&
    4870          16 :             (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) ||
    4871           8 :              linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
    4872             :                                 set_addr)))
    4873           0 :                 return -1;
    4874             : 
    4875         631 :         if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
    4876           0 :                 drv->start_mode_ap = 1;
    4877             : 
    4878         631 :         if (drv->hostapd || bss->static_ap)
    4879         631 :                 nlmode = NL80211_IFTYPE_AP;
    4880           0 :         else if (bss->if_dynamic)
    4881           0 :                 nlmode = nl80211_get_ifmode(bss);
    4882             :         else
    4883           0 :                 nlmode = NL80211_IFTYPE_STATION;
    4884             : 
    4885         631 :         if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
    4886           0 :                 wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
    4887           0 :                 return -1;
    4888             :         }
    4889             : 
    4890         631 :         if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
    4891           0 :                 nl80211_get_macaddr(bss);
    4892             : 
    4893         631 :         if (!rfkill_is_blocked(drv->rfkill)) {
    4894         631 :                 int ret = i802_set_iface_flags(bss, 1);
    4895         631 :                 if (ret) {
    4896           0 :                         wpa_printf(MSG_ERROR, "nl80211: Could not set "
    4897           0 :                                    "interface '%s' UP", bss->ifname);
    4898           0 :                         return ret;
    4899             :                 }
    4900         631 :                 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
    4901           0 :                         return ret;
    4902             :         } else {
    4903           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
    4904           0 :                            "interface '%s' due to rfkill", bss->ifname);
    4905           0 :                 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
    4906           0 :                         return 0;
    4907           0 :                 drv->if_disabled = 1;
    4908           0 :                 send_rfkill_event = 1;
    4909             :         }
    4910             : 
    4911         631 :         if (!drv->hostapd)
    4912           0 :                 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
    4913             :                                        1, IF_OPER_DORMANT);
    4914             : 
    4915         631 :         if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
    4916         631 :                                bss->addr))
    4917           0 :                 return -1;
    4918         631 :         os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
    4919             : 
    4920         631 :         if (send_rfkill_event) {
    4921           0 :                 eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
    4922             :                                        drv, drv->ctx);
    4923             :         }
    4924             : 
    4925         631 :         return 0;
    4926             : }
    4927             : 
    4928             : 
    4929         631 : static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
    4930             : {
    4931             :         struct nl_msg *msg;
    4932             : 
    4933         631 :         msg = nlmsg_alloc();
    4934         631 :         if (!msg)
    4935           0 :                 return -ENOMEM;
    4936             : 
    4937         631 :         wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
    4938             :                    drv->ifindex);
    4939         631 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_BEACON);
    4940         631 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    4941             : 
    4942         631 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    4943             :  nla_put_failure:
    4944           0 :         nlmsg_free(msg);
    4945           0 :         return -ENOBUFS;
    4946             : }
    4947             : 
    4948             : 
    4949             : /**
    4950             :  * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
    4951             :  * @bss: Pointer to private nl80211 data from wpa_driver_nl80211_init()
    4952             :  *
    4953             :  * Shut down driver interface and processing of driver events. Free
    4954             :  * private data buffer if one was allocated in wpa_driver_nl80211_init().
    4955             :  */
    4956         631 : static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
    4957             : {
    4958         631 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    4959             : 
    4960         631 :         bss->in_deinit = 1;
    4961         631 :         if (drv->data_tx_status)
    4962         631 :                 eloop_unregister_read_sock(drv->eapol_tx_sock);
    4963         631 :         if (drv->eapol_tx_sock >= 0)
    4964         631 :                 close(drv->eapol_tx_sock);
    4965             : 
    4966         631 :         if (bss->nl_preq)
    4967           0 :                 wpa_driver_nl80211_probe_req_report(bss, 0);
    4968         631 :         if (bss->added_if_into_bridge) {
    4969           5 :                 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
    4970           5 :                                     bss->ifname) < 0)
    4971          10 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
    4972             :                                    "interface %s from bridge %s: %s",
    4973          10 :                                    bss->ifname, bss->brname, strerror(errno));
    4974           5 :                 if (drv->rtnl_sk)
    4975           5 :                         nl80211_handle_destroy(drv->rtnl_sk);
    4976             :         }
    4977         631 :         if (bss->added_bridge) {
    4978           3 :                 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
    4979           6 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
    4980             :                                    "bridge %s: %s",
    4981           6 :                                    bss->brname, strerror(errno));
    4982             :         }
    4983             : 
    4984         631 :         nl80211_remove_monitor_interface(drv);
    4985             : 
    4986         631 :         if (is_ap_interface(drv->nlmode))
    4987         631 :                 wpa_driver_nl80211_del_beacon(drv);
    4988             : 
    4989         631 :         if (drv->eapol_sock >= 0) {
    4990         631 :                 eloop_unregister_read_sock(drv->eapol_sock);
    4991         631 :                 close(drv->eapol_sock);
    4992             :         }
    4993             : 
    4994         631 :         if (drv->if_indices != drv->default_if_indices)
    4995           0 :                 os_free(drv->if_indices);
    4996             : 
    4997         631 :         if (drv->disabled_11b_rates)
    4998           0 :                 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
    4999             : 
    5000         631 :         netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
    5001             :                                IF_OPER_UP);
    5002         631 :         eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
    5003         631 :         rfkill_deinit(drv->rfkill);
    5004             : 
    5005         631 :         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
    5006             : 
    5007         631 :         if (!drv->start_iface_up)
    5008         631 :                 (void) i802_set_iface_flags(bss, 0);
    5009             : 
    5010         631 :         if (drv->addr_changed) {
    5011           0 :                 linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
    5012           0 :                 if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
    5013           0 :                                        drv->perm_addr) < 0) {
    5014           0 :                         wpa_printf(MSG_DEBUG,
    5015             :                                    "nl80211: Could not restore permanent MAC address");
    5016             :                 }
    5017             :         }
    5018             : 
    5019         631 :         if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
    5020         631 :                 if (!drv->hostapd || !drv->start_mode_ap)
    5021         631 :                         wpa_driver_nl80211_set_mode(bss,
    5022             :                                                     NL80211_IFTYPE_STATION);
    5023         631 :                 nl80211_mgmt_unsubscribe(bss, "deinit");
    5024             :         } else {
    5025           0 :                 nl80211_mgmt_unsubscribe(bss, "deinit");
    5026           0 :                 nl80211_del_p2pdev(bss);
    5027             :         }
    5028         631 :         nl_cb_put(drv->nl_cb);
    5029             : 
    5030         631 :         nl80211_destroy_bss(drv->first_bss);
    5031             : 
    5032         631 :         os_free(drv->filter_ssids);
    5033             : 
    5034         631 :         os_free(drv->auth_ie);
    5035             : 
    5036         631 :         if (drv->in_interface_list)
    5037         631 :                 dl_list_del(&drv->list);
    5038             : 
    5039         631 :         os_free(drv->extended_capa);
    5040         631 :         os_free(drv->extended_capa_mask);
    5041         631 :         os_free(drv->first_bss);
    5042         631 :         os_free(drv);
    5043         631 : }
    5044             : 
    5045             : 
    5046             : /**
    5047             :  * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
    5048             :  * @eloop_ctx: Driver private data
    5049             :  * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
    5050             :  *
    5051             :  * This function can be used as registered timeout when starting a scan to
    5052             :  * generate a scan completed event if the driver does not report this.
    5053             :  */
    5054           0 : static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
    5055             : {
    5056           0 :         struct wpa_driver_nl80211_data *drv = eloop_ctx;
    5057           0 :         if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
    5058           0 :                 wpa_driver_nl80211_set_mode(drv->first_bss,
    5059             :                                             drv->ap_scan_as_station);
    5060           0 :                 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
    5061             :         }
    5062           0 :         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
    5063           0 :         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
    5064           0 : }
    5065             : 
    5066             : 
    5067             : static struct nl_msg *
    5068          68 : nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
    5069             :                     struct wpa_driver_scan_params *params, u64 *wdev_id)
    5070             : {
    5071             :         struct nl_msg *msg;
    5072             :         size_t i;
    5073          68 :         u32 scan_flags = 0;
    5074             : 
    5075          68 :         msg = nlmsg_alloc();
    5076          68 :         if (!msg)
    5077           0 :                 return NULL;
    5078             : 
    5079          68 :         nl80211_cmd(drv, msg, 0, cmd);
    5080             : 
    5081          68 :         if (!wdev_id)
    5082          68 :                 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    5083             :         else
    5084           0 :                 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, *wdev_id);
    5085             : 
    5086          68 :         if (params->num_ssids) {
    5087             :                 struct nlattr *ssids;
    5088             : 
    5089           0 :                 ssids = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
    5090           0 :                 if (ssids == NULL)
    5091           0 :                         goto fail;
    5092           0 :                 for (i = 0; i < params->num_ssids; i++) {
    5093           0 :                         wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
    5094           0 :                                           params->ssids[i].ssid,
    5095             :                                           params->ssids[i].ssid_len);
    5096           0 :                         if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
    5097           0 :                                     params->ssids[i].ssid) < 0)
    5098           0 :                                 goto fail;
    5099             :                 }
    5100           0 :                 nla_nest_end(msg, ssids);
    5101             :         }
    5102             : 
    5103          68 :         if (params->extra_ies) {
    5104           0 :                 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
    5105           0 :                             params->extra_ies, params->extra_ies_len);
    5106           0 :                 if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
    5107           0 :                             params->extra_ies) < 0)
    5108           0 :                         goto fail;
    5109             :         }
    5110             : 
    5111          68 :         if (params->freqs) {
    5112             :                 struct nlattr *freqs;
    5113          68 :                 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
    5114          68 :                 if (freqs == NULL)
    5115           0 :                         goto fail;
    5116         621 :                 for (i = 0; params->freqs[i]; i++) {
    5117         553 :                         wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
    5118         553 :                                    "MHz", params->freqs[i]);
    5119         553 :                         if (nla_put_u32(msg, i + 1, params->freqs[i]) < 0)
    5120           0 :                                 goto fail;
    5121             :                 }
    5122          68 :                 nla_nest_end(msg, freqs);
    5123             :         }
    5124             : 
    5125          68 :         os_free(drv->filter_ssids);
    5126          68 :         drv->filter_ssids = params->filter_ssids;
    5127          68 :         params->filter_ssids = NULL;
    5128          68 :         drv->num_filter_ssids = params->num_filter_ssids;
    5129             : 
    5130          68 :         if (params->only_new_results) {
    5131           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
    5132           0 :                 scan_flags |= NL80211_SCAN_FLAG_FLUSH;
    5133             :         }
    5134             : 
    5135          68 :         if (params->low_priority && drv->have_low_prio_scan) {
    5136           0 :                 wpa_printf(MSG_DEBUG,
    5137             :                            "nl80211: Add NL80211_SCAN_FLAG_LOW_PRIORITY");
    5138           0 :                 scan_flags |= NL80211_SCAN_FLAG_LOW_PRIORITY;
    5139             :         }
    5140             : 
    5141          68 :         if (scan_flags)
    5142           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, scan_flags);
    5143             : 
    5144          68 :         return msg;
    5145             : 
    5146             : fail:
    5147             : nla_put_failure:
    5148           0 :         nlmsg_free(msg);
    5149           0 :         return NULL;
    5150             : }
    5151             : 
    5152             : 
    5153             : /**
    5154             :  * wpa_driver_nl80211_scan - Request the driver to initiate scan
    5155             :  * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
    5156             :  * @params: Scan parameters
    5157             :  * Returns: 0 on success, -1 on failure
    5158             :  */
    5159          68 : static int wpa_driver_nl80211_scan(struct i802_bss *bss,
    5160             :                                    struct wpa_driver_scan_params *params)
    5161             : {
    5162          68 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5163          68 :         int ret = -1, timeout;
    5164          68 :         struct nl_msg *msg = NULL;
    5165             : 
    5166          68 :         wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
    5167          68 :         drv->scan_for_auth = 0;
    5168             : 
    5169          68 :         msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params,
    5170          68 :                                   bss->wdev_id_set ? &bss->wdev_id : NULL);
    5171          68 :         if (!msg)
    5172           0 :                 return -1;
    5173             : 
    5174          68 :         if (params->p2p_probe) {
    5175             :                 struct nlattr *rates;
    5176             : 
    5177           0 :                 wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
    5178             : 
    5179           0 :                 rates = nla_nest_start(msg, NL80211_ATTR_SCAN_SUPP_RATES);
    5180           0 :                 if (rates == NULL)
    5181           0 :                         goto nla_put_failure;
    5182             : 
    5183             :                 /*
    5184             :                  * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
    5185             :                  * by masking out everything else apart from the OFDM rates 6,
    5186             :                  * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
    5187             :                  * rates are left enabled.
    5188             :                  */
    5189           0 :                 NLA_PUT(msg, NL80211_BAND_2GHZ, 8,
    5190             :                         "\x0c\x12\x18\x24\x30\x48\x60\x6c");
    5191           0 :                 nla_nest_end(msg, rates);
    5192             : 
    5193           0 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
    5194             :         }
    5195             : 
    5196          68 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5197          68 :         msg = NULL;
    5198          68 :         if (ret) {
    5199           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
    5200             :                            "(%s)", ret, strerror(-ret));
    5201           0 :                 if (drv->hostapd && is_ap_interface(drv->nlmode)) {
    5202           0 :                         enum nl80211_iftype old_mode = drv->nlmode;
    5203             : 
    5204             :                         /*
    5205             :                          * mac80211 does not allow scan requests in AP mode, so
    5206             :                          * try to do this in station mode.
    5207             :                          */
    5208           0 :                         if (wpa_driver_nl80211_set_mode(
    5209             :                                     bss, NL80211_IFTYPE_STATION))
    5210           0 :                                 goto nla_put_failure;
    5211             : 
    5212           0 :                         if (wpa_driver_nl80211_scan(bss, params)) {
    5213           0 :                                 wpa_driver_nl80211_set_mode(bss, drv->nlmode);
    5214           0 :                                 goto nla_put_failure;
    5215             :                         }
    5216             : 
    5217             :                         /* Restore AP mode when processing scan results */
    5218           0 :                         drv->ap_scan_as_station = old_mode;
    5219           0 :                         ret = 0;
    5220             :                 } else
    5221             :                         goto nla_put_failure;
    5222             :         }
    5223             : 
    5224          68 :         drv->scan_state = SCAN_REQUESTED;
    5225             :         /* Not all drivers generate "scan completed" wireless event, so try to
    5226             :          * read results after a timeout. */
    5227          68 :         timeout = 10;
    5228          68 :         if (drv->scan_complete_events) {
    5229             :                 /*
    5230             :                  * The driver seems to deliver events to notify when scan is
    5231             :                  * complete, so use longer timeout to avoid race conditions
    5232             :                  * with scanning and following association request.
    5233             :                  */
    5234          29 :                 timeout = 30;
    5235             :         }
    5236          68 :         wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
    5237             :                    "seconds", ret, timeout);
    5238          68 :         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
    5239          68 :         eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
    5240             :                                drv, drv->ctx);
    5241             : 
    5242             : nla_put_failure:
    5243          68 :         nlmsg_free(msg);
    5244          68 :         return ret;
    5245             : }
    5246             : 
    5247             : 
    5248             : /**
    5249             :  * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
    5250             :  * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
    5251             :  * @params: Scan parameters
    5252             :  * @interval: Interval between scan cycles in milliseconds
    5253             :  * Returns: 0 on success, -1 on failure or if not supported
    5254             :  */
    5255           0 : static int wpa_driver_nl80211_sched_scan(void *priv,
    5256             :                                          struct wpa_driver_scan_params *params,
    5257             :                                          u32 interval)
    5258             : {
    5259           0 :         struct i802_bss *bss = priv;
    5260           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5261           0 :         int ret = -1;
    5262             :         struct nl_msg *msg;
    5263             :         size_t i;
    5264             : 
    5265           0 :         wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request");
    5266             : 
    5267             : #ifdef ANDROID
    5268             :         if (!drv->capa.sched_scan_supported)
    5269             :                 return android_pno_start(bss, params);
    5270             : #endif /* ANDROID */
    5271             : 
    5272           0 :         msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params,
    5273           0 :                                   bss->wdev_id_set ? &bss->wdev_id : NULL);
    5274           0 :         if (!msg)
    5275           0 :                 goto nla_put_failure;
    5276             : 
    5277           0 :         NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
    5278             : 
    5279           0 :         if ((drv->num_filter_ssids &&
    5280           0 :             (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
    5281           0 :             params->filter_rssi) {
    5282             :                 struct nlattr *match_sets;
    5283           0 :                 match_sets = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
    5284           0 :                 if (match_sets == NULL)
    5285           0 :                         goto nla_put_failure;
    5286             : 
    5287           0 :                 for (i = 0; i < drv->num_filter_ssids; i++) {
    5288             :                         struct nlattr *match_set_ssid;
    5289           0 :                         wpa_hexdump_ascii(MSG_MSGDUMP,
    5290             :                                           "nl80211: Sched scan filter SSID",
    5291           0 :                                           drv->filter_ssids[i].ssid,
    5292           0 :                                           drv->filter_ssids[i].ssid_len);
    5293             : 
    5294           0 :                         match_set_ssid = nla_nest_start(msg, i + 1);
    5295           0 :                         if (match_set_ssid == NULL)
    5296           0 :                                 goto nla_put_failure;
    5297           0 :                         NLA_PUT(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
    5298             :                                 drv->filter_ssids[i].ssid_len,
    5299             :                                 drv->filter_ssids[i].ssid);
    5300           0 :                         if (params->filter_rssi)
    5301           0 :                                 NLA_PUT_U32(msg,
    5302             :                                             NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
    5303             :                                             params->filter_rssi);
    5304             : 
    5305           0 :                         nla_nest_end(msg, match_set_ssid);
    5306             :                 }
    5307             : 
    5308             :                 /*
    5309             :                  * Due to backward compatibility code, newer kernels treat this
    5310             :                  * matchset (with only an RSSI filter) as the default for all
    5311             :                  * other matchsets, unless it's the only one, in which case the
    5312             :                  * matchset will actually allow all SSIDs above the RSSI.
    5313             :                  */
    5314           0 :                 if (params->filter_rssi) {
    5315             :                         struct nlattr *match_set_rssi;
    5316           0 :                         match_set_rssi = nla_nest_start(msg, 0);
    5317           0 :                         if (match_set_rssi == NULL)
    5318           0 :                                 goto nla_put_failure;
    5319           0 :                         NLA_PUT_U32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
    5320             :                                     params->filter_rssi);
    5321           0 :                         wpa_printf(MSG_MSGDUMP,
    5322             :                                    "nl80211: Sched scan RSSI filter %d dBm",
    5323             :                                    params->filter_rssi);
    5324           0 :                         nla_nest_end(msg, match_set_rssi);
    5325             :                 }
    5326             : 
    5327           0 :                 nla_nest_end(msg, match_sets);
    5328             :         }
    5329             : 
    5330           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5331             : 
    5332             :         /* TODO: if we get an error here, we should fall back to normal scan */
    5333             : 
    5334           0 :         msg = NULL;
    5335           0 :         if (ret) {
    5336           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
    5337             :                            "ret=%d (%s)", ret, strerror(-ret));
    5338           0 :                 goto nla_put_failure;
    5339             :         }
    5340             : 
    5341           0 :         wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
    5342             :                    "scan interval %d msec", ret, interval);
    5343             : 
    5344             : nla_put_failure:
    5345           0 :         nlmsg_free(msg);
    5346           0 :         return ret;
    5347             : }
    5348             : 
    5349             : 
    5350             : /**
    5351             :  * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
    5352             :  * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
    5353             :  * Returns: 0 on success, -1 on failure or if not supported
    5354             :  */
    5355           0 : static int wpa_driver_nl80211_stop_sched_scan(void *priv)
    5356             : {
    5357           0 :         struct i802_bss *bss = priv;
    5358           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5359           0 :         int ret = 0;
    5360             :         struct nl_msg *msg;
    5361             : 
    5362             : #ifdef ANDROID
    5363             :         if (!drv->capa.sched_scan_supported)
    5364             :                 return android_pno_stop(bss);
    5365             : #endif /* ANDROID */
    5366             : 
    5367           0 :         msg = nlmsg_alloc();
    5368           0 :         if (!msg)
    5369           0 :                 return -1;
    5370             : 
    5371           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_SCHED_SCAN);
    5372             : 
    5373           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    5374             : 
    5375           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5376           0 :         msg = NULL;
    5377           0 :         if (ret) {
    5378           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop failed: "
    5379             :                            "ret=%d (%s)", ret, strerror(-ret));
    5380           0 :                 goto nla_put_failure;
    5381             :         }
    5382             : 
    5383           0 :         wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop sent (ret=%d)", ret);
    5384             : 
    5385             : nla_put_failure:
    5386           0 :         nlmsg_free(msg);
    5387           0 :         return ret;
    5388             : }
    5389             : 
    5390             : 
    5391           0 : static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
    5392             : {
    5393             :         const u8 *end, *pos;
    5394             : 
    5395           0 :         if (ies == NULL)
    5396           0 :                 return NULL;
    5397             : 
    5398           0 :         pos = ies;
    5399           0 :         end = ies + ies_len;
    5400             : 
    5401           0 :         while (pos + 1 < end) {
    5402           0 :                 if (pos + 2 + pos[1] > end)
    5403           0 :                         break;
    5404           0 :                 if (pos[0] == ie)
    5405           0 :                         return pos;
    5406           0 :                 pos += 2 + pos[1];
    5407             :         }
    5408             : 
    5409           0 :         return NULL;
    5410             : }
    5411             : 
    5412             : 
    5413           7 : static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
    5414             :                                  const u8 *ie, size_t ie_len)
    5415             : {
    5416             :         const u8 *ssid;
    5417             :         size_t i;
    5418             : 
    5419           7 :         if (drv->filter_ssids == NULL)
    5420           7 :                 return 0;
    5421             : 
    5422           0 :         ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
    5423           0 :         if (ssid == NULL)
    5424           0 :                 return 1;
    5425             : 
    5426           0 :         for (i = 0; i < drv->num_filter_ssids; i++) {
    5427           0 :                 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
    5428           0 :                     os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
    5429             :                     0)
    5430           0 :                         return 0;
    5431             :         }
    5432             : 
    5433           0 :         return 1;
    5434             : }
    5435             : 
    5436             : 
    5437           7 : static int bss_info_handler(struct nl_msg *msg, void *arg)
    5438             : {
    5439             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    5440           7 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    5441             :         struct nlattr *bss[NL80211_BSS_MAX + 1];
    5442             :         static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
    5443             :                 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
    5444             :                 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
    5445             :                 [NL80211_BSS_TSF] = { .type = NLA_U64 },
    5446             :                 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
    5447             :                 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
    5448             :                 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
    5449             :                 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
    5450             :                 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
    5451             :                 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
    5452             :                 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
    5453             :                 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
    5454             :         };
    5455           7 :         struct nl80211_bss_info_arg *_arg = arg;
    5456           7 :         struct wpa_scan_results *res = _arg->res;
    5457             :         struct wpa_scan_res **tmp;
    5458             :         struct wpa_scan_res *r;
    5459             :         const u8 *ie, *beacon_ie;
    5460             :         size_t ie_len, beacon_ie_len;
    5461             :         u8 *pos;
    5462             :         size_t i;
    5463             : 
    5464           7 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    5465             :                   genlmsg_attrlen(gnlh, 0), NULL);
    5466           7 :         if (!tb[NL80211_ATTR_BSS])
    5467           0 :                 return NL_SKIP;
    5468           7 :         if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
    5469             :                              bss_policy))
    5470           0 :                 return NL_SKIP;
    5471           7 :         if (bss[NL80211_BSS_STATUS]) {
    5472             :                 enum nl80211_bss_status status;
    5473           0 :                 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
    5474           0 :                 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
    5475           0 :                     bss[NL80211_BSS_FREQUENCY]) {
    5476           0 :                         _arg->assoc_freq =
    5477           0 :                                 nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
    5478           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
    5479             :                                    _arg->assoc_freq);
    5480             :                 }
    5481           0 :                 if (status == NL80211_BSS_STATUS_IBSS_JOINED &&
    5482           0 :                     bss[NL80211_BSS_FREQUENCY]) {
    5483           0 :                         _arg->ibss_freq =
    5484           0 :                                 nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
    5485           0 :                         wpa_printf(MSG_DEBUG, "nl80211: IBSS-joined on %u MHz",
    5486             :                                    _arg->ibss_freq);
    5487             :                 }
    5488           0 :                 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
    5489           0 :                     bss[NL80211_BSS_BSSID]) {
    5490           0 :                         os_memcpy(_arg->assoc_bssid,
    5491             :                                   nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN);
    5492           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Associated with "
    5493           0 :                                    MACSTR, MAC2STR(_arg->assoc_bssid));
    5494             :                 }
    5495             :         }
    5496           7 :         if (!res)
    5497           0 :                 return NL_SKIP;
    5498           7 :         if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
    5499           7 :                 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
    5500           7 :                 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
    5501             :         } else {
    5502           0 :                 ie = NULL;
    5503           0 :                 ie_len = 0;
    5504             :         }
    5505           7 :         if (bss[NL80211_BSS_BEACON_IES]) {
    5506           7 :                 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
    5507           7 :                 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
    5508             :         } else {
    5509           0 :                 beacon_ie = NULL;
    5510           0 :                 beacon_ie_len = 0;
    5511             :         }
    5512             : 
    5513           7 :         if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
    5514             :                                   ie ? ie_len : beacon_ie_len))
    5515           0 :                 return NL_SKIP;
    5516             : 
    5517           7 :         r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
    5518           7 :         if (r == NULL)
    5519           0 :                 return NL_SKIP;
    5520           7 :         if (bss[NL80211_BSS_BSSID])
    5521           7 :                 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
    5522             :                           ETH_ALEN);
    5523           7 :         if (bss[NL80211_BSS_FREQUENCY])
    5524           7 :                 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
    5525           7 :         if (bss[NL80211_BSS_BEACON_INTERVAL])
    5526           7 :                 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
    5527           7 :         if (bss[NL80211_BSS_CAPABILITY])
    5528           7 :                 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
    5529           7 :         r->flags |= WPA_SCAN_NOISE_INVALID;
    5530           7 :         if (bss[NL80211_BSS_SIGNAL_MBM]) {
    5531           7 :                 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
    5532           7 :                 r->level /= 100; /* mBm to dBm */
    5533           7 :                 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
    5534           0 :         } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
    5535           0 :                 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
    5536           0 :                 r->flags |= WPA_SCAN_QUAL_INVALID;
    5537             :         } else
    5538           0 :                 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
    5539           7 :         if (bss[NL80211_BSS_TSF])
    5540           7 :                 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
    5541           7 :         if (bss[NL80211_BSS_SEEN_MS_AGO])
    5542           7 :                 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
    5543           7 :         r->ie_len = ie_len;
    5544           7 :         pos = (u8 *) (r + 1);
    5545           7 :         if (ie) {
    5546           7 :                 os_memcpy(pos, ie, ie_len);
    5547           7 :                 pos += ie_len;
    5548             :         }
    5549           7 :         r->beacon_ie_len = beacon_ie_len;
    5550           7 :         if (beacon_ie)
    5551           7 :                 os_memcpy(pos, beacon_ie, beacon_ie_len);
    5552             : 
    5553           7 :         if (bss[NL80211_BSS_STATUS]) {
    5554             :                 enum nl80211_bss_status status;
    5555           0 :                 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
    5556           0 :                 switch (status) {
    5557             :                 case NL80211_BSS_STATUS_AUTHENTICATED:
    5558           0 :                         r->flags |= WPA_SCAN_AUTHENTICATED;
    5559           0 :                         break;
    5560             :                 case NL80211_BSS_STATUS_ASSOCIATED:
    5561           0 :                         r->flags |= WPA_SCAN_ASSOCIATED;
    5562           0 :                         break;
    5563             :                 default:
    5564           0 :                         break;
    5565             :                 }
    5566             :         }
    5567             : 
    5568             :         /*
    5569             :          * cfg80211 maintains separate BSS table entries for APs if the same
    5570             :          * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
    5571             :          * not use frequency as a separate key in the BSS table, so filter out
    5572             :          * duplicated entries. Prefer associated BSS entry in such a case in
    5573             :          * order to get the correct frequency into the BSS table. Similarly,
    5574             :          * prefer newer entries over older.
    5575             :          */
    5576           8 :         for (i = 0; i < res->num; i++) {
    5577             :                 const u8 *s1, *s2;
    5578           1 :                 if (os_memcmp(res->res[i]->bssid, r->bssid, ETH_ALEN) != 0)
    5579           1 :                         continue;
    5580             : 
    5581           0 :                 s1 = nl80211_get_ie((u8 *) (res->res[i] + 1),
    5582           0 :                                     res->res[i]->ie_len, WLAN_EID_SSID);
    5583           0 :                 s2 = nl80211_get_ie((u8 *) (r + 1), r->ie_len, WLAN_EID_SSID);
    5584           0 :                 if (s1 == NULL || s2 == NULL || s1[1] != s2[1] ||
    5585           0 :                     os_memcmp(s1, s2, 2 + s1[1]) != 0)
    5586           0 :                         continue;
    5587             : 
    5588             :                 /* Same BSSID,SSID was already included in scan results */
    5589           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
    5590           0 :                            "for " MACSTR, MAC2STR(r->bssid));
    5591             : 
    5592           0 :                 if (((r->flags & WPA_SCAN_ASSOCIATED) &&
    5593           0 :                      !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) ||
    5594           0 :                     r->age < res->res[i]->age) {
    5595           0 :                         os_free(res->res[i]);
    5596           0 :                         res->res[i] = r;
    5597             :                 } else
    5598           0 :                         os_free(r);
    5599           0 :                 return NL_SKIP;
    5600             :         }
    5601             : 
    5602           7 :         tmp = os_realloc_array(res->res, res->num + 1,
    5603             :                                sizeof(struct wpa_scan_res *));
    5604           7 :         if (tmp == NULL) {
    5605           0 :                 os_free(r);
    5606           0 :                 return NL_SKIP;
    5607             :         }
    5608           7 :         tmp[res->num++] = r;
    5609           7 :         res->res = tmp;
    5610             : 
    5611           7 :         return NL_SKIP;
    5612             : }
    5613             : 
    5614             : 
    5615           0 : static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
    5616             :                                  const u8 *addr)
    5617             : {
    5618           0 :         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
    5619           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
    5620           0 :                            "mismatch (" MACSTR ")", MAC2STR(addr));
    5621           0 :                 wpa_driver_nl80211_mlme(drv, addr,
    5622             :                                         NL80211_CMD_DEAUTHENTICATE,
    5623             :                                         WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
    5624             :         }
    5625           0 : }
    5626             : 
    5627             : 
    5628          28 : static void wpa_driver_nl80211_check_bss_status(
    5629             :         struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
    5630             : {
    5631             :         size_t i;
    5632             : 
    5633          35 :         for (i = 0; i < res->num; i++) {
    5634           7 :                 struct wpa_scan_res *r = res->res[i];
    5635           7 :                 if (r->flags & WPA_SCAN_AUTHENTICATED) {
    5636           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Scan results "
    5637             :                                    "indicates BSS status with " MACSTR
    5638             :                                    " as authenticated",
    5639           0 :                                    MAC2STR(r->bssid));
    5640           0 :                         if (is_sta_interface(drv->nlmode) &&
    5641           0 :                             os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
    5642           0 :                             os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
    5643             :                             0) {
    5644           0 :                                 wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
    5645             :                                            " in local state (auth=" MACSTR
    5646             :                                            " assoc=" MACSTR ")",
    5647           0 :                                            MAC2STR(drv->auth_bssid),
    5648           0 :                                            MAC2STR(drv->bssid));
    5649           0 :                                 clear_state_mismatch(drv, r->bssid);
    5650             :                         }
    5651             :                 }
    5652             : 
    5653           7 :                 if (r->flags & WPA_SCAN_ASSOCIATED) {
    5654           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Scan results "
    5655             :                                    "indicate BSS status with " MACSTR
    5656             :                                    " as associated",
    5657           0 :                                    MAC2STR(r->bssid));
    5658           0 :                         if (is_sta_interface(drv->nlmode) &&
    5659           0 :                             !drv->associated) {
    5660           0 :                                 wpa_printf(MSG_DEBUG, "nl80211: Local state "
    5661             :                                            "(not associated) does not match "
    5662             :                                            "with BSS state");
    5663           0 :                                 clear_state_mismatch(drv, r->bssid);
    5664           0 :                         } else if (is_sta_interface(drv->nlmode) &&
    5665           0 :                                    os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
    5666             :                                    0) {
    5667           0 :                                 wpa_printf(MSG_DEBUG, "nl80211: Local state "
    5668             :                                            "(associated with " MACSTR ") does "
    5669             :                                            "not match with BSS state",
    5670           0 :                                            MAC2STR(drv->bssid));
    5671           0 :                                 clear_state_mismatch(drv, r->bssid);
    5672           0 :                                 clear_state_mismatch(drv, drv->bssid);
    5673             :                         }
    5674             :                 }
    5675             :         }
    5676          28 : }
    5677             : 
    5678             : 
    5679             : static struct wpa_scan_results *
    5680          28 : nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
    5681             : {
    5682             :         struct nl_msg *msg;
    5683             :         struct wpa_scan_results *res;
    5684             :         int ret;
    5685             :         struct nl80211_bss_info_arg arg;
    5686             : 
    5687          28 :         res = os_zalloc(sizeof(*res));
    5688          28 :         if (res == NULL)
    5689           0 :                 return NULL;
    5690          28 :         msg = nlmsg_alloc();
    5691          28 :         if (!msg)
    5692           0 :                 goto nla_put_failure;
    5693             : 
    5694          28 :         nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
    5695          28 :         if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
    5696           0 :                 goto nla_put_failure;
    5697             : 
    5698          28 :         arg.drv = drv;
    5699          28 :         arg.res = res;
    5700          28 :         ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
    5701          28 :         msg = NULL;
    5702          28 :         if (ret == 0) {
    5703          28 :                 wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu "
    5704             :                            "BSSes)", (unsigned long) res->num);
    5705          28 :                 nl80211_get_noise_for_scan_results(drv, res);
    5706          28 :                 return res;
    5707             :         }
    5708           0 :         wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
    5709             :                    "(%s)", ret, strerror(-ret));
    5710             : nla_put_failure:
    5711           0 :         nlmsg_free(msg);
    5712           0 :         wpa_scan_results_free(res);
    5713           0 :         return NULL;
    5714             : }
    5715             : 
    5716             : 
    5717             : /**
    5718             :  * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
    5719             :  * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
    5720             :  * Returns: Scan results on success, -1 on failure
    5721             :  */
    5722             : static struct wpa_scan_results *
    5723          28 : wpa_driver_nl80211_get_scan_results(void *priv)
    5724             : {
    5725          28 :         struct i802_bss *bss = priv;
    5726          28 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5727             :         struct wpa_scan_results *res;
    5728             : 
    5729          28 :         res = nl80211_get_scan_results(drv);
    5730          28 :         if (res)
    5731          28 :                 wpa_driver_nl80211_check_bss_status(drv, res);
    5732          28 :         return res;
    5733             : }
    5734             : 
    5735             : 
    5736           0 : static void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
    5737             : {
    5738             :         struct wpa_scan_results *res;
    5739             :         size_t i;
    5740             : 
    5741           0 :         res = nl80211_get_scan_results(drv);
    5742           0 :         if (res == NULL) {
    5743           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
    5744           0 :                 return;
    5745             :         }
    5746             : 
    5747           0 :         wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
    5748           0 :         for (i = 0; i < res->num; i++) {
    5749           0 :                 struct wpa_scan_res *r = res->res[i];
    5750           0 :                 wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s%s",
    5751           0 :                            (int) i, (int) res->num, MAC2STR(r->bssid),
    5752           0 :                            r->flags & WPA_SCAN_AUTHENTICATED ? " [auth]" : "",
    5753           0 :                            r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
    5754             :         }
    5755             : 
    5756           0 :         wpa_scan_results_free(res);
    5757             : }
    5758             : 
    5759             : 
    5760        2045 : static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
    5761             : {
    5762        2045 :         switch (alg) {
    5763             :         case WPA_ALG_WEP:
    5764          10 :                 if (key_len == 5)
    5765           4 :                         return WLAN_CIPHER_SUITE_WEP40;
    5766           6 :                 return WLAN_CIPHER_SUITE_WEP104;
    5767             :         case WPA_ALG_TKIP:
    5768          70 :                 return WLAN_CIPHER_SUITE_TKIP;
    5769             :         case WPA_ALG_CCMP:
    5770        1755 :                 return WLAN_CIPHER_SUITE_CCMP;
    5771             :         case WPA_ALG_GCMP:
    5772           0 :                 return WLAN_CIPHER_SUITE_GCMP;
    5773             :         case WPA_ALG_CCMP_256:
    5774           0 :                 return WLAN_CIPHER_SUITE_CCMP_256;
    5775             :         case WPA_ALG_GCMP_256:
    5776           0 :                 return WLAN_CIPHER_SUITE_GCMP_256;
    5777             :         case WPA_ALG_IGTK:
    5778         210 :                 return WLAN_CIPHER_SUITE_AES_CMAC;
    5779             :         case WPA_ALG_BIP_GMAC_128:
    5780           0 :                 return WLAN_CIPHER_SUITE_BIP_GMAC_128;
    5781             :         case WPA_ALG_BIP_GMAC_256:
    5782           0 :                 return WLAN_CIPHER_SUITE_BIP_GMAC_256;
    5783             :         case WPA_ALG_BIP_CMAC_256:
    5784           0 :                 return WLAN_CIPHER_SUITE_BIP_CMAC_256;
    5785             :         case WPA_ALG_SMS4:
    5786           0 :                 return WLAN_CIPHER_SUITE_SMS4;
    5787             :         case WPA_ALG_KRK:
    5788           0 :                 return WLAN_CIPHER_SUITE_KRK;
    5789             :         case WPA_ALG_NONE:
    5790             :         case WPA_ALG_PMK:
    5791           0 :                 wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
    5792             :                            alg);
    5793           0 :                 return 0;
    5794             :         }
    5795             : 
    5796           0 :         wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
    5797             :                    alg);
    5798           0 :         return 0;
    5799             : }
    5800             : 
    5801             : 
    5802         866 : static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
    5803             : {
    5804         866 :         switch (cipher) {
    5805             :         case WPA_CIPHER_CCMP_256:
    5806           0 :                 return WLAN_CIPHER_SUITE_CCMP_256;
    5807             :         case WPA_CIPHER_GCMP_256:
    5808           0 :                 return WLAN_CIPHER_SUITE_GCMP_256;
    5809             :         case WPA_CIPHER_CCMP:
    5810         543 :                 return WLAN_CIPHER_SUITE_CCMP;
    5811             :         case WPA_CIPHER_GCMP:
    5812           0 :                 return WLAN_CIPHER_SUITE_GCMP;
    5813             :         case WPA_CIPHER_TKIP:
    5814          76 :                 return WLAN_CIPHER_SUITE_TKIP;
    5815             :         case WPA_CIPHER_WEP104:
    5816           5 :                 return WLAN_CIPHER_SUITE_WEP104;
    5817             :         case WPA_CIPHER_WEP40:
    5818           7 :                 return WLAN_CIPHER_SUITE_WEP40;
    5819             :         case WPA_CIPHER_GTK_NOT_USED:
    5820           0 :                 return WLAN_CIPHER_SUITE_NO_GROUP_ADDR;
    5821             :         }
    5822             : 
    5823         235 :         return 0;
    5824             : }
    5825             : 
    5826             : 
    5827         866 : static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
    5828             :                                        int max_suites)
    5829             : {
    5830         866 :         int num_suites = 0;
    5831             : 
    5832         866 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
    5833           0 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP_256;
    5834         866 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
    5835           0 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP_256;
    5836         866 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
    5837         592 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
    5838         866 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
    5839           0 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
    5840         866 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
    5841          79 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
    5842         866 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
    5843           5 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
    5844         866 :         if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
    5845           7 :                 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
    5846             : 
    5847         866 :         return num_suites;
    5848             : }
    5849             : 
    5850             : 
    5851        9752 : static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
    5852             :                                       enum wpa_alg alg, const u8 *addr,
    5853             :                                       int key_idx, int set_tx,
    5854             :                                       const u8 *seq, size_t seq_len,
    5855             :                                       const u8 *key, size_t key_len)
    5856             : {
    5857        9752 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    5858             :         int ifindex;
    5859             :         struct nl_msg *msg;
    5860             :         int ret;
    5861        9752 :         int tdls = 0;
    5862             : 
    5863             :         /* Ignore for P2P Device */
    5864        9752 :         if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
    5865           0 :                 return 0;
    5866             : 
    5867        9752 :         ifindex = if_nametoindex(ifname);
    5868        9752 :         wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
    5869             :                    "set_tx=%d seq_len=%lu key_len=%lu",
    5870             :                    __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
    5871             :                    (unsigned long) seq_len, (unsigned long) key_len);
    5872             : #ifdef CONFIG_TDLS
    5873             :         if (key_idx == -1) {
    5874             :                 key_idx = 0;
    5875             :                 tdls = 1;
    5876             :         }
    5877             : #endif /* CONFIG_TDLS */
    5878             : 
    5879        9752 :         msg = nlmsg_alloc();
    5880        9752 :         if (!msg)
    5881           0 :                 return -ENOMEM;
    5882             : 
    5883        9752 :         if (alg == WPA_ALG_NONE) {
    5884        7707 :                 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_KEY);
    5885             :         } else {
    5886        2045 :                 nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_KEY);
    5887        2045 :                 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
    5888        2045 :                 wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
    5889        2045 :                 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
    5890             :                             wpa_alg_to_cipher_suite(alg, key_len));
    5891             :         }
    5892             : 
    5893        9752 :         if (seq && seq_len) {
    5894           0 :                 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
    5895           0 :                 wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
    5896             :         }
    5897             : 
    5898        9752 :         if (addr && !is_broadcast_ether_addr(addr)) {
    5899        5766 :                 wpa_printf(MSG_DEBUG, "   addr=" MACSTR, MAC2STR(addr));
    5900        5766 :                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
    5901             : 
    5902       11532 :                 if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
    5903           0 :                         wpa_printf(MSG_DEBUG, "   RSN IBSS RX GTK");
    5904           0 :                         NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE,
    5905             :                                     NL80211_KEYTYPE_GROUP);
    5906             :                 }
    5907        3986 :         } else if (addr && is_broadcast_ether_addr(addr)) {
    5908             :                 struct nlattr *types;
    5909             : 
    5910        1032 :                 wpa_printf(MSG_DEBUG, "   broadcast key");
    5911             : 
    5912        1032 :                 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
    5913        1032 :                 if (!types)
    5914           0 :                         goto nla_put_failure;
    5915        1032 :                 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
    5916        1032 :                 nla_nest_end(msg, types);
    5917             :         }
    5918        9752 :         NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
    5919        9752 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
    5920             : 
    5921        9752 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5922        9752 :         if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
    5923        7220 :                 ret = 0;
    5924        9752 :         if (ret)
    5925          19 :                 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
    5926             :                            ret, strerror(-ret));
    5927             : 
    5928             :         /*
    5929             :          * If we failed or don't need to set the default TX key (below),
    5930             :          * we're done here.
    5931             :          */
    5932        9752 :         if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
    5933        7722 :                 return ret;
    5934        4056 :         if (is_ap_interface(drv->nlmode) && addr &&
    5935        2026 :             !is_broadcast_ether_addr(addr))
    5936         996 :                 return ret;
    5937             : 
    5938        1034 :         msg = nlmsg_alloc();
    5939        1034 :         if (!msg)
    5940           0 :                 return -ENOMEM;
    5941             : 
    5942        1034 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_KEY);
    5943        1034 :         NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
    5944        1034 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
    5945        1034 :         if (alg == WPA_ALG_IGTK)
    5946         210 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
    5947             :         else
    5948         824 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
    5949        2064 :         if (addr && is_broadcast_ether_addr(addr)) {
    5950             :                 struct nlattr *types;
    5951             : 
    5952        1030 :                 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
    5953        1030 :                 if (!types)
    5954           0 :                         goto nla_put_failure;
    5955        1030 :                 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
    5956        1030 :                 nla_nest_end(msg, types);
    5957           4 :         } else if (addr) {
    5958             :                 struct nlattr *types;
    5959             : 
    5960           0 :                 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
    5961           0 :                 if (!types)
    5962           0 :                         goto nla_put_failure;
    5963           0 :                 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST);
    5964           0 :                 nla_nest_end(msg, types);
    5965             :         }
    5966             : 
    5967        1034 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    5968        1034 :         if (ret == -ENOENT)
    5969           0 :                 ret = 0;
    5970        1034 :         if (ret)
    5971           0 :                 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
    5972             :                            "err=%d %s)", ret, strerror(-ret));
    5973        1034 :         return ret;
    5974             : 
    5975             : nla_put_failure:
    5976           0 :         nlmsg_free(msg);
    5977           0 :         return -ENOBUFS;
    5978             : }
    5979             : 
    5980             : 
    5981           0 : static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
    5982             :                       int key_idx, int defkey,
    5983             :                       const u8 *seq, size_t seq_len,
    5984             :                       const u8 *key, size_t key_len)
    5985             : {
    5986           0 :         struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
    5987           0 :         if (!key_attr)
    5988           0 :                 return -1;
    5989             : 
    5990           0 :         if (defkey && alg == WPA_ALG_IGTK)
    5991           0 :                 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
    5992           0 :         else if (defkey)
    5993           0 :                 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
    5994             : 
    5995           0 :         NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
    5996             : 
    5997           0 :         NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
    5998             :                     wpa_alg_to_cipher_suite(alg, key_len));
    5999             : 
    6000           0 :         if (seq && seq_len)
    6001           0 :                 NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
    6002             : 
    6003           0 :         NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
    6004             : 
    6005           0 :         nla_nest_end(msg, key_attr);
    6006             : 
    6007           0 :         return 0;
    6008             :  nla_put_failure:
    6009           0 :         return -1;
    6010             : }
    6011             : 
    6012             : 
    6013           0 : static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
    6014             :                                  struct nl_msg *msg)
    6015             : {
    6016           0 :         int i, privacy = 0;
    6017             :         struct nlattr *nl_keys, *nl_key;
    6018             : 
    6019           0 :         for (i = 0; i < 4; i++) {
    6020           0 :                 if (!params->wep_key[i])
    6021           0 :                         continue;
    6022           0 :                 privacy = 1;
    6023           0 :                 break;
    6024             :         }
    6025           0 :         if (params->wps == WPS_MODE_PRIVACY)
    6026           0 :                 privacy = 1;
    6027           0 :         if (params->pairwise_suite &&
    6028           0 :             params->pairwise_suite != WPA_CIPHER_NONE)
    6029           0 :                 privacy = 1;
    6030             : 
    6031           0 :         if (!privacy)
    6032           0 :                 return 0;
    6033             : 
    6034           0 :         NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
    6035             : 
    6036           0 :         nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
    6037           0 :         if (!nl_keys)
    6038           0 :                 goto nla_put_failure;
    6039             : 
    6040           0 :         for (i = 0; i < 4; i++) {
    6041           0 :                 if (!params->wep_key[i])
    6042           0 :                         continue;
    6043             : 
    6044           0 :                 nl_key = nla_nest_start(msg, i);
    6045           0 :                 if (!nl_key)
    6046           0 :                         goto nla_put_failure;
    6047             : 
    6048           0 :                 NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
    6049             :                         params->wep_key[i]);
    6050           0 :                 if (params->wep_key_len[i] == 5)
    6051           0 :                         NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
    6052             :                                     WLAN_CIPHER_SUITE_WEP40);
    6053             :                 else
    6054           0 :                         NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
    6055             :                                     WLAN_CIPHER_SUITE_WEP104);
    6056             : 
    6057           0 :                 NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
    6058             : 
    6059           0 :                 if (i == params->wep_tx_keyidx)
    6060           0 :                         NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
    6061             : 
    6062           0 :                 nla_nest_end(msg, nl_key);
    6063             :         }
    6064           0 :         nla_nest_end(msg, nl_keys);
    6065             : 
    6066           0 :         return 0;
    6067             : 
    6068             : nla_put_failure:
    6069           0 :         return -ENOBUFS;
    6070             : }
    6071             : 
    6072             : 
    6073           0 : static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
    6074             :                                    const u8 *addr, int cmd, u16 reason_code,
    6075             :                                    int local_state_change)
    6076             : {
    6077           0 :         int ret = -1;
    6078             :         struct nl_msg *msg;
    6079             : 
    6080           0 :         msg = nlmsg_alloc();
    6081           0 :         if (!msg)
    6082           0 :                 return -1;
    6083             : 
    6084           0 :         nl80211_cmd(drv, msg, 0, cmd);
    6085             : 
    6086           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    6087           0 :         NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
    6088           0 :         if (addr)
    6089           0 :                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
    6090           0 :         if (local_state_change)
    6091           0 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
    6092             : 
    6093           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    6094           0 :         msg = NULL;
    6095           0 :         if (ret) {
    6096           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    6097             :                         "nl80211: MLME command failed: reason=%u ret=%d (%s)",
    6098             :                         reason_code, ret, strerror(-ret));
    6099           0 :                 goto nla_put_failure;
    6100             :         }
    6101           0 :         ret = 0;
    6102             : 
    6103             : nla_put_failure:
    6104           0 :         nlmsg_free(msg);
    6105           0 :         return ret;
    6106             : }
    6107             : 
    6108             : 
    6109           0 : static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
    6110             :                                          int reason_code)
    6111             : {
    6112             :         int ret;
    6113             : 
    6114           0 :         wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
    6115           0 :         nl80211_mark_disconnected(drv);
    6116             :         /* Disconnect command doesn't need BSSID - it uses cached value */
    6117           0 :         ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
    6118             :                                       reason_code, 0);
    6119             :         /*
    6120             :          * For locally generated disconnect, supplicant already generates a
    6121             :          * DEAUTH event, so ignore the event from NL80211.
    6122             :          */
    6123           0 :         drv->ignore_next_local_disconnect = ret == 0;
    6124             : 
    6125           0 :         return ret;
    6126             : }
    6127             : 
    6128             : 
    6129           0 : static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
    6130             :                                              const u8 *addr, int reason_code)
    6131             : {
    6132           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6133             :         int ret;
    6134             : 
    6135           0 :         if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
    6136           0 :                 nl80211_mark_disconnected(drv);
    6137           0 :                 return nl80211_leave_ibss(drv);
    6138             :         }
    6139           0 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
    6140           0 :                 return wpa_driver_nl80211_disconnect(drv, reason_code);
    6141           0 :         wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
    6142           0 :                    __func__, MAC2STR(addr), reason_code);
    6143           0 :         nl80211_mark_disconnected(drv);
    6144           0 :         ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
    6145             :                                       reason_code, 0);
    6146             :         /*
    6147             :          * For locally generated deauthenticate, supplicant already generates a
    6148             :          * DEAUTH event, so ignore the event from NL80211.
    6149             :          */
    6150           0 :         drv->ignore_next_local_deauth = ret == 0;
    6151           0 :         return ret;
    6152             : }
    6153             : 
    6154             : 
    6155           0 : static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
    6156             :                                      struct wpa_driver_auth_params *params)
    6157             : {
    6158             :         int i;
    6159             : 
    6160           0 :         drv->auth_freq = params->freq;
    6161           0 :         drv->auth_alg = params->auth_alg;
    6162           0 :         drv->auth_wep_tx_keyidx = params->wep_tx_keyidx;
    6163           0 :         drv->auth_local_state_change = params->local_state_change;
    6164           0 :         drv->auth_p2p = params->p2p;
    6165             : 
    6166           0 :         if (params->bssid)
    6167           0 :                 os_memcpy(drv->auth_bssid_, params->bssid, ETH_ALEN);
    6168             :         else
    6169           0 :                 os_memset(drv->auth_bssid_, 0, ETH_ALEN);
    6170             : 
    6171           0 :         if (params->ssid) {
    6172           0 :                 os_memcpy(drv->auth_ssid, params->ssid, params->ssid_len);
    6173           0 :                 drv->auth_ssid_len = params->ssid_len;
    6174             :         } else
    6175           0 :                 drv->auth_ssid_len = 0;
    6176             : 
    6177             : 
    6178           0 :         os_free(drv->auth_ie);
    6179           0 :         drv->auth_ie = NULL;
    6180           0 :         drv->auth_ie_len = 0;
    6181           0 :         if (params->ie) {
    6182           0 :                 drv->auth_ie = os_malloc(params->ie_len);
    6183           0 :                 if (drv->auth_ie) {
    6184           0 :                         os_memcpy(drv->auth_ie, params->ie, params->ie_len);
    6185           0 :                         drv->auth_ie_len = params->ie_len;
    6186             :                 }
    6187             :         }
    6188             : 
    6189           0 :         for (i = 0; i < 4; i++) {
    6190           0 :                 if (params->wep_key[i] && params->wep_key_len[i] &&
    6191           0 :                     params->wep_key_len[i] <= 16) {
    6192           0 :                         os_memcpy(drv->auth_wep_key[i], params->wep_key[i],
    6193             :                                   params->wep_key_len[i]);
    6194           0 :                         drv->auth_wep_key_len[i] = params->wep_key_len[i];
    6195             :                 } else
    6196           0 :                         drv->auth_wep_key_len[i] = 0;
    6197             :         }
    6198           0 : }
    6199             : 
    6200             : 
    6201           0 : static int wpa_driver_nl80211_authenticate(
    6202             :         struct i802_bss *bss, struct wpa_driver_auth_params *params)
    6203             : {
    6204           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    6205           0 :         int ret = -1, i;
    6206             :         struct nl_msg *msg;
    6207             :         enum nl80211_auth_type type;
    6208             :         enum nl80211_iftype nlmode;
    6209           0 :         int count = 0;
    6210             :         int is_retry;
    6211             : 
    6212           0 :         is_retry = drv->retry_auth;
    6213           0 :         drv->retry_auth = 0;
    6214           0 :         drv->ignore_deauth_event = 0;
    6215             : 
    6216           0 :         nl80211_mark_disconnected(drv);
    6217           0 :         os_memset(drv->auth_bssid, 0, ETH_ALEN);
    6218           0 :         if (params->bssid)
    6219           0 :                 os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
    6220             :         else
    6221           0 :                 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
    6222             :         /* FIX: IBSS mode */
    6223           0 :         nlmode = params->p2p ?
    6224             :                 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
    6225           0 :         if (drv->nlmode != nlmode &&
    6226           0 :             wpa_driver_nl80211_set_mode(bss, nlmode) < 0)
    6227           0 :                 return -1;
    6228             : 
    6229             : retry:
    6230           0 :         msg = nlmsg_alloc();
    6231           0 :         if (!msg)
    6232           0 :                 return -1;
    6233             : 
    6234           0 :         wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
    6235             :                    drv->ifindex);
    6236             : 
    6237           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_AUTHENTICATE);
    6238             : 
    6239           0 :         for (i = 0; i < 4; i++) {
    6240           0 :                 if (!params->wep_key[i])
    6241           0 :                         continue;
    6242           0 :                 wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
    6243             :                                            NULL, i,
    6244           0 :                                            i == params->wep_tx_keyidx, NULL, 0,
    6245             :                                            params->wep_key[i],
    6246             :                                            params->wep_key_len[i]);
    6247           0 :                 if (params->wep_tx_keyidx != i)
    6248           0 :                         continue;
    6249           0 :                 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
    6250             :                                params->wep_key[i], params->wep_key_len[i])) {
    6251           0 :                         nlmsg_free(msg);
    6252           0 :                         return -1;
    6253             :                 }
    6254             :         }
    6255             : 
    6256           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    6257           0 :         if (params->bssid) {
    6258           0 :                 wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
    6259           0 :                            MAC2STR(params->bssid));
    6260           0 :                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
    6261             :         }
    6262           0 :         if (params->freq) {
    6263           0 :                 wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
    6264           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
    6265             :         }
    6266           0 :         if (params->ssid) {
    6267           0 :                 wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
    6268           0 :                                   params->ssid, params->ssid_len);
    6269           0 :                 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
    6270             :                         params->ssid);
    6271             :         }
    6272           0 :         wpa_hexdump(MSG_DEBUG, "  * IEs", params->ie, params->ie_len);
    6273           0 :         if (params->ie)
    6274           0 :                 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
    6275           0 :         if (params->sae_data) {
    6276           0 :                 wpa_hexdump(MSG_DEBUG, "  * SAE data", params->sae_data,
    6277             :                             params->sae_data_len);
    6278           0 :                 NLA_PUT(msg, NL80211_ATTR_SAE_DATA, params->sae_data_len,
    6279             :                         params->sae_data);
    6280             :         }
    6281           0 :         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
    6282           0 :                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
    6283           0 :         else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
    6284           0 :                 type = NL80211_AUTHTYPE_SHARED_KEY;
    6285           0 :         else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
    6286           0 :                 type = NL80211_AUTHTYPE_NETWORK_EAP;
    6287           0 :         else if (params->auth_alg & WPA_AUTH_ALG_FT)
    6288           0 :                 type = NL80211_AUTHTYPE_FT;
    6289           0 :         else if (params->auth_alg & WPA_AUTH_ALG_SAE)
    6290           0 :                 type = NL80211_AUTHTYPE_SAE;
    6291             :         else
    6292           0 :                 goto nla_put_failure;
    6293           0 :         wpa_printf(MSG_DEBUG, "  * Auth Type %d", type);
    6294           0 :         NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
    6295           0 :         if (params->local_state_change) {
    6296           0 :                 wpa_printf(MSG_DEBUG, "  * Local state change only");
    6297           0 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
    6298             :         }
    6299             : 
    6300           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    6301           0 :         msg = NULL;
    6302           0 :         if (ret) {
    6303           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    6304             :                         "nl80211: MLME command failed (auth): ret=%d (%s)",
    6305             :                         ret, strerror(-ret));
    6306           0 :                 count++;
    6307           0 :                 if (ret == -EALREADY && count == 1 && params->bssid &&
    6308           0 :                     !params->local_state_change) {
    6309             :                         /*
    6310             :                          * mac80211 does not currently accept new
    6311             :                          * authentication if we are already authenticated. As a
    6312             :                          * workaround, force deauthentication and try again.
    6313             :                          */
    6314           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
    6315             :                                    "after forced deauthentication");
    6316           0 :                         drv->ignore_deauth_event = 1;
    6317           0 :                         wpa_driver_nl80211_deauthenticate(
    6318             :                                 bss, params->bssid,
    6319             :                                 WLAN_REASON_PREV_AUTH_NOT_VALID);
    6320           0 :                         nlmsg_free(msg);
    6321           0 :                         goto retry;
    6322             :                 }
    6323             : 
    6324           0 :                 if (ret == -ENOENT && params->freq && !is_retry) {
    6325             :                         /*
    6326             :                          * cfg80211 has likely expired the BSS entry even
    6327             :                          * though it was previously available in our internal
    6328             :                          * BSS table. To recover quickly, start a single
    6329             :                          * channel scan on the specified channel.
    6330             :                          */
    6331             :                         struct wpa_driver_scan_params scan;
    6332             :                         int freqs[2];
    6333             : 
    6334           0 :                         os_memset(&scan, 0, sizeof(scan));
    6335           0 :                         scan.num_ssids = 1;
    6336           0 :                         if (params->ssid) {
    6337           0 :                                 scan.ssids[0].ssid = params->ssid;
    6338           0 :                                 scan.ssids[0].ssid_len = params->ssid_len;
    6339             :                         }
    6340           0 :                         freqs[0] = params->freq;
    6341           0 :                         freqs[1] = 0;
    6342           0 :                         scan.freqs = freqs;
    6343           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Trigger single "
    6344             :                                    "channel scan to refresh cfg80211 BSS "
    6345             :                                    "entry");
    6346           0 :                         ret = wpa_driver_nl80211_scan(bss, &scan);
    6347           0 :                         if (ret == 0) {
    6348           0 :                                 nl80211_copy_auth_params(drv, params);
    6349           0 :                                 drv->scan_for_auth = 1;
    6350             :                         }
    6351           0 :                 } else if (is_retry) {
    6352             :                         /*
    6353             :                          * Need to indicate this with an event since the return
    6354             :                          * value from the retry is not delivered to core code.
    6355             :                          */
    6356             :                         union wpa_event_data event;
    6357           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Authentication retry "
    6358             :                                    "failed");
    6359           0 :                         os_memset(&event, 0, sizeof(event));
    6360           0 :                         os_memcpy(event.timeout_event.addr, drv->auth_bssid_,
    6361             :                                   ETH_ALEN);
    6362           0 :                         wpa_supplicant_event(drv->ctx, EVENT_AUTH_TIMED_OUT,
    6363             :                                              &event);
    6364             :                 }
    6365             : 
    6366           0 :                 goto nla_put_failure;
    6367             :         }
    6368           0 :         ret = 0;
    6369           0 :         wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
    6370             :                    "successfully");
    6371             : 
    6372             : nla_put_failure:
    6373           0 :         nlmsg_free(msg);
    6374           0 :         return ret;
    6375             : }
    6376             : 
    6377             : 
    6378           0 : static int wpa_driver_nl80211_authenticate_retry(
    6379             :         struct wpa_driver_nl80211_data *drv)
    6380             : {
    6381             :         struct wpa_driver_auth_params params;
    6382           0 :         struct i802_bss *bss = drv->first_bss;
    6383             :         int i;
    6384             : 
    6385           0 :         wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
    6386             : 
    6387           0 :         os_memset(&params, 0, sizeof(params));
    6388           0 :         params.freq = drv->auth_freq;
    6389           0 :         params.auth_alg = drv->auth_alg;
    6390           0 :         params.wep_tx_keyidx = drv->auth_wep_tx_keyidx;
    6391           0 :         params.local_state_change = drv->auth_local_state_change;
    6392           0 :         params.p2p = drv->auth_p2p;
    6393             : 
    6394           0 :         if (!is_zero_ether_addr(drv->auth_bssid_))
    6395           0 :                 params.bssid = drv->auth_bssid_;
    6396             : 
    6397           0 :         if (drv->auth_ssid_len) {
    6398           0 :                 params.ssid = drv->auth_ssid;
    6399           0 :                 params.ssid_len = drv->auth_ssid_len;
    6400             :         }
    6401             : 
    6402           0 :         params.ie = drv->auth_ie;
    6403           0 :         params.ie_len = drv->auth_ie_len;
    6404             : 
    6405           0 :         for (i = 0; i < 4; i++) {
    6406           0 :                 if (drv->auth_wep_key_len[i]) {
    6407           0 :                         params.wep_key[i] = drv->auth_wep_key[i];
    6408           0 :                         params.wep_key_len[i] = drv->auth_wep_key_len[i];
    6409             :                 }
    6410             :         }
    6411             : 
    6412           0 :         drv->retry_auth = 1;
    6413           0 :         return wpa_driver_nl80211_authenticate(bss, &params);
    6414             : }
    6415             : 
    6416             : 
    6417             : struct phy_info_arg {
    6418             :         u16 *num_modes;
    6419             :         struct hostapd_hw_modes *modes;
    6420             :         int last_mode, last_chan_idx;
    6421             : };
    6422             : 
    6423       26502 : static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
    6424             :                              struct nlattr *ampdu_factor,
    6425             :                              struct nlattr *ampdu_density,
    6426             :                              struct nlattr *mcs_set)
    6427             : {
    6428       26502 :         if (capa)
    6429        1262 :                 mode->ht_capab = nla_get_u16(capa);
    6430             : 
    6431       26502 :         if (ampdu_factor)
    6432        1262 :                 mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
    6433             : 
    6434       26502 :         if (ampdu_density)
    6435        1262 :                 mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
    6436             : 
    6437       26502 :         if (mcs_set && nla_len(mcs_set) >= 16) {
    6438             :                 u8 *mcs;
    6439        1262 :                 mcs = nla_data(mcs_set);
    6440        1262 :                 os_memcpy(mode->mcs_set, mcs, 16);
    6441             :         }
    6442       26502 : }
    6443             : 
    6444             : 
    6445       26502 : static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
    6446             :                               struct nlattr *capa,
    6447             :                               struct nlattr *mcs_set)
    6448             : {
    6449       26502 :         if (capa)
    6450        1262 :                 mode->vht_capab = nla_get_u32(capa);
    6451             : 
    6452       26502 :         if (mcs_set && nla_len(mcs_set) >= 8) {
    6453             :                 u8 *mcs;
    6454        1262 :                 mcs = nla_data(mcs_set);
    6455        1262 :                 os_memcpy(mode->vht_mcs_set, mcs, 8);
    6456             :         }
    6457       26502 : }
    6458             : 
    6459             : 
    6460       23978 : static void phy_info_freq(struct hostapd_hw_modes *mode,
    6461             :                           struct hostapd_channel_data *chan,
    6462             :                           struct nlattr *tb_freq[])
    6463             : {
    6464             :         u8 channel;
    6465       23978 :         chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
    6466       23978 :         chan->flag = 0;
    6467       23978 :         chan->dfs_cac_ms = 0;
    6468       23978 :         if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
    6469       23978 :                 chan->chan = channel;
    6470             : 
    6471       23978 :         if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
    6472         247 :                 chan->flag |= HOSTAPD_CHAN_DISABLED;
    6473       23978 :         if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
    6474       16555 :                 chan->flag |= HOSTAPD_CHAN_PASSIVE_SCAN | HOSTAPD_CHAN_NO_IBSS;
    6475       23978 :         if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
    6476        9465 :                 chan->flag |= HOSTAPD_CHAN_RADAR;
    6477             : 
    6478       23978 :         if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
    6479        9465 :                 enum nl80211_dfs_state state =
    6480        9465 :                         nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
    6481             : 
    6482        9465 :                 switch (state) {
    6483             :                 case NL80211_DFS_USABLE:
    6484        9465 :                         chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
    6485        9465 :                         break;
    6486             :                 case NL80211_DFS_AVAILABLE:
    6487           0 :                         chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
    6488           0 :                         break;
    6489             :                 case NL80211_DFS_UNAVAILABLE:
    6490           0 :                         chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
    6491           0 :                         break;
    6492             :                 }
    6493             :         }
    6494             : 
    6495       23978 :         if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
    6496        9465 :                 chan->dfs_cac_ms = nla_get_u32(
    6497        9465 :                         tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
    6498             :         }
    6499       23978 : }
    6500             : 
    6501             : 
    6502       26502 : static int phy_info_freqs(struct phy_info_arg *phy_info,
    6503             :                           struct hostapd_hw_modes *mode, struct nlattr *tb)
    6504             : {
    6505             :         static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
    6506             :                 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
    6507             :                 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
    6508             :                 [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
    6509             :                 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
    6510             :                 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
    6511             :                 [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
    6512             :         };
    6513       26502 :         int new_channels = 0;
    6514             :         struct hostapd_channel_data *channel;
    6515             :         struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
    6516             :         struct nlattr *nl_freq;
    6517             :         int rem_freq, idx;
    6518             : 
    6519       26502 :         if (tb == NULL)
    6520        1262 :                 return NL_OK;
    6521             : 
    6522       49218 :         nla_for_each_nested(nl_freq, tb, rem_freq) {
    6523       47956 :                 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
    6524       23978 :                           nla_data(nl_freq), nla_len(nl_freq), freq_policy);
    6525       23978 :                 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
    6526           0 :                         continue;
    6527       23978 :                 new_channels++;
    6528             :         }
    6529             : 
    6530       25240 :         channel = os_realloc_array(mode->channels,
    6531       25240 :                                    mode->num_channels + new_channels,
    6532             :                                    sizeof(struct hostapd_channel_data));
    6533       25240 :         if (!channel)
    6534           0 :                 return NL_SKIP;
    6535             : 
    6536       25240 :         mode->channels = channel;
    6537       25240 :         mode->num_channels += new_channels;
    6538             : 
    6539       25240 :         idx = phy_info->last_chan_idx;
    6540             : 
    6541       49218 :         nla_for_each_nested(nl_freq, tb, rem_freq) {
    6542       47956 :                 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
    6543       23978 :                           nla_data(nl_freq), nla_len(nl_freq), freq_policy);
    6544       23978 :                 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
    6545           0 :                         continue;
    6546       23978 :                 phy_info_freq(mode, &mode->channels[idx], tb_freq);
    6547       23978 :                 idx++;
    6548             :         }
    6549       25240 :         phy_info->last_chan_idx = idx;
    6550             : 
    6551       25240 :         return NL_OK;
    6552             : }
    6553             : 
    6554             : 
    6555       26502 : static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
    6556             : {
    6557             :         static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
    6558             :                 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
    6559             :                 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
    6560             :                 { .type = NLA_FLAG },
    6561             :         };
    6562             :         struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
    6563             :         struct nlattr *nl_rate;
    6564             :         int rem_rate, idx;
    6565             : 
    6566       26502 :         if (tb == NULL)
    6567       25240 :                 return NL_OK;
    6568             : 
    6569       13882 :         nla_for_each_nested(nl_rate, tb, rem_rate) {
    6570       25240 :                 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
    6571       12620 :                           nla_data(nl_rate), nla_len(nl_rate),
    6572             :                           rate_policy);
    6573       12620 :                 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
    6574           0 :                         continue;
    6575       12620 :                 mode->num_rates++;
    6576             :         }
    6577             : 
    6578        1262 :         mode->rates = os_calloc(mode->num_rates, sizeof(int));
    6579        1262 :         if (!mode->rates)
    6580           0 :                 return NL_SKIP;
    6581             : 
    6582        1262 :         idx = 0;
    6583             : 
    6584       13882 :         nla_for_each_nested(nl_rate, tb, rem_rate) {
    6585       25240 :                 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
    6586       12620 :                           nla_data(nl_rate), nla_len(nl_rate),
    6587             :                           rate_policy);
    6588       12620 :                 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
    6589           0 :                         continue;
    6590       12620 :                 mode->rates[idx] = nla_get_u32(
    6591             :                         tb_rate[NL80211_BITRATE_ATTR_RATE]);
    6592       12620 :                 idx++;
    6593             :         }
    6594             : 
    6595        1262 :         return NL_OK;
    6596             : }
    6597             : 
    6598             : 
    6599       26502 : static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
    6600             : {
    6601             :         struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
    6602             :         struct hostapd_hw_modes *mode;
    6603             :         int ret;
    6604             : 
    6605       26502 :         if (phy_info->last_mode != nl_band->nla_type) {
    6606        1262 :                 mode = os_realloc_array(phy_info->modes,
    6607        1262 :                                         *phy_info->num_modes + 1,
    6608             :                                         sizeof(*mode));
    6609        1262 :                 if (!mode)
    6610           0 :                         return NL_SKIP;
    6611        1262 :                 phy_info->modes = mode;
    6612             : 
    6613        1262 :                 mode = &phy_info->modes[*(phy_info->num_modes)];
    6614        1262 :                 os_memset(mode, 0, sizeof(*mode));
    6615        1262 :                 mode->mode = NUM_HOSTAPD_MODES;
    6616        1262 :                 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
    6617             :                         HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
    6618             : 
    6619             :                 /*
    6620             :                  * Unsupported VHT MCS stream is defined as value 3, so the VHT
    6621             :                  * MCS RX/TX map must be initialized with 0xffff to mark all 8
    6622             :                  * possible streams as unsupported. This will be overridden if
    6623             :                  * driver advertises VHT support.
    6624             :                  */
    6625        1262 :                 mode->vht_mcs_set[0] = 0xff;
    6626        1262 :                 mode->vht_mcs_set[1] = 0xff;
    6627        1262 :                 mode->vht_mcs_set[4] = 0xff;
    6628        1262 :                 mode->vht_mcs_set[5] = 0xff;
    6629             : 
    6630        1262 :                 *(phy_info->num_modes) += 1;
    6631        1262 :                 phy_info->last_mode = nl_band->nla_type;
    6632        1262 :                 phy_info->last_chan_idx = 0;
    6633             :         } else
    6634       25240 :                 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
    6635             : 
    6636       26502 :         nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
    6637             :                   nla_len(nl_band), NULL);
    6638             : 
    6639       26502 :         phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
    6640             :                          tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
    6641             :                          tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
    6642             :                          tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
    6643       26502 :         phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
    6644             :                           tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
    6645       26502 :         ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
    6646       26502 :         if (ret != NL_OK)
    6647           0 :                 return ret;
    6648       26502 :         ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
    6649       26502 :         if (ret != NL_OK)
    6650           0 :                 return ret;
    6651             : 
    6652       26502 :         return NL_OK;
    6653             : }
    6654             : 
    6655             : 
    6656       34074 : static int phy_info_handler(struct nl_msg *msg, void *arg)
    6657             : {
    6658             :         struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
    6659       34074 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    6660       34074 :         struct phy_info_arg *phy_info = arg;
    6661             :         struct nlattr *nl_band;
    6662             :         int rem_band;
    6663             : 
    6664       34074 :         nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    6665             :                   genlmsg_attrlen(gnlh, 0), NULL);
    6666             : 
    6667       34074 :         if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
    6668        6941 :                 return NL_SKIP;
    6669             : 
    6670       53635 :         nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
    6671             :         {
    6672       26502 :                 int res = phy_info_band(phy_info, nl_band);
    6673       26502 :                 if (res != NL_OK)
    6674           0 :                         return res;
    6675             :         }
    6676             : 
    6677       27133 :         return NL_SKIP;
    6678             : }
    6679             : 
    6680             : 
    6681             : static struct hostapd_hw_modes *
    6682         631 : wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
    6683             :                                      u16 *num_modes)
    6684             : {
    6685             :         u16 m;
    6686         631 :         struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
    6687         631 :         int i, mode11g_idx = -1;
    6688             : 
    6689             :         /* heuristic to set up modes */
    6690        1893 :         for (m = 0; m < *num_modes; m++) {
    6691        1262 :                 if (!modes[m].num_channels)
    6692           0 :                         continue;
    6693        1262 :                 if (modes[m].channels[0].freq < 4000) {
    6694         631 :                         modes[m].mode = HOSTAPD_MODE_IEEE80211B;
    6695        5679 :                         for (i = 0; i < modes[m].num_rates; i++) {
    6696        5679 :                                 if (modes[m].rates[i] > 200) {
    6697         631 :                                         modes[m].mode = HOSTAPD_MODE_IEEE80211G;
    6698         631 :                                         break;
    6699             :                                 }
    6700             :                         }
    6701         631 :                 } else if (modes[m].channels[0].freq > 50000)
    6702           0 :                         modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
    6703             :                 else
    6704         631 :                         modes[m].mode = HOSTAPD_MODE_IEEE80211A;
    6705             :         }
    6706             : 
    6707             :         /* If only 802.11g mode is included, use it to construct matching
    6708             :          * 802.11b mode data. */
    6709             : 
    6710        1893 :         for (m = 0; m < *num_modes; m++) {
    6711        1262 :                 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
    6712           0 :                         return modes; /* 802.11b already included */
    6713        1262 :                 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
    6714         631 :                         mode11g_idx = m;
    6715             :         }
    6716             : 
    6717         631 :         if (mode11g_idx < 0)
    6718           0 :                 return modes; /* 2.4 GHz band not supported at all */
    6719             : 
    6720         631 :         nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
    6721         631 :         if (nmodes == NULL)
    6722           0 :                 return modes; /* Could not add 802.11b mode */
    6723             : 
    6724         631 :         mode = &nmodes[*num_modes];
    6725         631 :         os_memset(mode, 0, sizeof(*mode));
    6726         631 :         (*num_modes)++;
    6727         631 :         modes = nmodes;
    6728             : 
    6729         631 :         mode->mode = HOSTAPD_MODE_IEEE80211B;
    6730             : 
    6731         631 :         mode11g = &modes[mode11g_idx];
    6732         631 :         mode->num_channels = mode11g->num_channels;
    6733         631 :         mode->channels = os_malloc(mode11g->num_channels *
    6734             :                                    sizeof(struct hostapd_channel_data));
    6735         631 :         if (mode->channels == NULL) {
    6736           0 :                 (*num_modes)--;
    6737           0 :                 return modes; /* Could not add 802.11b mode */
    6738             :         }
    6739         631 :         os_memcpy(mode->channels, mode11g->channels,
    6740             :                   mode11g->num_channels * sizeof(struct hostapd_channel_data));
    6741             : 
    6742         631 :         mode->num_rates = 0;
    6743         631 :         mode->rates = os_malloc(4 * sizeof(int));
    6744         631 :         if (mode->rates == NULL) {
    6745           0 :                 os_free(mode->channels);
    6746           0 :                 (*num_modes)--;
    6747           0 :                 return modes; /* Could not add 802.11b mode */
    6748             :         }
    6749             : 
    6750        2524 :         for (i = 0; i < mode11g->num_rates; i++) {
    6751        3786 :                 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
    6752        1893 :                     mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
    6753           0 :                         continue;
    6754        2524 :                 mode->rates[mode->num_rates] = mode11g->rates[i];
    6755        2524 :                 mode->num_rates++;
    6756        2524 :                 if (mode->num_rates == 4)
    6757         631 :                         break;
    6758             :         }
    6759             : 
    6760         631 :         if (mode->num_rates == 0) {
    6761           0 :                 os_free(mode->channels);
    6762           0 :                 os_free(mode->rates);
    6763           0 :                 (*num_modes)--;
    6764           0 :                 return modes; /* No 802.11b rates */
    6765             :         }
    6766             : 
    6767         631 :         wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
    6768             :                    "information");
    6769             : 
    6770         631 :         return modes;
    6771             : }
    6772             : 
    6773             : 
    6774        8728 : static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
    6775             :                                   int end)
    6776             : {
    6777             :         int c;
    6778             : 
    6779      174560 :         for (c = 0; c < mode->num_channels; c++) {
    6780      165832 :                 struct hostapd_channel_data *chan = &mode->channels[c];
    6781      165832 :                 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
    6782       23119 :                         chan->flag |= HOSTAPD_CHAN_HT40;
    6783             :         }
    6784        8728 : }
    6785             : 
    6786             : 
    6787        9942 : static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
    6788             :                                       int end)
    6789             : {
    6790             :         int c;
    6791             : 
    6792      198840 :         for (c = 0; c < mode->num_channels; c++) {
    6793      188898 :                 struct hostapd_channel_data *chan = &mode->channels[c];
    6794      188898 :                 if (!(chan->flag & HOSTAPD_CHAN_HT40))
    6795        6146 :                         continue;
    6796      182752 :                 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
    6797       18732 :                         chan->flag |= HOSTAPD_CHAN_HT40MINUS;
    6798      182752 :                 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
    6799       19335 :                         chan->flag |= HOSTAPD_CHAN_HT40PLUS;
    6800             :         }
    6801        9942 : }
    6802             : 
    6803             : 
    6804        4971 : static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
    6805             :                                       struct phy_info_arg *results)
    6806             : {
    6807             :         u16 m;
    6808             : 
    6809       14913 :         for (m = 0; m < *results->num_modes; m++) {
    6810             :                 int c;
    6811        9942 :                 struct hostapd_hw_modes *mode = &results->modes[m];
    6812             : 
    6813      198840 :                 for (c = 0; c < mode->num_channels; c++) {
    6814      188898 :                         struct hostapd_channel_data *chan = &mode->channels[c];
    6815      285257 :                         if ((u32) chan->freq - 10 >= start &&
    6816       96359 :                             (u32) chan->freq + 10 <= end)
    6817       23726 :                                 chan->max_tx_power = max_eirp;
    6818             :                 }
    6819             :         }
    6820        4971 : }
    6821             : 
    6822             : 
    6823        4364 : static void nl80211_reg_rule_ht40(u32 start, u32 end,
    6824             :                                   struct phy_info_arg *results)
    6825             : {
    6826             :         u16 m;
    6827             : 
    6828       13092 :         for (m = 0; m < *results->num_modes; m++) {
    6829        8728 :                 if (!(results->modes[m].ht_capab &
    6830             :                       HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
    6831           0 :                         continue;
    6832        8728 :                 nl80211_set_ht40_mode(&results->modes[m], start, end);
    6833             :         }
    6834        4364 : }
    6835             : 
    6836             : 
    6837        4971 : static void nl80211_reg_rule_sec(struct nlattr *tb[],
    6838             :                                  struct phy_info_arg *results)
    6839             : {
    6840             :         u32 start, end, max_bw;
    6841             :         u16 m;
    6842             : 
    6843        9942 :         if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
    6844        9942 :             tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
    6845        4971 :             tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
    6846           0 :                 return;
    6847             : 
    6848        4971 :         start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
    6849        4971 :         end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
    6850        4971 :         max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
    6851             : 
    6852        4971 :         if (max_bw < 20)
    6853           0 :                 return;
    6854             : 
    6855       14913 :         for (m = 0; m < *results->num_modes; m++) {
    6856        9942 :                 if (!(results->modes[m].ht_capab &
    6857             :                       HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
    6858           0 :                         continue;
    6859        9942 :                 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
    6860             :         }
    6861             : }
    6862             : 
    6863             : 
    6864        6246 : static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
    6865             :                                  int end)
    6866             : {
    6867             :         int c;
    6868             : 
    6869      124920 :         for (c = 0; c < mode->num_channels; c++) {
    6870      118674 :                 struct hostapd_channel_data *chan = &mode->channels[c];
    6871      118674 :                 if (chan->freq - 10 >= start && chan->freq + 70 <= end)
    6872        8055 :                         chan->flag |= HOSTAPD_CHAN_VHT_10_70;
    6873             : 
    6874      118674 :                 if (chan->freq - 30 >= start && chan->freq + 50 <= end)
    6875        8057 :                         chan->flag |= HOSTAPD_CHAN_VHT_30_50;
    6876             : 
    6877      118674 :                 if (chan->freq - 50 >= start && chan->freq + 30 <= end)
    6878        8057 :                         chan->flag |= HOSTAPD_CHAN_VHT_50_30;
    6879             : 
    6880      118674 :                 if (chan->freq - 70 >= start && chan->freq + 10 <= end)
    6881        7452 :                         chan->flag |= HOSTAPD_CHAN_VHT_70_10;
    6882             :         }
    6883        6246 : }
    6884             : 
    6885             : 
    6886        4971 : static void nl80211_reg_rule_vht(struct nlattr *tb[],
    6887             :                                  struct phy_info_arg *results)
    6888             : {
    6889             :         u32 start, end, max_bw;
    6890             :         u16 m;
    6891             : 
    6892        9942 :         if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
    6893        9942 :             tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
    6894        4971 :             tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
    6895           0 :                 return;
    6896             : 
    6897        4971 :         start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
    6898        4971 :         end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
    6899        4971 :         max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
    6900             : 
    6901        4971 :         if (max_bw < 80)
    6902        1848 :                 return;
    6903             : 
    6904        9369 :         for (m = 0; m < *results->num_modes; m++) {
    6905        6246 :                 if (!(results->modes[m].ht_capab &
    6906             :                       HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
    6907           0 :                         continue;
    6908             :                 /* TODO: use a real VHT support indication */
    6909        6246 :                 if (!results->modes[m].vht_capab)
    6910           0 :                         continue;
    6911             : 
    6912        6246 :                 nl80211_set_vht_mode(&results->modes[m], start, end);
    6913             :         }
    6914             : }
    6915             : 
    6916             : 
    6917          27 : static const char * dfs_domain_name(enum nl80211_dfs_regions region)
    6918             : {
    6919          27 :         switch (region) {
    6920             :         case NL80211_DFS_UNSET:
    6921           0 :                 return "DFS-UNSET";
    6922             :         case NL80211_DFS_FCC:
    6923          11 :                 return "DFS-FCC";
    6924             :         case NL80211_DFS_ETSI:
    6925          13 :                 return "DFS-ETSI";
    6926             :         case NL80211_DFS_JP:
    6927           3 :                 return "DFS-JP";
    6928             :         default:
    6929           0 :                 return "DFS-invalid";
    6930             :         }
    6931             : }
    6932             : 
    6933             : 
    6934         631 : static int nl80211_get_reg(struct nl_msg *msg, void *arg)
    6935             : {
    6936         631 :         struct phy_info_arg *results = arg;
    6937             :         struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
    6938         631 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    6939             :         struct nlattr *nl_rule;
    6940             :         struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
    6941             :         int rem_rule;
    6942             :         static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
    6943             :                 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
    6944             :                 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
    6945             :                 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
    6946             :                 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
    6947             :                 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
    6948             :                 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
    6949             :         };
    6950             : 
    6951         631 :         nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    6952             :                   genlmsg_attrlen(gnlh, 0), NULL);
    6953        1262 :         if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
    6954         631 :             !tb_msg[NL80211_ATTR_REG_RULES]) {
    6955           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
    6956             :                            "available");
    6957           0 :                 return NL_SKIP;
    6958             :         }
    6959             : 
    6960         631 :         if (tb_msg[NL80211_ATTR_DFS_REGION]) {
    6961             :                 enum nl80211_dfs_regions dfs_domain;
    6962          27 :                 dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
    6963          54 :                 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
    6964          27 :                            (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
    6965             :                            dfs_domain_name(dfs_domain));
    6966             :         } else {
    6967         604 :                 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
    6968         604 :                            (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
    6969             :         }
    6970             : 
    6971        5602 :         nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
    6972             :         {
    6973        4971 :                 u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
    6974        9942 :                 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
    6975        4971 :                           nla_data(nl_rule), nla_len(nl_rule), reg_policy);
    6976        9942 :                 if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
    6977        4971 :                     tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
    6978           0 :                         continue;
    6979        4971 :                 start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
    6980        4971 :                 end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
    6981        4971 :                 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
    6982        4971 :                         max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
    6983        4971 :                 if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
    6984        4971 :                         max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
    6985        4971 :                 if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
    6986        4971 :                         flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
    6987             : 
    6988       39768 :                 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
    6989             :                            start, end, max_bw, max_eirp,
    6990        4971 :                            flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
    6991        4971 :                            flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
    6992        4971 :                            flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
    6993        4971 :                            flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
    6994             :                            "",
    6995        4971 :                            flags & NL80211_RRF_DFS ? " (DFS)" : "",
    6996        4971 :                            flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
    6997        4971 :                            flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
    6998        4971 :                            flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
    6999        4971 :                 if (max_bw >= 40)
    7000        4364 :                         nl80211_reg_rule_ht40(start, end, results);
    7001        4971 :                 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
    7002        4971 :                         nl80211_reg_rule_max_eirp(start, end, max_eirp,
    7003             :                                                   results);
    7004             :         }
    7005             : 
    7006        5602 :         nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
    7007             :         {
    7008        9942 :                 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
    7009        4971 :                           nla_data(nl_rule), nla_len(nl_rule), reg_policy);
    7010        4971 :                 nl80211_reg_rule_sec(tb_rule, results);
    7011             :         }
    7012             : 
    7013        5602 :         nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
    7014             :         {
    7015        9942 :                 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
    7016        4971 :                           nla_data(nl_rule), nla_len(nl_rule), reg_policy);
    7017        4971 :                 nl80211_reg_rule_vht(tb_rule, results);
    7018             :         }
    7019             : 
    7020         631 :         return NL_SKIP;
    7021             : }
    7022             : 
    7023             : 
    7024         631 : static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
    7025             :                                         struct phy_info_arg *results)
    7026             : {
    7027             :         struct nl_msg *msg;
    7028             : 
    7029         631 :         msg = nlmsg_alloc();
    7030         631 :         if (!msg)
    7031           0 :                 return -ENOMEM;
    7032             : 
    7033         631 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
    7034         631 :         return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
    7035             : }
    7036             : 
    7037             : 
    7038             : static struct hostapd_hw_modes *
    7039         631 : wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
    7040             : {
    7041             :         u32 feat;
    7042         631 :         struct i802_bss *bss = priv;
    7043         631 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7044             :         struct nl_msg *msg;
    7045         631 :         struct phy_info_arg result = {
    7046             :                 .num_modes = num_modes,
    7047             :                 .modes = NULL,
    7048             :                 .last_mode = -1,
    7049             :         };
    7050             : 
    7051         631 :         *num_modes = 0;
    7052         631 :         *flags = 0;
    7053             : 
    7054         631 :         msg = nlmsg_alloc();
    7055         631 :         if (!msg)
    7056           0 :                 return NULL;
    7057             : 
    7058         631 :         feat = get_nl80211_protocol_features(drv);
    7059         631 :         if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
    7060         631 :                 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_WIPHY);
    7061             :         else
    7062           0 :                 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
    7063             : 
    7064         631 :         NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
    7065         631 :         if (nl80211_set_iface_id(msg, bss) < 0)
    7066           0 :                 goto nla_put_failure;
    7067             : 
    7068         631 :         if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
    7069         631 :                 nl80211_set_regulatory_flags(drv, &result);
    7070         631 :                 return wpa_driver_nl80211_postprocess_modes(result.modes,
    7071             :                                                             num_modes);
    7072             :         }
    7073           0 :         msg = NULL;
    7074             :  nla_put_failure:
    7075           0 :         nlmsg_free(msg);
    7076           0 :         return NULL;
    7077             : }
    7078             : 
    7079             : 
    7080           0 : static int wpa_driver_nl80211_send_mntr(struct wpa_driver_nl80211_data *drv,
    7081             :                                         const void *data, size_t len,
    7082             :                                         int encrypt, int noack)
    7083             : {
    7084           0 :         __u8 rtap_hdr[] = {
    7085             :                 0x00, 0x00, /* radiotap version */
    7086             :                 0x0e, 0x00, /* radiotap length */
    7087             :                 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
    7088             :                 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
    7089             :                 0x00,       /* padding */
    7090             :                 0x00, 0x00, /* RX and TX flags to indicate that */
    7091             :                 0x00, 0x00, /* this is the injected frame directly */
    7092             :         };
    7093           0 :         struct iovec iov[2] = {
    7094             :                 {
    7095             :                         .iov_base = &rtap_hdr,
    7096             :                         .iov_len = sizeof(rtap_hdr),
    7097             :                 },
    7098             :                 {
    7099             :                         .iov_base = (void *) data,
    7100             :                         .iov_len = len,
    7101             :                 }
    7102             :         };
    7103           0 :         struct msghdr msg = {
    7104             :                 .msg_name = NULL,
    7105             :                 .msg_namelen = 0,
    7106             :                 .msg_iov = iov,
    7107             :                 .msg_iovlen = 2,
    7108             :                 .msg_control = NULL,
    7109             :                 .msg_controllen = 0,
    7110             :                 .msg_flags = 0,
    7111             :         };
    7112             :         int res;
    7113           0 :         u16 txflags = 0;
    7114             : 
    7115           0 :         if (encrypt)
    7116           0 :                 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
    7117             : 
    7118           0 :         if (drv->monitor_sock < 0) {
    7119           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No monitor socket available "
    7120             :                            "for %s", __func__);
    7121           0 :                 return -1;
    7122             :         }
    7123             : 
    7124           0 :         if (noack)
    7125           0 :                 txflags |= IEEE80211_RADIOTAP_F_TX_NOACK;
    7126           0 :         WPA_PUT_LE16(&rtap_hdr[12], txflags);
    7127             : 
    7128           0 :         res = sendmsg(drv->monitor_sock, &msg, 0);
    7129           0 :         if (res < 0) {
    7130           0 :                 wpa_printf(MSG_INFO, "nl80211: sendmsg: %s", strerror(errno));
    7131           0 :                 return -1;
    7132             :         }
    7133           0 :         return 0;
    7134             : }
    7135             : 
    7136             : 
    7137        6022 : static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
    7138             :                                          const void *data, size_t len,
    7139             :                                          int encrypt, int noack,
    7140             :                                          unsigned int freq, int no_cck,
    7141             :                                          int offchanok, unsigned int wait_time)
    7142             : {
    7143        6022 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7144             :         u64 cookie;
    7145             :         int res;
    7146             : 
    7147        6022 :         if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
    7148           0 :                 freq = nl80211_get_assoc_freq(drv);
    7149           0 :                 wpa_printf(MSG_DEBUG,
    7150             :                            "nl80211: send_frame - Use assoc_freq=%u for IBSS",
    7151             :                            freq);
    7152             :         }
    7153        6022 :         if (freq == 0) {
    7154        5783 :                 wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
    7155             :                            bss->freq);
    7156        5783 :                 freq = bss->freq;
    7157             :         }
    7158             : 
    7159        6022 :         if (drv->use_monitor) {
    7160           0 :                 wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_mntr",
    7161             :                            freq, bss->freq);
    7162           0 :                 return wpa_driver_nl80211_send_mntr(drv, data, len,
    7163             :                                                     encrypt, noack);
    7164             :         }
    7165             : 
    7166        6022 :         wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
    7167        6022 :         res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
    7168             :                                      &cookie, no_cck, noack, offchanok);
    7169        6022 :         if (res == 0 && !noack) {
    7170             :                 const struct ieee80211_mgmt *mgmt;
    7171             :                 u16 fc;
    7172             : 
    7173        4134 :                 mgmt = (const struct ieee80211_mgmt *) data;
    7174        4134 :                 fc = le_to_host16(mgmt->frame_control);
    7175        8268 :                 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    7176        4134 :                     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
    7177        1226 :                         wpa_printf(MSG_MSGDUMP,
    7178             :                                    "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
    7179             :                                    (long long unsigned int)
    7180         613 :                                    drv->send_action_cookie,
    7181             :                                    (long long unsigned int) cookie);
    7182         613 :                         drv->send_action_cookie = cookie;
    7183             :                 }
    7184             :         }
    7185             : 
    7186        6022 :         return res;
    7187             : }
    7188             : 
    7189             : 
    7190        6020 : static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
    7191             :                                         size_t data_len, int noack,
    7192             :                                         unsigned int freq, int no_cck,
    7193             :                                         int offchanok,
    7194             :                                         unsigned int wait_time)
    7195             : {
    7196        6020 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7197             :         struct ieee80211_mgmt *mgmt;
    7198        6020 :         int encrypt = 1;
    7199             :         u16 fc;
    7200             : 
    7201        6020 :         mgmt = (struct ieee80211_mgmt *) data;
    7202        6020 :         fc = le_to_host16(mgmt->frame_control);
    7203       42140 :         wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da= " MACSTR
    7204             :                    " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x (%s) nlmode=%d",
    7205       36120 :                    MAC2STR(mgmt->da), noack, freq, no_cck, offchanok, wait_time,
    7206        6020 :                    fc, fc2str(fc), drv->nlmode);
    7207             : 
    7208       12040 :         if ((is_sta_interface(drv->nlmode) ||
    7209        6020 :              drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
    7210           0 :             WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    7211           0 :             WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
    7212             :                 /*
    7213             :                  * The use of last_mgmt_freq is a bit of a hack,
    7214             :                  * but it works due to the single-threaded nature
    7215             :                  * of wpa_supplicant.
    7216             :                  */
    7217           0 :                 if (freq == 0) {
    7218           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
    7219             :                                    drv->last_mgmt_freq);
    7220           0 :                         freq = drv->last_mgmt_freq;
    7221             :                 }
    7222           0 :                 return nl80211_send_frame_cmd(bss, freq, 0,
    7223             :                                               data, data_len, NULL, 1, noack,
    7224             :                                               1);
    7225             :         }
    7226             : 
    7227        6020 :         if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
    7228           0 :                 if (freq == 0) {
    7229           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
    7230             :                                    bss->freq);
    7231           0 :                         freq = bss->freq;
    7232             :                 }
    7233           0 :                 return nl80211_send_frame_cmd(bss, freq,
    7234           0 :                                               (int) freq == bss->freq ? 0 :
    7235             :                                               wait_time,
    7236             :                                               data, data_len,
    7237             :                                               &drv->send_action_cookie,
    7238             :                                               no_cck, noack, offchanok);
    7239             :         }
    7240             : 
    7241       12040 :         if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    7242        6020 :             WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
    7243             :                 /*
    7244             :                  * Only one of the authentication frame types is encrypted.
    7245             :                  * In order for static WEP encryption to work properly (i.e.,
    7246             :                  * to not encrypt the frame), we need to tell mac80211 about
    7247             :                  * the frames that must not be encrypted.
    7248             :                  */
    7249        1250 :                 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
    7250        1250 :                 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
    7251        1250 :                 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
    7252        1250 :                         encrypt = 0;
    7253             :         }
    7254             : 
    7255        6020 :         wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
    7256        6020 :         return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
    7257             :                                              noack, freq, no_cck, offchanok,
    7258             :                                              wait_time);
    7259             : }
    7260             : 
    7261             : 
    7262         866 : static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
    7263             :                            int slot, int ht_opmode, int ap_isolate,
    7264             :                            int *basic_rates)
    7265             : {
    7266         866 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7267             :         struct nl_msg *msg;
    7268             : 
    7269         866 :         msg = nlmsg_alloc();
    7270         866 :         if (!msg)
    7271           0 :                 return -ENOMEM;
    7272             : 
    7273         866 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_BSS);
    7274             : 
    7275         866 :         if (cts >= 0)
    7276         866 :                 NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
    7277         866 :         if (preamble >= 0)
    7278         866 :                 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
    7279         866 :         if (slot >= 0)
    7280         831 :                 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
    7281         866 :         if (ht_opmode >= 0)
    7282         818 :                 NLA_PUT_U16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode);
    7283         866 :         if (ap_isolate >= 0)
    7284         866 :                 NLA_PUT_U8(msg, NL80211_ATTR_AP_ISOLATE, ap_isolate);
    7285             : 
    7286         866 :         if (basic_rates) {
    7287             :                 u8 rates[NL80211_MAX_SUPP_RATES];
    7288         866 :                 u8 rates_len = 0;
    7289             :                 int i;
    7290             : 
    7291        5161 :                 for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0;
    7292        3429 :                      i++)
    7293        3429 :                         rates[rates_len++] = basic_rates[i] / 5;
    7294             : 
    7295         866 :                 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
    7296             :         }
    7297             : 
    7298         866 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
    7299             : 
    7300         866 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    7301             :  nla_put_failure:
    7302           0 :         nlmsg_free(msg);
    7303           0 :         return -ENOBUFS;
    7304             : }
    7305             : 
    7306             : 
    7307           0 : static int wpa_driver_nl80211_set_acl(void *priv,
    7308             :                                       struct hostapd_acl_params *params)
    7309             : {
    7310           0 :         struct i802_bss *bss = priv;
    7311           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7312             :         struct nl_msg *msg;
    7313             :         struct nlattr *acl;
    7314             :         unsigned int i;
    7315           0 :         int ret = 0;
    7316             : 
    7317           0 :         if (!(drv->capa.max_acl_mac_addrs))
    7318           0 :                 return -ENOTSUP;
    7319             : 
    7320           0 :         if (params->num_mac_acl > drv->capa.max_acl_mac_addrs)
    7321           0 :                 return -ENOTSUP;
    7322             : 
    7323           0 :         msg = nlmsg_alloc();
    7324           0 :         if (!msg)
    7325           0 :                 return -ENOMEM;
    7326             : 
    7327           0 :         wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
    7328           0 :                    params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
    7329             : 
    7330           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_MAC_ACL);
    7331             : 
    7332           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    7333             : 
    7334           0 :         NLA_PUT_U32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
    7335             :                     NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
    7336             :                     NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED);
    7337             : 
    7338           0 :         acl = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
    7339           0 :         if (acl == NULL)
    7340           0 :                 goto nla_put_failure;
    7341             : 
    7342           0 :         for (i = 0; i < params->num_mac_acl; i++)
    7343           0 :                 NLA_PUT(msg, i + 1, ETH_ALEN, params->mac_acl[i].addr);
    7344             : 
    7345           0 :         nla_nest_end(msg, acl);
    7346             : 
    7347           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7348           0 :         msg = NULL;
    7349           0 :         if (ret) {
    7350           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to set MAC ACL: %d (%s)",
    7351             :                            ret, strerror(-ret));
    7352             :         }
    7353             : 
    7354             : nla_put_failure:
    7355           0 :         nlmsg_free(msg);
    7356             : 
    7357           0 :         return ret;
    7358             : }
    7359             : 
    7360             : 
    7361         866 : static int wpa_driver_nl80211_set_ap(void *priv,
    7362             :                                      struct wpa_driver_ap_params *params)
    7363             : {
    7364         866 :         struct i802_bss *bss = priv;
    7365         866 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7366             :         struct nl_msg *msg;
    7367         866 :         u8 cmd = NL80211_CMD_NEW_BEACON;
    7368             :         int ret;
    7369             :         int beacon_set;
    7370         866 :         int ifindex = if_nametoindex(bss->ifname);
    7371             :         int num_suites;
    7372             :         u32 suites[10], suite;
    7373             :         u32 ver;
    7374             : 
    7375         866 :         beacon_set = bss->beacon_set;
    7376             : 
    7377         866 :         msg = nlmsg_alloc();
    7378         866 :         if (!msg)
    7379           0 :                 return -ENOMEM;
    7380             : 
    7381         866 :         wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
    7382             :                    beacon_set);
    7383         866 :         if (beacon_set)
    7384         233 :                 cmd = NL80211_CMD_SET_BEACON;
    7385             : 
    7386         866 :         nl80211_cmd(drv, msg, 0, cmd);
    7387        1732 :         wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
    7388         866 :                     params->head, params->head_len);
    7389         866 :         NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, params->head_len, params->head);
    7390        1732 :         wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
    7391         866 :                     params->tail, params->tail_len);
    7392         866 :         NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len, params->tail);
    7393         866 :         wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", ifindex);
    7394         866 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
    7395         866 :         wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
    7396         866 :         NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
    7397         866 :         wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
    7398         866 :         NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
    7399        1732 :         wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
    7400         866 :                           params->ssid, params->ssid_len);
    7401         866 :         NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
    7402             :                 params->ssid);
    7403         866 :         if (params->proberesp && params->proberesp_len) {
    7404           0 :                 wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
    7405           0 :                             params->proberesp, params->proberesp_len);
    7406           0 :                 NLA_PUT(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
    7407             :                         params->proberesp);
    7408             :         }
    7409         866 :         switch (params->hide_ssid) {
    7410             :         case NO_SSID_HIDING:
    7411         862 :                 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
    7412         862 :                 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
    7413             :                             NL80211_HIDDEN_SSID_NOT_IN_USE);
    7414         862 :                 break;
    7415             :         case HIDDEN_SSID_ZERO_LEN:
    7416           3 :                 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
    7417           3 :                 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
    7418             :                             NL80211_HIDDEN_SSID_ZERO_LEN);
    7419           3 :                 break;
    7420             :         case HIDDEN_SSID_ZERO_CONTENTS:
    7421           1 :                 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
    7422           1 :                 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
    7423             :                             NL80211_HIDDEN_SSID_ZERO_CONTENTS);
    7424           1 :                 break;
    7425             :         }
    7426         866 :         wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
    7427         866 :         if (params->privacy)
    7428         629 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
    7429         866 :         wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
    7430         866 :         if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
    7431             :             (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
    7432             :                 /* Leave out the attribute */
    7433          58 :         } else if (params->auth_algs & WPA_AUTH_ALG_SHARED)
    7434           3 :                 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
    7435             :                             NL80211_AUTHTYPE_SHARED_KEY);
    7436             :         else
    7437          55 :                 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
    7438             :                             NL80211_AUTHTYPE_OPEN_SYSTEM);
    7439             : 
    7440         866 :         wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
    7441         866 :         ver = 0;
    7442         866 :         if (params->wpa_version & WPA_PROTO_WPA)
    7443          71 :                 ver |= NL80211_WPA_VERSION_1;
    7444         866 :         if (params->wpa_version & WPA_PROTO_RSN)
    7445         591 :                 ver |= NL80211_WPA_VERSION_2;
    7446         866 :         if (ver)
    7447         616 :                 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
    7448             : 
    7449         866 :         wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
    7450             :                    params->key_mgmt_suites);
    7451         866 :         num_suites = 0;
    7452         866 :         if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
    7453         243 :                 suites[num_suites++] = WLAN_AKM_SUITE_8021X;
    7454         866 :         if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
    7455         576 :                 suites[num_suites++] = WLAN_AKM_SUITE_PSK;
    7456         866 :         if (num_suites) {
    7457         819 :                 NLA_PUT(msg, NL80211_ATTR_AKM_SUITES,
    7458             :                         num_suites * sizeof(u32), suites);
    7459             :         }
    7460             : 
    7461        1109 :         if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X &&
    7462         243 :             params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40))
    7463           0 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT);
    7464             : 
    7465         866 :         wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
    7466             :                    params->pairwise_ciphers);
    7467         866 :         num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
    7468             :                                                  suites, ARRAY_SIZE(suites));
    7469         866 :         if (num_suites) {
    7470         631 :                 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
    7471             :                         num_suites * sizeof(u32), suites);
    7472             :         }
    7473             : 
    7474         866 :         wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
    7475             :                    params->group_cipher);
    7476         866 :         suite = wpa_cipher_to_cipher_suite(params->group_cipher);
    7477         866 :         if (suite)
    7478         631 :                 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite);
    7479             : 
    7480         866 :         if (params->beacon_ies) {
    7481         866 :                 wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
    7482             :                                 params->beacon_ies);
    7483         866 :                 NLA_PUT(msg, NL80211_ATTR_IE, wpabuf_len(params->beacon_ies),
    7484             :                         wpabuf_head(params->beacon_ies));
    7485             :         }
    7486         866 :         if (params->proberesp_ies) {
    7487         866 :                 wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
    7488             :                                 params->proberesp_ies);
    7489         866 :                 NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
    7490             :                         wpabuf_len(params->proberesp_ies),
    7491             :                         wpabuf_head(params->proberesp_ies));
    7492             :         }
    7493         866 :         if (params->assocresp_ies) {
    7494         866 :                 wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
    7495             :                                 params->assocresp_ies);
    7496         866 :                 NLA_PUT(msg, NL80211_ATTR_IE_ASSOC_RESP,
    7497             :                         wpabuf_len(params->assocresp_ies),
    7498             :                         wpabuf_head(params->assocresp_ies));
    7499             :         }
    7500             : 
    7501         866 :         if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)  {
    7502           0 :                 wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
    7503             :                            params->ap_max_inactivity);
    7504           0 :                 NLA_PUT_U16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
    7505             :                             params->ap_max_inactivity);
    7506             :         }
    7507             : 
    7508         866 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7509         866 :         if (ret) {
    7510           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
    7511             :                            ret, strerror(-ret));
    7512             :         } else {
    7513         866 :                 bss->beacon_set = 1;
    7514         866 :                 nl80211_set_bss(bss, params->cts_protect, params->preamble,
    7515             :                                 params->short_slot_time, params->ht_opmode,
    7516             :                                 params->isolate, params->basic_rates);
    7517        1099 :                 if (beacon_set && params->freq &&
    7518         233 :                     params->freq->bandwidth != bss->bandwidth) {
    7519          18 :                         wpa_printf(MSG_DEBUG,
    7520             :                                    "nl80211: Update BSS %s bandwidth: %d -> %d",
    7521           9 :                                    bss->ifname, bss->bandwidth,
    7522           9 :                                    params->freq->bandwidth);
    7523           9 :                         ret = nl80211_set_channel(bss, params->freq, 1);
    7524          18 :                         if (ret) {
    7525           0 :                                 wpa_printf(MSG_DEBUG,
    7526             :                                            "nl80211: Frequency set failed: %d (%s)",
    7527             :                                            ret, strerror(-ret));
    7528             :                         } else {
    7529           9 :                                 wpa_printf(MSG_DEBUG,
    7530             :                                            "nl80211: Frequency set succeeded for ht2040 coex");
    7531           9 :                                 bss->bandwidth = params->freq->bandwidth;
    7532             :                         }
    7533         857 :                 } else if (!beacon_set) {
    7534             :                         /*
    7535             :                          * cfg80211 updates the driver on frequence change in AP
    7536             :                          * mode only at the point when beaconing is started, so
    7537             :                          * set the initial value here.
    7538             :                          */
    7539         633 :                         bss->bandwidth = params->freq->bandwidth;
    7540             :                 }
    7541             :         }
    7542         866 :         return ret;
    7543             :  nla_put_failure:
    7544           0 :         nlmsg_free(msg);
    7545           0 :         return -ENOBUFS;
    7546             : }
    7547             : 
    7548             : 
    7549         635 : static int nl80211_put_freq_params(struct nl_msg *msg,
    7550             :                                    struct hostapd_freq_params *freq)
    7551             : {
    7552         635 :         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq);
    7553         635 :         if (freq->vht_enabled) {
    7554          10 :                 switch (freq->bandwidth) {
    7555             :                 case 20:
    7556           1 :                         NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
    7557             :                                     NL80211_CHAN_WIDTH_20);
    7558           1 :                         break;
    7559             :                 case 40:
    7560           0 :                         NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
    7561             :                                     NL80211_CHAN_WIDTH_40);
    7562           0 :                         break;
    7563             :                 case 80:
    7564           4 :                         if (freq->center_freq2)
    7565           2 :                                 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
    7566             :                                             NL80211_CHAN_WIDTH_80P80);
    7567             :                         else
    7568           2 :                                 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
    7569             :                                             NL80211_CHAN_WIDTH_80);
    7570           4 :                         break;
    7571             :                 case 160:
    7572           4 :                         NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
    7573             :                                     NL80211_CHAN_WIDTH_160);
    7574           4 :                         break;
    7575             :                 default:
    7576           1 :                         return -EINVAL;
    7577             :                 }
    7578           9 :                 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1);
    7579           9 :                 if (freq->center_freq2)
    7580           2 :                         NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2,
    7581             :                                     freq->center_freq2);
    7582         625 :         } else if (freq->ht_enabled) {
    7583         620 :                 switch (freq->sec_channel_offset) {
    7584             :                 case -1:
    7585          12 :                         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
    7586             :                                     NL80211_CHAN_HT40MINUS);
    7587          12 :                         break;
    7588             :                 case 1:
    7589          12 :                         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
    7590             :                                     NL80211_CHAN_HT40PLUS);
    7591          12 :                         break;
    7592             :                 default:
    7593         596 :                         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
    7594             :                                     NL80211_CHAN_HT20);
    7595         596 :                         break;
    7596             :                 }
    7597             :         }
    7598         634 :         return 0;
    7599             : 
    7600             : nla_put_failure:
    7601           0 :         return -ENOBUFS;
    7602             : }
    7603             : 
    7604             : 
    7605         627 : static int nl80211_set_channel(struct i802_bss *bss,
    7606             :                                struct hostapd_freq_params *freq, int set_chan)
    7607             : {
    7608         627 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7609             :         struct nl_msg *msg;
    7610             :         int ret;
    7611             : 
    7612         627 :         wpa_printf(MSG_DEBUG,
    7613             :                    "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
    7614             :                    freq->freq, freq->ht_enabled, freq->vht_enabled,
    7615             :                    freq->bandwidth, freq->center_freq1, freq->center_freq2);
    7616         627 :         msg = nlmsg_alloc();
    7617         627 :         if (!msg)
    7618           0 :                 return -1;
    7619             : 
    7620         627 :         nl80211_cmd(drv, msg, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
    7621             :                     NL80211_CMD_SET_WIPHY);
    7622             : 
    7623         627 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    7624         627 :         if (nl80211_put_freq_params(msg, freq) < 0)
    7625           0 :                 goto nla_put_failure;
    7626             : 
    7627         627 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7628         627 :         msg = NULL;
    7629         627 :         if (ret == 0) {
    7630         627 :                 bss->freq = freq->freq;
    7631         627 :                 return 0;
    7632             :         }
    7633           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
    7634             :                    "%d (%s)", freq->freq, ret, strerror(-ret));
    7635             : nla_put_failure:
    7636           0 :         nlmsg_free(msg);
    7637           0 :         return -1;
    7638             : }
    7639             : 
    7640             : 
    7641        7529 : static u32 sta_flags_nl80211(int flags)
    7642             : {
    7643        7529 :         u32 f = 0;
    7644             : 
    7645        7529 :         if (flags & WPA_STA_AUTHORIZED)
    7646        3656 :                 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
    7647        7529 :         if (flags & WPA_STA_WMM)
    7648        3889 :                 f |= BIT(NL80211_STA_FLAG_WME);
    7649        7529 :         if (flags & WPA_STA_SHORT_PREAMBLE)
    7650        3863 :                 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
    7651        7529 :         if (flags & WPA_STA_MFP)
    7652        1361 :                 f |= BIT(NL80211_STA_FLAG_MFP);
    7653        7529 :         if (flags & WPA_STA_TDLS_PEER)
    7654           0 :                 f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
    7655             : 
    7656        7529 :         return f;
    7657             : }
    7658             : 
    7659             : 
    7660        1299 : static int wpa_driver_nl80211_sta_add(void *priv,
    7661             :                                       struct hostapd_sta_add_params *params)
    7662             : {
    7663        1299 :         struct i802_bss *bss = priv;
    7664        1299 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7665             :         struct nl_msg *msg;
    7666             :         struct nl80211_sta_flag_update upd;
    7667        1299 :         int ret = -ENOBUFS;
    7668             : 
    7669        1299 :         if ((params->flags & WPA_STA_TDLS_PEER) &&
    7670           0 :             !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
    7671           0 :                 return -EOPNOTSUPP;
    7672             : 
    7673        1299 :         msg = nlmsg_alloc();
    7674        1299 :         if (!msg)
    7675           0 :                 return -ENOMEM;
    7676             : 
    7677        9093 :         wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
    7678        9093 :                    params->set ? "Set" : "Add", MAC2STR(params->addr));
    7679        1299 :         nl80211_cmd(drv, msg, 0, params->set ? NL80211_CMD_SET_STATION :
    7680             :                     NL80211_CMD_NEW_STATION);
    7681             : 
    7682        1299 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
    7683        1299 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
    7684        1299 :         NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
    7685             :                 params->supp_rates);
    7686        1299 :         wpa_hexdump(MSG_DEBUG, "  * supported rates", params->supp_rates,
    7687             :                     params->supp_rates_len);
    7688        1299 :         if (!params->set) {
    7689        1299 :                 if (params->aid) {
    7690        1299 :                         wpa_printf(MSG_DEBUG, "  * aid=%u", params->aid);
    7691        1299 :                         NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
    7692             :                 } else {
    7693             :                         /*
    7694             :                          * cfg80211 validates that AID is non-zero, so we have
    7695             :                          * to make this a non-zero value for the TDLS case where
    7696             :                          * a dummy STA entry is used for now.
    7697             :                          */
    7698           0 :                         wpa_printf(MSG_DEBUG, "  * aid=1 (TDLS workaround)");
    7699           0 :                         NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, 1);
    7700             :                 }
    7701        1299 :                 wpa_printf(MSG_DEBUG, "  * listen_interval=%u",
    7702        1299 :                            params->listen_interval);
    7703        1299 :                 NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
    7704             :                             params->listen_interval);
    7705           0 :         } else if (params->aid && (params->flags & WPA_STA_TDLS_PEER)) {
    7706           0 :                 wpa_printf(MSG_DEBUG, "  * peer_aid=%u", params->aid);
    7707           0 :                 NLA_PUT_U16(msg, NL80211_ATTR_PEER_AID, params->aid);
    7708             :         }
    7709        1299 :         if (params->ht_capabilities) {
    7710        1276 :                 wpa_hexdump(MSG_DEBUG, "  * ht_capabilities",
    7711        1276 :                             (u8 *) params->ht_capabilities,
    7712             :                             sizeof(*params->ht_capabilities));
    7713        1276 :                 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
    7714             :                         sizeof(*params->ht_capabilities),
    7715             :                         params->ht_capabilities);
    7716             :         }
    7717             : 
    7718        1299 :         if (params->vht_capabilities) {
    7719           6 :                 wpa_hexdump(MSG_DEBUG, "  * vht_capabilities",
    7720           6 :                             (u8 *) params->vht_capabilities,
    7721             :                             sizeof(*params->vht_capabilities));
    7722           6 :                 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY,
    7723             :                         sizeof(*params->vht_capabilities),
    7724             :                         params->vht_capabilities);
    7725             :         }
    7726             : 
    7727        1299 :         if (params->vht_opmode_enabled) {
    7728           0 :                 wpa_printf(MSG_DEBUG, "  * opmode=%u", params->vht_opmode);
    7729           0 :                 NLA_PUT_U8(msg, NL80211_ATTR_OPMODE_NOTIF,
    7730             :                            params->vht_opmode);
    7731             :         }
    7732             : 
    7733        1299 :         wpa_printf(MSG_DEBUG, "  * capability=0x%x", params->capability);
    7734        1299 :         NLA_PUT_U16(msg, NL80211_ATTR_STA_CAPABILITY, params->capability);
    7735             : 
    7736        1299 :         if (params->ext_capab) {
    7737           0 :                 wpa_hexdump(MSG_DEBUG, "  * ext_capab",
    7738           0 :                             params->ext_capab, params->ext_capab_len);
    7739           0 :                 NLA_PUT(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
    7740             :                         params->ext_capab_len, params->ext_capab);
    7741             :         }
    7742             : 
    7743        1299 :         if (params->supp_channels) {
    7744           0 :                 wpa_hexdump(MSG_DEBUG, "  * supported channels",
    7745           0 :                             params->supp_channels, params->supp_channels_len);
    7746           0 :                 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_CHANNELS,
    7747             :                         params->supp_channels_len, params->supp_channels);
    7748             :         }
    7749             : 
    7750        1299 :         if (params->supp_oper_classes) {
    7751           0 :                 wpa_hexdump(MSG_DEBUG, "  * supported operating classes",
    7752           0 :                             params->supp_oper_classes,
    7753             :                             params->supp_oper_classes_len);
    7754           0 :                 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
    7755             :                         params->supp_oper_classes_len,
    7756             :                         params->supp_oper_classes);
    7757             :         }
    7758             : 
    7759        1299 :         os_memset(&upd, 0, sizeof(upd));
    7760        1299 :         upd.mask = sta_flags_nl80211(params->flags);
    7761        1299 :         upd.set = upd.mask;
    7762        1299 :         wpa_printf(MSG_DEBUG, "  * flags set=0x%x mask=0x%x",
    7763             :                    upd.set, upd.mask);
    7764        1299 :         NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
    7765             : 
    7766        1299 :         if (params->flags & WPA_STA_WMM) {
    7767        1295 :                 struct nlattr *wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
    7768             : 
    7769        1295 :                 if (!wme)
    7770           0 :                         goto nla_put_failure;
    7771             : 
    7772        1295 :                 wpa_printf(MSG_DEBUG, "  * qosinfo=0x%x", params->qosinfo);
    7773        1295 :                 NLA_PUT_U8(msg, NL80211_STA_WME_UAPSD_QUEUES,
    7774             :                                 params->qosinfo & WMM_QOSINFO_STA_AC_MASK);
    7775        1295 :                 NLA_PUT_U8(msg, NL80211_STA_WME_MAX_SP,
    7776             :                                 (params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
    7777             :                                 WMM_QOSINFO_STA_SP_MASK);
    7778        1295 :                 nla_nest_end(msg, wme);
    7779             :         }
    7780             : 
    7781        1299 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7782        1299 :         msg = NULL;
    7783        1299 :         if (ret)
    7784           0 :                 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
    7785           0 :                            "result: %d (%s)", params->set ? "SET" : "NEW", ret,
    7786             :                            strerror(-ret));
    7787        1299 :         if (ret == -EEXIST)
    7788           0 :                 ret = 0;
    7789             :  nla_put_failure:
    7790        1299 :         nlmsg_free(msg);
    7791        1299 :         return ret;
    7792             : }
    7793             : 
    7794             : 
    7795          11 : static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
    7796             : {
    7797             : #ifdef CONFIG_LIBNL3_ROUTE
    7798          11 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7799             :         struct rtnl_neigh *rn;
    7800             :         struct nl_addr *nl_addr;
    7801             :         int err;
    7802             : 
    7803          11 :         rn = rtnl_neigh_alloc();
    7804          11 :         if (!rn)
    7805           0 :                 return;
    7806             : 
    7807          11 :         rtnl_neigh_set_family(rn, AF_BRIDGE);
    7808          11 :         rtnl_neigh_set_ifindex(rn, bss->ifindex);
    7809          11 :         nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN);
    7810          11 :         if (!nl_addr) {
    7811           0 :                 rtnl_neigh_put(rn);
    7812           0 :                 return;
    7813             :         }
    7814          11 :         rtnl_neigh_set_lladdr(rn, nl_addr);
    7815             : 
    7816          11 :         err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
    7817          11 :         if (err < 0) {
    7818          56 :                 wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
    7819          48 :                            MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
    7820             :                            bss->ifindex, nl_geterror(err));
    7821             :         } else {
    7822          18 :                 wpa_printf(MSG_DEBUG, "nl80211: deleted bridge FDB entry for "
    7823          18 :                            MACSTR, MAC2STR(addr));
    7824             :         }
    7825             : 
    7826          11 :         nl_addr_put(nl_addr);
    7827          11 :         rtnl_neigh_put(rn);
    7828             : #endif /* CONFIG_LIBNL3_ROUTE */
    7829             : }
    7830             : 
    7831             : 
    7832        2340 : static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr)
    7833             : {
    7834        2340 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    7835             :         struct nl_msg *msg;
    7836             :         int ret;
    7837             : 
    7838        2340 :         msg = nlmsg_alloc();
    7839        2340 :         if (!msg)
    7840           0 :                 return -ENOMEM;
    7841             : 
    7842        2340 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
    7843             : 
    7844        2340 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
    7845             :                     if_nametoindex(bss->ifname));
    7846        2340 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
    7847             : 
    7848        2340 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    7849       18720 :         wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
    7850             :                    " --> %d (%s)",
    7851       16380 :                    bss->ifname, MAC2STR(addr), ret, strerror(-ret));
    7852             : 
    7853        2340 :         if (drv->rtnl_sk)
    7854          11 :                 rtnl_neigh_delete_fdb_entry(bss, addr);
    7855             : 
    7856        2340 :         if (ret == -ENOENT)
    7857        1077 :                 return 0;
    7858        1263 :         return ret;
    7859             :  nla_put_failure:
    7860           0 :         nlmsg_free(msg);
    7861           0 :         return -ENOBUFS;
    7862             : }
    7863             : 
    7864             : 
    7865          31 : static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
    7866             :                                  int ifidx)
    7867             : {
    7868             :         struct nl_msg *msg;
    7869             :         struct wpa_driver_nl80211_data *drv2;
    7870             : 
    7871          31 :         wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
    7872             : 
    7873             :         /* stop listening for EAPOL on this interface */
    7874          62 :         dl_list_for_each(drv2, &drv->global->interfaces,
    7875             :                          struct wpa_driver_nl80211_data, list)
    7876          31 :                 del_ifidx(drv2, ifidx);
    7877             : 
    7878          31 :         msg = nlmsg_alloc();
    7879          31 :         if (!msg)
    7880           0 :                 goto nla_put_failure;
    7881             : 
    7882          31 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
    7883          31 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
    7884             : 
    7885          31 :         if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
    7886          62 :                 return;
    7887           0 :         msg = NULL;
    7888             :  nla_put_failure:
    7889           0 :         nlmsg_free(msg);
    7890           0 :         wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
    7891             : }
    7892             : 
    7893             : 
    7894        1293 : static const char * nl80211_iftype_str(enum nl80211_iftype mode)
    7895             : {
    7896        1293 :         switch (mode) {
    7897             :         case NL80211_IFTYPE_ADHOC:
    7898           0 :                 return "ADHOC";
    7899             :         case NL80211_IFTYPE_STATION:
    7900         631 :                 return "STATION";
    7901             :         case NL80211_IFTYPE_AP:
    7902         650 :                 return "AP";
    7903             :         case NL80211_IFTYPE_AP_VLAN:
    7904          12 :                 return "AP_VLAN";
    7905             :         case NL80211_IFTYPE_WDS:
    7906           0 :                 return "WDS";
    7907             :         case NL80211_IFTYPE_MONITOR:
    7908           0 :                 return "MONITOR";
    7909             :         case NL80211_IFTYPE_MESH_POINT:
    7910           0 :                 return "MESH_POINT";
    7911             :         case NL80211_IFTYPE_P2P_CLIENT:
    7912           0 :                 return "P2P_CLIENT";
    7913             :         case NL80211_IFTYPE_P2P_GO:
    7914           0 :                 return "P2P_GO";
    7915             :         case NL80211_IFTYPE_P2P_DEVICE:
    7916           0 :                 return "P2P_DEVICE";
    7917             :         default:
    7918           0 :                 return "unknown";
    7919             :         }
    7920             : }
    7921             : 
    7922             : 
    7923          31 : static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
    7924             :                                      const char *ifname,
    7925             :                                      enum nl80211_iftype iftype,
    7926             :                                      const u8 *addr, int wds,
    7927             :                                      int (*handler)(struct nl_msg *, void *),
    7928             :                                      void *arg)
    7929             : {
    7930             :         struct nl_msg *msg;
    7931             :         int ifidx;
    7932          31 :         int ret = -ENOBUFS;
    7933             : 
    7934          31 :         wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
    7935             :                    iftype, nl80211_iftype_str(iftype));
    7936             : 
    7937          31 :         msg = nlmsg_alloc();
    7938          31 :         if (!msg)
    7939           0 :                 return -1;
    7940             : 
    7941          31 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_INTERFACE);
    7942          31 :         if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
    7943           0 :                 goto nla_put_failure;
    7944          31 :         NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
    7945          31 :         NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
    7946             : 
    7947          31 :         if (iftype == NL80211_IFTYPE_MONITOR) {
    7948             :                 struct nlattr *flags;
    7949             : 
    7950           0 :                 flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
    7951           0 :                 if (!flags)
    7952           0 :                         goto nla_put_failure;
    7953             : 
    7954           0 :                 NLA_PUT_FLAG(msg, NL80211_MNTR_FLAG_COOK_FRAMES);
    7955             : 
    7956           0 :                 nla_nest_end(msg, flags);
    7957          31 :         } else if (wds) {
    7958           1 :                 NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
    7959             :         }
    7960             : 
    7961             :         /*
    7962             :          * Tell cfg80211 that the interface belongs to the socket that created
    7963             :          * it, and the interface should be deleted when the socket is closed.
    7964             :          */
    7965          31 :         NLA_PUT_FLAG(msg, NL80211_ATTR_IFACE_SOCKET_OWNER);
    7966             : 
    7967          31 :         ret = send_and_recv_msgs(drv, msg, handler, arg);
    7968          31 :         msg = NULL;
    7969          31 :         if (ret) {
    7970             :  nla_put_failure:
    7971           0 :                 nlmsg_free(msg);
    7972           0 :                 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
    7973             :                            ifname, ret, strerror(-ret));
    7974           0 :                 return ret;
    7975             :         }
    7976             : 
    7977          31 :         if (iftype == NL80211_IFTYPE_P2P_DEVICE)
    7978           0 :                 return 0;
    7979             : 
    7980          31 :         ifidx = if_nametoindex(ifname);
    7981          31 :         wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
    7982             :                    ifname, ifidx);
    7983             : 
    7984          31 :         if (ifidx <= 0)
    7985           0 :                 return -1;
    7986             : 
    7987             :         /*
    7988             :          * Some virtual interfaces need to process EAPOL packets and events on
    7989             :          * the parent interface. This is used mainly with hostapd.
    7990             :          */
    7991          31 :         if (drv->hostapd ||
    7992           0 :             iftype == NL80211_IFTYPE_AP_VLAN ||
    7993           0 :             iftype == NL80211_IFTYPE_WDS ||
    7994             :             iftype == NL80211_IFTYPE_MONITOR) {
    7995             :                 /* start listening for EAPOL on this interface */
    7996          31 :                 add_ifidx(drv, ifidx);
    7997             :         }
    7998             : 
    7999          62 :         if (addr && iftype != NL80211_IFTYPE_MONITOR &&
    8000          31 :             linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
    8001           0 :                 nl80211_remove_iface(drv, ifidx);
    8002           0 :                 return -1;
    8003             :         }
    8004             : 
    8005          31 :         return ifidx;
    8006             : }
    8007             : 
    8008             : 
    8009          31 : static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
    8010             :                                 const char *ifname, enum nl80211_iftype iftype,
    8011             :                                 const u8 *addr, int wds,
    8012             :                                 int (*handler)(struct nl_msg *, void *),
    8013             :                                 void *arg, int use_existing)
    8014             : {
    8015             :         int ret;
    8016             : 
    8017          31 :         ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
    8018             :                                         arg);
    8019             : 
    8020             :         /* if error occurred and interface exists already */
    8021          31 :         if (ret == -ENFILE && if_nametoindex(ifname)) {
    8022           0 :                 if (use_existing) {
    8023           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Continue using existing interface %s",
    8024             :                                    ifname);
    8025           0 :                         if (addr && iftype != NL80211_IFTYPE_MONITOR &&
    8026           0 :                             linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
    8027           0 :                                                addr) < 0 &&
    8028           0 :                             (linux_set_iface_flags(drv->global->ioctl_sock,
    8029           0 :                                                    ifname, 0) < 0 ||
    8030           0 :                              linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
    8031           0 :                                                 addr) < 0 ||
    8032           0 :                              linux_set_iface_flags(drv->global->ioctl_sock,
    8033             :                                                    ifname, 1) < 0))
    8034           0 :                                         return -1;
    8035           0 :                         return -ENFILE;
    8036             :                 }
    8037           0 :                 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
    8038             : 
    8039             :                 /* Try to remove the interface that was already there. */
    8040           0 :                 nl80211_remove_iface(drv, if_nametoindex(ifname));
    8041             : 
    8042             :                 /* Try to create the interface again */
    8043           0 :                 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
    8044             :                                                 wds, handler, arg);
    8045             :         }
    8046             : 
    8047          31 :         if (ret >= 0 && is_p2p_net_interface(iftype))
    8048           0 :                 nl80211_disable_11b_rates(drv, ret, 1);
    8049             : 
    8050          31 :         return ret;
    8051             : }
    8052             : 
    8053             : 
    8054           0 : static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
    8055             : {
    8056             :         struct ieee80211_hdr *hdr;
    8057             :         u16 fc;
    8058             :         union wpa_event_data event;
    8059             : 
    8060           0 :         hdr = (struct ieee80211_hdr *) buf;
    8061           0 :         fc = le_to_host16(hdr->frame_control);
    8062             : 
    8063           0 :         os_memset(&event, 0, sizeof(event));
    8064           0 :         event.tx_status.type = WLAN_FC_GET_TYPE(fc);
    8065           0 :         event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
    8066           0 :         event.tx_status.dst = hdr->addr1;
    8067           0 :         event.tx_status.data = buf;
    8068           0 :         event.tx_status.data_len = len;
    8069           0 :         event.tx_status.ack = ok;
    8070           0 :         wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event);
    8071           0 : }
    8072             : 
    8073             : 
    8074           0 : static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
    8075             :                              u8 *buf, size_t len)
    8076             : {
    8077           0 :         struct ieee80211_hdr *hdr = (void *)buf;
    8078             :         u16 fc;
    8079             :         union wpa_event_data event;
    8080             : 
    8081           0 :         if (len < sizeof(*hdr))
    8082           0 :                 return;
    8083             : 
    8084           0 :         fc = le_to_host16(hdr->frame_control);
    8085             : 
    8086           0 :         os_memset(&event, 0, sizeof(event));
    8087           0 :         event.rx_from_unknown.bssid = get_hdr_bssid(hdr, len);
    8088           0 :         event.rx_from_unknown.addr = hdr->addr2;
    8089           0 :         event.rx_from_unknown.wds = (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) ==
    8090             :                 (WLAN_FC_FROMDS | WLAN_FC_TODS);
    8091           0 :         wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
    8092             : }
    8093             : 
    8094             : 
    8095           0 : static void handle_frame(struct wpa_driver_nl80211_data *drv,
    8096             :                          u8 *buf, size_t len, int datarate, int ssi_signal)
    8097             : {
    8098             :         struct ieee80211_hdr *hdr;
    8099             :         u16 fc;
    8100             :         union wpa_event_data event;
    8101             : 
    8102           0 :         hdr = (struct ieee80211_hdr *) buf;
    8103           0 :         fc = le_to_host16(hdr->frame_control);
    8104             : 
    8105           0 :         switch (WLAN_FC_GET_TYPE(fc)) {
    8106             :         case WLAN_FC_TYPE_MGMT:
    8107           0 :                 os_memset(&event, 0, sizeof(event));
    8108           0 :                 event.rx_mgmt.frame = buf;
    8109           0 :                 event.rx_mgmt.frame_len = len;
    8110           0 :                 event.rx_mgmt.datarate = datarate;
    8111           0 :                 event.rx_mgmt.ssi_signal = ssi_signal;
    8112           0 :                 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
    8113           0 :                 break;
    8114             :         case WLAN_FC_TYPE_CTRL:
    8115             :                 /* can only get here with PS-Poll frames */
    8116           0 :                 wpa_printf(MSG_DEBUG, "CTRL");
    8117           0 :                 from_unknown_sta(drv, buf, len);
    8118           0 :                 break;
    8119             :         case WLAN_FC_TYPE_DATA:
    8120           0 :                 from_unknown_sta(drv, buf, len);
    8121           0 :                 break;
    8122             :         }
    8123           0 : }
    8124             : 
    8125             : 
    8126           0 : static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
    8127             : {
    8128           0 :         struct wpa_driver_nl80211_data *drv = eloop_ctx;
    8129             :         int len;
    8130             :         unsigned char buf[3000];
    8131             :         struct ieee80211_radiotap_iterator iter;
    8132             :         int ret;
    8133           0 :         int datarate = 0, ssi_signal = 0;
    8134           0 :         int injected = 0, failed = 0, rxflags = 0;
    8135             : 
    8136           0 :         len = recv(sock, buf, sizeof(buf), 0);
    8137           0 :         if (len < 0) {
    8138           0 :                 wpa_printf(MSG_ERROR, "nl80211: Monitor socket recv failed: %s",
    8139           0 :                            strerror(errno));
    8140           0 :                 return;
    8141             :         }
    8142             : 
    8143           0 :         if (ieee80211_radiotap_iterator_init(&iter, (void *) buf, len, NULL)) {
    8144           0 :                 wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame");
    8145           0 :                 return;
    8146             :         }
    8147             : 
    8148             :         while (1) {
    8149           0 :                 ret = ieee80211_radiotap_iterator_next(&iter);
    8150           0 :                 if (ret == -ENOENT)
    8151           0 :                         break;
    8152           0 :                 if (ret) {
    8153           0 :                         wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame (%d)",
    8154             :                                    ret);
    8155           0 :                         return;
    8156             :                 }
    8157           0 :                 switch (iter.this_arg_index) {
    8158             :                 case IEEE80211_RADIOTAP_FLAGS:
    8159           0 :                         if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
    8160           0 :                                 len -= 4;
    8161           0 :                         break;
    8162             :                 case IEEE80211_RADIOTAP_RX_FLAGS:
    8163           0 :                         rxflags = 1;
    8164           0 :                         break;
    8165             :                 case IEEE80211_RADIOTAP_TX_FLAGS:
    8166           0 :                         injected = 1;
    8167           0 :                         failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
    8168             :                                         IEEE80211_RADIOTAP_F_TX_FAIL;
    8169           0 :                         break;
    8170             :                 case IEEE80211_RADIOTAP_DATA_RETRIES:
    8171           0 :                         break;
    8172             :                 case IEEE80211_RADIOTAP_CHANNEL:
    8173             :                         /* TODO: convert from freq/flags to channel number */
    8174           0 :                         break;
    8175             :                 case IEEE80211_RADIOTAP_RATE:
    8176           0 :                         datarate = *iter.this_arg * 5;
    8177           0 :                         break;
    8178             :                 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
    8179           0 :                         ssi_signal = (s8) *iter.this_arg;
    8180           0 :                         break;
    8181             :                 }
    8182           0 :         }
    8183             : 
    8184           0 :         if (rxflags && injected)
    8185           0 :                 return;
    8186             : 
    8187           0 :         if (!injected)
    8188           0 :                 handle_frame(drv, buf + iter._max_length,
    8189           0 :                              len - iter._max_length, datarate, ssi_signal);
    8190             :         else
    8191           0 :                 handle_tx_callback(drv->ctx, buf + iter._max_length,
    8192           0 :                                    len - iter._max_length, !failed);
    8193             : }
    8194             : 
    8195             : 
    8196             : /*
    8197             :  * we post-process the filter code later and rewrite
    8198             :  * this to the offset to the last instruction
    8199             :  */
    8200             : #define PASS    0xFF
    8201             : #define FAIL    0xFE
    8202             : 
    8203             : static struct sock_filter msock_filter_insns[] = {
    8204             :         /*
    8205             :          * do a little-endian load of the radiotap length field
    8206             :          */
    8207             :         /* load lower byte into A */
    8208             :         BPF_STMT(BPF_LD  | BPF_B | BPF_ABS, 2),
    8209             :         /* put it into X (== index register) */
    8210             :         BPF_STMT(BPF_MISC| BPF_TAX, 0),
    8211             :         /* load upper byte into A */
    8212             :         BPF_STMT(BPF_LD  | BPF_B | BPF_ABS, 3),
    8213             :         /* left-shift it by 8 */
    8214             :         BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
    8215             :         /* or with X */
    8216             :         BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
    8217             :         /* put result into X */
    8218             :         BPF_STMT(BPF_MISC| BPF_TAX, 0),
    8219             : 
    8220             :         /*
    8221             :          * Allow management frames through, this also gives us those
    8222             :          * management frames that we sent ourselves with status
    8223             :          */
    8224             :         /* load the lower byte of the IEEE 802.11 frame control field */
    8225             :         BPF_STMT(BPF_LD  | BPF_B | BPF_IND, 0),
    8226             :         /* mask off frame type and version */
    8227             :         BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
    8228             :         /* accept frame if it's both 0, fall through otherwise */
    8229             :         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
    8230             : 
    8231             :         /*
    8232             :          * TODO: add a bit to radiotap RX flags that indicates
    8233             :          * that the sending station is not associated, then
    8234             :          * add a filter here that filters on our DA and that flag
    8235             :          * to allow us to deauth frames to that bad station.
    8236             :          *
    8237             :          * For now allow all To DS data frames through.
    8238             :          */
    8239             :         /* load the IEEE 802.11 frame control field */
    8240             :         BPF_STMT(BPF_LD  | BPF_H | BPF_IND, 0),
    8241             :         /* mask off frame type, version and DS status */
    8242             :         BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0F03),
    8243             :         /* accept frame if version 0, type 2 and To DS, fall through otherwise
    8244             :          */
    8245             :         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0801, PASS, 0),
    8246             : 
    8247             : #if 0
    8248             :         /*
    8249             :          * drop non-data frames
    8250             :          */
    8251             :         /* load the lower byte of the frame control field */
    8252             :         BPF_STMT(BPF_LD   | BPF_B | BPF_IND, 0),
    8253             :         /* mask off QoS bit */
    8254             :         BPF_STMT(BPF_ALU  | BPF_AND | BPF_K, 0x0c),
    8255             :         /* drop non-data frames */
    8256             :         BPF_JUMP(BPF_JMP  | BPF_JEQ | BPF_K, 8, 0, FAIL),
    8257             : #endif
    8258             :         /* load the upper byte of the frame control field */
    8259             :         BPF_STMT(BPF_LD   | BPF_B | BPF_IND, 1),
    8260             :         /* mask off toDS/fromDS */
    8261             :         BPF_STMT(BPF_ALU  | BPF_AND | BPF_K, 0x03),
    8262             :         /* accept WDS frames */
    8263             :         BPF_JUMP(BPF_JMP  | BPF_JEQ | BPF_K, 3, PASS, 0),
    8264             : 
    8265             :         /*
    8266             :          * add header length to index
    8267             :          */
    8268             :         /* load the lower byte of the frame control field */
    8269             :         BPF_STMT(BPF_LD   | BPF_B | BPF_IND, 0),
    8270             :         /* mask off QoS bit */
    8271             :         BPF_STMT(BPF_ALU  | BPF_AND | BPF_K, 0x80),
    8272             :         /* right shift it by 6 to give 0 or 2 */
    8273             :         BPF_STMT(BPF_ALU  | BPF_RSH | BPF_K, 6),
    8274             :         /* add data frame header length */
    8275             :         BPF_STMT(BPF_ALU  | BPF_ADD | BPF_K, 24),
    8276             :         /* add index, was start of 802.11 header */
    8277             :         BPF_STMT(BPF_ALU  | BPF_ADD | BPF_X, 0),
    8278             :         /* move to index, now start of LL header */
    8279             :         BPF_STMT(BPF_MISC | BPF_TAX, 0),
    8280             : 
    8281             :         /*
    8282             :          * Accept empty data frames, we use those for
    8283             :          * polling activity.
    8284             :          */
    8285             :         BPF_STMT(BPF_LD  | BPF_W | BPF_LEN, 0),
    8286             :         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
    8287             : 
    8288             :         /*
    8289             :          * Accept EAPOL frames
    8290             :          */
    8291             :         BPF_STMT(BPF_LD  | BPF_W | BPF_IND, 0),
    8292             :         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
    8293             :         BPF_STMT(BPF_LD  | BPF_W | BPF_IND, 4),
    8294             :         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
    8295             : 
    8296             :         /* keep these last two statements or change the code below */
    8297             :         /* return 0 == "DROP" */
    8298             :         BPF_STMT(BPF_RET | BPF_K, 0),
    8299             :         /* return ~0 == "keep all" */
    8300             :         BPF_STMT(BPF_RET | BPF_K, ~0),
    8301             : };
    8302             : 
    8303             : static struct sock_fprog msock_filter = {
    8304             :         .len = ARRAY_SIZE(msock_filter_insns),
    8305             :         .filter = msock_filter_insns,
    8306             : };
    8307             : 
    8308             : 
    8309           0 : static int add_monitor_filter(int s)
    8310             : {
    8311             :         int idx;
    8312             : 
    8313             :         /* rewrite all PASS/FAIL jump offsets */
    8314           0 :         for (idx = 0; idx < msock_filter.len; idx++) {
    8315           0 :                 struct sock_filter *insn = &msock_filter_insns[idx];
    8316             : 
    8317           0 :                 if (BPF_CLASS(insn->code) == BPF_JMP) {
    8318           0 :                         if (insn->code == (BPF_JMP|BPF_JA)) {
    8319           0 :                                 if (insn->k == PASS)
    8320           0 :                                         insn->k = msock_filter.len - idx - 2;
    8321           0 :                                 else if (insn->k == FAIL)
    8322           0 :                                         insn->k = msock_filter.len - idx - 3;
    8323             :                         }
    8324             : 
    8325           0 :                         if (insn->jt == PASS)
    8326           0 :                                 insn->jt = msock_filter.len - idx - 2;
    8327           0 :                         else if (insn->jt == FAIL)
    8328           0 :                                 insn->jt = msock_filter.len - idx - 3;
    8329             : 
    8330           0 :                         if (insn->jf == PASS)
    8331           0 :                                 insn->jf = msock_filter.len - idx - 2;
    8332           0 :                         else if (insn->jf == FAIL)
    8333           0 :                                 insn->jf = msock_filter.len - idx - 3;
    8334             :                 }
    8335             :         }
    8336             : 
    8337           0 :         if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
    8338             :                        &msock_filter, sizeof(msock_filter))) {
    8339           0 :                 wpa_printf(MSG_ERROR, "nl80211: setsockopt(SO_ATTACH_FILTER) failed: %s",
    8340           0 :                            strerror(errno));
    8341           0 :                 return -1;
    8342             :         }
    8343             : 
    8344           0 :         return 0;
    8345             : }
    8346             : 
    8347             : 
    8348         631 : static void nl80211_remove_monitor_interface(
    8349             :         struct wpa_driver_nl80211_data *drv)
    8350             : {
    8351         631 :         if (drv->monitor_refcount > 0)
    8352           0 :                 drv->monitor_refcount--;
    8353         631 :         wpa_printf(MSG_DEBUG, "nl80211: Remove monitor interface: refcount=%d",
    8354             :                    drv->monitor_refcount);
    8355         631 :         if (drv->monitor_refcount > 0)
    8356         631 :                 return;
    8357             : 
    8358         631 :         if (drv->monitor_ifidx >= 0) {
    8359           0 :                 nl80211_remove_iface(drv, drv->monitor_ifidx);
    8360           0 :                 drv->monitor_ifidx = -1;
    8361             :         }
    8362         631 :         if (drv->monitor_sock >= 0) {
    8363           0 :                 eloop_unregister_read_sock(drv->monitor_sock);
    8364           0 :                 close(drv->monitor_sock);
    8365           0 :                 drv->monitor_sock = -1;
    8366             :         }
    8367             : }
    8368             : 
    8369             : 
    8370             : static int
    8371           0 : nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
    8372             : {
    8373             :         char buf[IFNAMSIZ];
    8374             :         struct sockaddr_ll ll;
    8375             :         int optval;
    8376             :         socklen_t optlen;
    8377             : 
    8378           0 :         if (drv->monitor_ifidx >= 0) {
    8379           0 :                 drv->monitor_refcount++;
    8380           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Re-use existing monitor interface: refcount=%d",
    8381             :                            drv->monitor_refcount);
    8382           0 :                 return 0;
    8383             :         }
    8384             : 
    8385           0 :         if (os_strncmp(drv->first_bss->ifname, "p2p-", 4) == 0) {
    8386             :                 /*
    8387             :                  * P2P interface name is of the format p2p-%s-%d. For monitor
    8388             :                  * interface name corresponding to P2P GO, replace "p2p-" with
    8389             :                  * "mon-" to retain the same interface name length and to
    8390             :                  * indicate that it is a monitor interface.
    8391             :                  */
    8392           0 :                 snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss->ifname + 4);
    8393             :         } else {
    8394             :                 /* Non-P2P interface with AP functionality. */
    8395           0 :                 snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss->ifname);
    8396             :         }
    8397             : 
    8398           0 :         buf[IFNAMSIZ - 1] = '\0';
    8399             : 
    8400           0 :         drv->monitor_ifidx =
    8401           0 :                 nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
    8402             :                                      0, NULL, NULL, 0);
    8403             : 
    8404           0 :         if (drv->monitor_ifidx == -EOPNOTSUPP) {
    8405             :                 /*
    8406             :                  * This is backward compatibility for a few versions of
    8407             :                  * the kernel only that didn't advertise the right
    8408             :                  * attributes for the only driver that then supported
    8409             :                  * AP mode w/o monitor -- ath6kl.
    8410             :                  */
    8411           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support "
    8412             :                            "monitor interface type - try to run without it");
    8413           0 :                 drv->device_ap_sme = 1;
    8414             :         }
    8415             : 
    8416           0 :         if (drv->monitor_ifidx < 0)
    8417           0 :                 return -1;
    8418             : 
    8419           0 :         if (linux_set_iface_flags(drv->global->ioctl_sock, buf, 1))
    8420           0 :                 goto error;
    8421             : 
    8422           0 :         memset(&ll, 0, sizeof(ll));
    8423           0 :         ll.sll_family = AF_PACKET;
    8424           0 :         ll.sll_ifindex = drv->monitor_ifidx;
    8425           0 :         drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    8426           0 :         if (drv->monitor_sock < 0) {
    8427           0 :                 wpa_printf(MSG_ERROR, "nl80211: socket[PF_PACKET,SOCK_RAW] failed: %s",
    8428           0 :                            strerror(errno));
    8429           0 :                 goto error;
    8430             :         }
    8431             : 
    8432           0 :         if (add_monitor_filter(drv->monitor_sock)) {
    8433           0 :                 wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
    8434             :                            "interface; do filtering in user space");
    8435             :                 /* This works, but will cost in performance. */
    8436             :         }
    8437             : 
    8438           0 :         if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
    8439           0 :                 wpa_printf(MSG_ERROR, "nl80211: monitor socket bind failed: %s",
    8440           0 :                            strerror(errno));
    8441           0 :                 goto error;
    8442             :         }
    8443             : 
    8444           0 :         optlen = sizeof(optval);
    8445           0 :         optval = 20;
    8446           0 :         if (setsockopt
    8447           0 :             (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
    8448           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to set socket priority: %s",
    8449           0 :                            strerror(errno));
    8450           0 :                 goto error;
    8451             :         }
    8452             : 
    8453           0 :         if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
    8454             :                                      drv, NULL)) {
    8455           0 :                 wpa_printf(MSG_INFO, "nl80211: Could not register monitor read socket");
    8456           0 :                 goto error;
    8457             :         }
    8458             : 
    8459           0 :         drv->monitor_refcount++;
    8460           0 :         return 0;
    8461             :  error:
    8462           0 :         nl80211_remove_monitor_interface(drv);
    8463           0 :         return -1;
    8464             : }
    8465             : 
    8466             : 
    8467         650 : static int nl80211_setup_ap(struct i802_bss *bss)
    8468             : {
    8469         650 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8470             : 
    8471        1950 :         wpa_printf(MSG_DEBUG, "nl80211: Setup AP(%s) - device_ap_sme=%d use_monitor=%d",
    8472        1950 :                    bss->ifname, drv->device_ap_sme, drv->use_monitor);
    8473             : 
    8474             :         /*
    8475             :          * Disable Probe Request reporting unless we need it in this way for
    8476             :          * devices that include the AP SME, in the other case (unless using
    8477             :          * monitor iface) we'll get it through the nl_mgmt socket instead.
    8478             :          */
    8479         650 :         if (!drv->device_ap_sme)
    8480         650 :                 wpa_driver_nl80211_probe_req_report(bss, 0);
    8481             : 
    8482         650 :         if (!drv->device_ap_sme && !drv->use_monitor)
    8483         650 :                 if (nl80211_mgmt_subscribe_ap(bss))
    8484           0 :                         return -1;
    8485             : 
    8486         650 :         if (drv->device_ap_sme && !drv->use_monitor)
    8487           0 :                 if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
    8488           0 :                         return -1;
    8489             : 
    8490         650 :         if (!drv->device_ap_sme && drv->use_monitor &&
    8491           0 :             nl80211_create_monitor_interface(drv) &&
    8492           0 :             !drv->device_ap_sme)
    8493           0 :                 return -1;
    8494             : 
    8495         650 :         if (drv->device_ap_sme &&
    8496           0 :             wpa_driver_nl80211_probe_req_report(bss, 1) < 0) {
    8497           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
    8498             :                            "Probe Request frame reporting in AP mode");
    8499             :                 /* Try to survive without this */
    8500             :         }
    8501             : 
    8502         650 :         return 0;
    8503             : }
    8504             : 
    8505             : 
    8506         650 : static void nl80211_teardown_ap(struct i802_bss *bss)
    8507             : {
    8508         650 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8509             : 
    8510        1950 :         wpa_printf(MSG_DEBUG, "nl80211: Teardown AP(%s) - device_ap_sme=%d use_monitor=%d",
    8511        1950 :                    bss->ifname, drv->device_ap_sme, drv->use_monitor);
    8512         650 :         if (drv->device_ap_sme) {
    8513           0 :                 wpa_driver_nl80211_probe_req_report(bss, 0);
    8514           0 :                 if (!drv->use_monitor)
    8515           0 :                         nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
    8516         650 :         } else if (drv->use_monitor)
    8517           0 :                 nl80211_remove_monitor_interface(drv);
    8518             :         else
    8519         650 :                 nl80211_mgmt_unsubscribe(bss, "AP teardown");
    8520             : 
    8521         650 :         bss->beacon_set = 0;
    8522         650 : }
    8523             : 
    8524             : 
    8525        4775 : static int nl80211_send_eapol_data(struct i802_bss *bss,
    8526             :                                    const u8 *addr, const u8 *data,
    8527             :                                    size_t data_len)
    8528             : {
    8529             :         struct sockaddr_ll ll;
    8530             :         int ret;
    8531             : 
    8532        4775 :         if (bss->drv->eapol_tx_sock < 0) {
    8533           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
    8534           0 :                 return -1;
    8535             :         }
    8536             : 
    8537        4775 :         os_memset(&ll, 0, sizeof(ll));
    8538        4775 :         ll.sll_family = AF_PACKET;
    8539        4775 :         ll.sll_ifindex = bss->ifindex;
    8540        4775 :         ll.sll_protocol = htons(ETH_P_PAE);
    8541        4775 :         ll.sll_halen = ETH_ALEN;
    8542        4775 :         os_memcpy(ll.sll_addr, addr, ETH_ALEN);
    8543        4775 :         ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
    8544             :                      (struct sockaddr *) &ll, sizeof(ll));
    8545        4775 :         if (ret < 0)
    8546           0 :                 wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
    8547           0 :                            strerror(errno));
    8548             : 
    8549        4775 :         return ret;
    8550             : }
    8551             : 
    8552             : 
    8553             : static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
    8554             : 
    8555        4775 : static int wpa_driver_nl80211_hapd_send_eapol(
    8556             :         void *priv, const u8 *addr, const u8 *data,
    8557             :         size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
    8558             : {
    8559        4775 :         struct i802_bss *bss = priv;
    8560        4775 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8561             :         struct ieee80211_hdr *hdr;
    8562             :         size_t len;
    8563             :         u8 *pos;
    8564             :         int res;
    8565        4775 :         int qos = flags & WPA_STA_WMM;
    8566             : 
    8567        4775 :         if (drv->device_ap_sme || !drv->use_monitor)
    8568        4775 :                 return nl80211_send_eapol_data(bss, addr, data, data_len);
    8569             : 
    8570           0 :         len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
    8571             :                 data_len;
    8572           0 :         hdr = os_zalloc(len);
    8573           0 :         if (hdr == NULL) {
    8574           0 :                 wpa_printf(MSG_INFO, "nl80211: Failed to allocate EAPOL buffer(len=%lu)",
    8575             :                            (unsigned long) len);
    8576           0 :                 return -1;
    8577             :         }
    8578             : 
    8579           0 :         hdr->frame_control =
    8580             :                 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
    8581           0 :         hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
    8582           0 :         if (encrypt)
    8583           0 :                 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
    8584           0 :         if (qos) {
    8585           0 :                 hdr->frame_control |=
    8586             :                         host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
    8587             :         }
    8588             : 
    8589           0 :         memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
    8590           0 :         memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
    8591           0 :         memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
    8592           0 :         pos = (u8 *) (hdr + 1);
    8593             : 
    8594           0 :         if (qos) {
    8595             :                 /* Set highest priority in QoS header */
    8596           0 :                 pos[0] = 7;
    8597           0 :                 pos[1] = 0;
    8598           0 :                 pos += 2;
    8599             :         }
    8600             : 
    8601           0 :         memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
    8602           0 :         pos += sizeof(rfc1042_header);
    8603           0 :         WPA_PUT_BE16(pos, ETH_P_PAE);
    8604           0 :         pos += 2;
    8605           0 :         memcpy(pos, data, data_len);
    8606             : 
    8607           0 :         res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
    8608             :                                             0, 0, 0, 0);
    8609           0 :         if (res < 0) {
    8610           0 :                 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
    8611             :                            "failed: %d (%s)",
    8612           0 :                            (unsigned long) len, errno, strerror(errno));
    8613             :         }
    8614           0 :         os_free(hdr);
    8615             : 
    8616           0 :         return res;
    8617             : }
    8618             : 
    8619             : 
    8620        3115 : static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
    8621             :                                             int total_flags,
    8622             :                                             int flags_or, int flags_and)
    8623             : {
    8624        3115 :         struct i802_bss *bss = priv;
    8625        3115 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    8626             :         struct nl_msg *msg;
    8627             :         struct nlattr *flags;
    8628             :         struct nl80211_sta_flag_update upd;
    8629             : 
    8630       24920 :         wpa_printf(MSG_DEBUG, "nl80211: Set STA flags - ifname=%s addr=" MACSTR
    8631             :                    " total_flags=0x%x flags_or=0x%x flags_and=0x%x authorized=%d",
    8632       21805 :                    bss->ifname, MAC2STR(addr), total_flags, flags_or, flags_and,
    8633        3115 :                    !!(total_flags & WPA_STA_AUTHORIZED));
    8634             : 
    8635        3115 :         msg = nlmsg_alloc();
    8636        3115 :         if (!msg)
    8637           0 :                 return -ENOMEM;
    8638             : 
    8639        3115 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
    8640             : 
    8641        3115 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
    8642             :                     if_nametoindex(bss->ifname));
    8643        3115 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
    8644             : 
    8645             :         /*
    8646             :          * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
    8647             :          * can be removed eventually.
    8648             :          */
    8649        3115 :         flags = nla_nest_start(msg, NL80211_ATTR_STA_FLAGS);
    8650        3115 :         if (!flags)
    8651           0 :                 goto nla_put_failure;
    8652        3115 :         if (total_flags & WPA_STA_AUTHORIZED)
    8653         996 :                 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_AUTHORIZED);
    8654             : 
    8655        3115 :         if (total_flags & WPA_STA_WMM)
    8656        3101 :                 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_WME);
    8657             : 
    8658        3115 :         if (total_flags & WPA_STA_SHORT_PREAMBLE)
    8659        3085 :                 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_SHORT_PREAMBLE);
    8660             : 
    8661        3115 :         if (total_flags & WPA_STA_MFP)
    8662          98 :                 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_MFP);
    8663             : 
    8664        3115 :         if (total_flags & WPA_STA_TDLS_PEER)
    8665           0 :                 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_TDLS_PEER);
    8666             : 
    8667        3115 :         nla_nest_end(msg, flags);
    8668             : 
    8669        3115 :         os_memset(&upd, 0, sizeof(upd));
    8670        3115 :         upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
    8671        3115 :         upd.set = sta_flags_nl80211(flags_or);
    8672        3115 :         NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
    8673             : 
    8674        3115 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
    8675             :  nla_put_failure:
    8676           0 :         nlmsg_free(msg);
    8677           0 :         return -ENOBUFS;
    8678             : }
    8679             : 
    8680             : 
    8681           0 : static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
    8682             :                                  struct wpa_driver_associate_params *params)
    8683             : {
    8684             :         enum nl80211_iftype nlmode, old_mode;
    8685             : 
    8686           0 :         if (params->p2p) {
    8687           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
    8688             :                            "group (GO)");
    8689           0 :                 nlmode = NL80211_IFTYPE_P2P_GO;
    8690             :         } else
    8691           0 :                 nlmode = NL80211_IFTYPE_AP;
    8692             : 
    8693           0 :         old_mode = drv->nlmode;
    8694           0 :         if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
    8695           0 :                 nl80211_remove_monitor_interface(drv);
    8696           0 :                 return -1;
    8697             :         }
    8698             : 
    8699           0 :         if (nl80211_set_channel(drv->first_bss, &params->freq, 0)) {
    8700           0 :                 if (old_mode != nlmode)
    8701           0 :                         wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
    8702           0 :                 nl80211_remove_monitor_interface(drv);
    8703           0 :                 return -1;
    8704             :         }
    8705             : 
    8706           0 :         return 0;
    8707             : }
    8708             : 
    8709             : 
    8710           0 : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
    8711             : {
    8712             :         struct nl_msg *msg;
    8713           0 :         int ret = -1;
    8714             : 
    8715           0 :         msg = nlmsg_alloc();
    8716           0 :         if (!msg)
    8717           0 :                 return -1;
    8718             : 
    8719           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_LEAVE_IBSS);
    8720           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    8721           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    8722           0 :         msg = NULL;
    8723           0 :         if (ret) {
    8724           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
    8725             :                            "(%s)", ret, strerror(-ret));
    8726           0 :                 goto nla_put_failure;
    8727             :         }
    8728             : 
    8729           0 :         ret = 0;
    8730           0 :         wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
    8731             : 
    8732             : nla_put_failure:
    8733           0 :         if (wpa_driver_nl80211_set_mode(drv->first_bss,
    8734             :                                         NL80211_IFTYPE_STATION)) {
    8735           0 :                 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
    8736             :                            "station mode");
    8737             :         }
    8738             : 
    8739           0 :         nlmsg_free(msg);
    8740           0 :         return ret;
    8741             : }
    8742             : 
    8743             : 
    8744           0 : static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
    8745             :                                    struct wpa_driver_associate_params *params)
    8746             : {
    8747             :         struct nl_msg *msg;
    8748           0 :         int ret = -1;
    8749           0 :         int count = 0;
    8750             : 
    8751           0 :         wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
    8752             : 
    8753           0 :         if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, &params->freq)) {
    8754           0 :                 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
    8755             :                            "IBSS mode");
    8756           0 :                 return -1;
    8757             :         }
    8758             : 
    8759             : retry:
    8760           0 :         msg = nlmsg_alloc();
    8761           0 :         if (!msg)
    8762           0 :                 return -1;
    8763             : 
    8764           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_JOIN_IBSS);
    8765           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    8766             : 
    8767           0 :         if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
    8768             :                 goto nla_put_failure;
    8769             : 
    8770           0 :         wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
    8771           0 :                           params->ssid, params->ssid_len);
    8772           0 :         NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
    8773             :                 params->ssid);
    8774           0 :         os_memcpy(drv->ssid, params->ssid, params->ssid_len);
    8775           0 :         drv->ssid_len = params->ssid_len;
    8776             : 
    8777           0 :         wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq.freq);
    8778           0 :         wpa_printf(MSG_DEBUG, "  * ht_enabled=%d", params->freq.ht_enabled);
    8779           0 :         wpa_printf(MSG_DEBUG, "  * sec_channel_offset=%d",
    8780             :                    params->freq.sec_channel_offset);
    8781           0 :         wpa_printf(MSG_DEBUG, "  * vht_enabled=%d", params->freq.vht_enabled);
    8782           0 :         wpa_printf(MSG_DEBUG, "  * center_freq1=%d", params->freq.center_freq1);
    8783           0 :         wpa_printf(MSG_DEBUG, "  * center_freq2=%d", params->freq.center_freq2);
    8784           0 :         wpa_printf(MSG_DEBUG, "  * bandwidth=%d", params->freq.bandwidth);
    8785           0 :         if (nl80211_put_freq_params(msg, &params->freq) < 0)
    8786           0 :                 goto nla_put_failure;
    8787             : 
    8788           0 :         if (params->beacon_int > 0) {
    8789           0 :                 wpa_printf(MSG_DEBUG, "  * beacon_int=%d", params->beacon_int);
    8790           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL,
    8791             :                             params->beacon_int);
    8792             :         }
    8793             : 
    8794           0 :         ret = nl80211_set_conn_keys(params, msg);
    8795           0 :         if (ret)
    8796           0 :                 goto nla_put_failure;
    8797             : 
    8798           0 :         if (params->bssid && params->fixed_bssid) {
    8799           0 :                 wpa_printf(MSG_DEBUG, "  * BSSID=" MACSTR,
    8800           0 :                            MAC2STR(params->bssid));
    8801           0 :                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
    8802             :         }
    8803             : 
    8804           0 :         if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
    8805           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
    8806           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
    8807           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
    8808           0 :                 wpa_printf(MSG_DEBUG, "  * control port");
    8809           0 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
    8810             :         }
    8811             : 
    8812           0 :         if (params->wpa_ie) {
    8813           0 :                 wpa_hexdump(MSG_DEBUG,
    8814             :                             "  * Extra IEs for Beacon/Probe Response frames",
    8815           0 :                             params->wpa_ie, params->wpa_ie_len);
    8816           0 :                 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
    8817             :                         params->wpa_ie);
    8818             :         }
    8819             : 
    8820           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    8821           0 :         msg = NULL;
    8822           0 :         if (ret) {
    8823           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
    8824             :                            ret, strerror(-ret));
    8825           0 :                 count++;
    8826           0 :                 if (ret == -EALREADY && count == 1) {
    8827           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
    8828             :                                    "forced leave");
    8829           0 :                         nl80211_leave_ibss(drv);
    8830           0 :                         nlmsg_free(msg);
    8831           0 :                         goto retry;
    8832             :                 }
    8833             : 
    8834           0 :                 goto nla_put_failure;
    8835             :         }
    8836           0 :         ret = 0;
    8837           0 :         wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
    8838             : 
    8839             : nla_put_failure:
    8840           0 :         nlmsg_free(msg);
    8841           0 :         return ret;
    8842             : }
    8843             : 
    8844             : 
    8845           0 : static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
    8846             :                                   struct wpa_driver_associate_params *params,
    8847             :                                   struct nl_msg *msg)
    8848             : {
    8849           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    8850             : 
    8851           0 :         if (params->bssid) {
    8852           0 :                 wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
    8853           0 :                            MAC2STR(params->bssid));
    8854           0 :                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
    8855             :         }
    8856             : 
    8857           0 :         if (params->bssid_hint) {
    8858           0 :                 wpa_printf(MSG_DEBUG, "  * bssid_hint=" MACSTR,
    8859           0 :                            MAC2STR(params->bssid_hint));
    8860           0 :                 NLA_PUT(msg, NL80211_ATTR_MAC_HINT, ETH_ALEN,
    8861             :                         params->bssid_hint);
    8862             :         }
    8863             : 
    8864           0 :         if (params->freq.freq) {
    8865           0 :                 wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq.freq);
    8866           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq.freq);
    8867           0 :                 drv->assoc_freq = params->freq.freq;
    8868             :         } else
    8869           0 :                 drv->assoc_freq = 0;
    8870             : 
    8871           0 :         if (params->freq_hint) {
    8872           0 :                 wpa_printf(MSG_DEBUG, "  * freq_hint=%d", params->freq_hint);
    8873           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ_HINT,
    8874             :                             params->freq_hint);
    8875             :         }
    8876             : 
    8877           0 :         if (params->bg_scan_period >= 0) {
    8878           0 :                 wpa_printf(MSG_DEBUG, "  * bg scan period=%d",
    8879             :                            params->bg_scan_period);
    8880           0 :                 NLA_PUT_U16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
    8881             :                             params->bg_scan_period);
    8882             :         }
    8883             : 
    8884           0 :         if (params->ssid) {
    8885           0 :                 wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
    8886           0 :                                   params->ssid, params->ssid_len);
    8887           0 :                 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
    8888             :                         params->ssid);
    8889           0 :                 if (params->ssid_len > sizeof(drv->ssid))
    8890           0 :                         goto nla_put_failure;
    8891           0 :                 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
    8892           0 :                 drv->ssid_len = params->ssid_len;
    8893             :         }
    8894             : 
    8895           0 :         wpa_hexdump(MSG_DEBUG, "  * IEs", params->wpa_ie, params->wpa_ie_len);
    8896           0 :         if (params->wpa_ie)
    8897           0 :                 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
    8898             :                         params->wpa_ie);
    8899             : 
    8900           0 :         if (params->wpa_proto) {
    8901           0 :                 enum nl80211_wpa_versions ver = 0;
    8902             : 
    8903           0 :                 if (params->wpa_proto & WPA_PROTO_WPA)
    8904           0 :                         ver |= NL80211_WPA_VERSION_1;
    8905           0 :                 if (params->wpa_proto & WPA_PROTO_RSN)
    8906           0 :                         ver |= NL80211_WPA_VERSION_2;
    8907             : 
    8908           0 :                 wpa_printf(MSG_DEBUG, "  * WPA Versions 0x%x", ver);
    8909           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
    8910             :         }
    8911             : 
    8912           0 :         if (params->pairwise_suite != WPA_CIPHER_NONE) {
    8913           0 :                 u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
    8914           0 :                 wpa_printf(MSG_DEBUG, "  * pairwise=0x%x", cipher);
    8915           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
    8916             :         }
    8917             : 
    8918           0 :         if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
    8919           0 :             !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
    8920             :                 /*
    8921             :                  * This is likely to work even though many drivers do not
    8922             :                  * advertise support for operations without GTK.
    8923             :                  */
    8924           0 :                 wpa_printf(MSG_DEBUG, "  * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
    8925           0 :         } else if (params->group_suite != WPA_CIPHER_NONE) {
    8926           0 :                 u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
    8927           0 :                 wpa_printf(MSG_DEBUG, "  * group=0x%x", cipher);
    8928           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
    8929             :         }
    8930             : 
    8931           0 :         if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
    8932           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
    8933           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
    8934           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
    8935           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
    8936           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
    8937           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
    8938           0 :             params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
    8939           0 :                 int mgmt = WLAN_AKM_SUITE_PSK;
    8940             : 
    8941           0 :                 switch (params->key_mgmt_suite) {
    8942             :                 case WPA_KEY_MGMT_CCKM:
    8943           0 :                         mgmt = WLAN_AKM_SUITE_CCKM;
    8944           0 :                         break;
    8945             :                 case WPA_KEY_MGMT_IEEE8021X:
    8946           0 :                         mgmt = WLAN_AKM_SUITE_8021X;
    8947           0 :                         break;
    8948             :                 case WPA_KEY_MGMT_FT_IEEE8021X:
    8949           0 :                         mgmt = WLAN_AKM_SUITE_FT_8021X;
    8950           0 :                         break;
    8951             :                 case WPA_KEY_MGMT_FT_PSK:
    8952           0 :                         mgmt = WLAN_AKM_SUITE_FT_PSK;
    8953           0 :                         break;
    8954             :                 case WPA_KEY_MGMT_IEEE8021X_SHA256:
    8955           0 :                         mgmt = WLAN_AKM_SUITE_8021X_SHA256;
    8956           0 :                         break;
    8957             :                 case WPA_KEY_MGMT_PSK_SHA256:
    8958           0 :                         mgmt = WLAN_AKM_SUITE_PSK_SHA256;
    8959           0 :                         break;
    8960             :                 case WPA_KEY_MGMT_OSEN:
    8961           0 :                         mgmt = WLAN_AKM_SUITE_OSEN;
    8962           0 :                         break;
    8963             :                 case WPA_KEY_MGMT_PSK:
    8964             :                 default:
    8965           0 :                         mgmt = WLAN_AKM_SUITE_PSK;
    8966           0 :                         break;
    8967             :                 }
    8968           0 :                 wpa_printf(MSG_DEBUG, "  * akm=0x%x", mgmt);
    8969           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
    8970             :         }
    8971             : 
    8972           0 :         NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
    8973             : 
    8974           0 :         if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
    8975           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
    8976             : 
    8977           0 :         if (params->disable_ht)
    8978           0 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
    8979             : 
    8980           0 :         if (params->htcaps && params->htcaps_mask) {
    8981           0 :                 int sz = sizeof(struct ieee80211_ht_capabilities);
    8982           0 :                 wpa_hexdump(MSG_DEBUG, "  * htcaps", params->htcaps, sz);
    8983           0 :                 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
    8984           0 :                 wpa_hexdump(MSG_DEBUG, "  * htcaps_mask",
    8985           0 :                             params->htcaps_mask, sz);
    8986           0 :                 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
    8987             :                         params->htcaps_mask);
    8988             :         }
    8989             : 
    8990             : #ifdef CONFIG_VHT_OVERRIDES
    8991             :         if (params->disable_vht) {
    8992             :                 wpa_printf(MSG_DEBUG, "  * VHT disabled");
    8993             :                 NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
    8994             :         }
    8995             : 
    8996             :         if (params->vhtcaps && params->vhtcaps_mask) {
    8997             :                 int sz = sizeof(struct ieee80211_vht_capabilities);
    8998             :                 wpa_hexdump(MSG_DEBUG, "  * vhtcaps", params->vhtcaps, sz);
    8999             :                 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
    9000             :                 wpa_hexdump(MSG_DEBUG, "  * vhtcaps_mask",
    9001             :                             params->vhtcaps_mask, sz);
    9002             :                 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
    9003             :                         params->vhtcaps_mask);
    9004             :         }
    9005             : #endif /* CONFIG_VHT_OVERRIDES */
    9006             : 
    9007           0 :         if (params->p2p)
    9008           0 :                 wpa_printf(MSG_DEBUG, "  * P2P group");
    9009             : 
    9010           0 :         return 0;
    9011             : nla_put_failure:
    9012           0 :         return -1;
    9013             : }
    9014             : 
    9015             : 
    9016           0 : static int wpa_driver_nl80211_try_connect(
    9017             :         struct wpa_driver_nl80211_data *drv,
    9018             :         struct wpa_driver_associate_params *params)
    9019             : {
    9020             :         struct nl_msg *msg;
    9021             :         enum nl80211_auth_type type;
    9022             :         int ret;
    9023             :         int algs;
    9024             : 
    9025           0 :         msg = nlmsg_alloc();
    9026           0 :         if (!msg)
    9027           0 :                 return -1;
    9028             : 
    9029           0 :         wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
    9030           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_CONNECT);
    9031             : 
    9032           0 :         ret = nl80211_connect_common(drv, params, msg);
    9033           0 :         if (ret)
    9034           0 :                 goto nla_put_failure;
    9035             : 
    9036           0 :         algs = 0;
    9037           0 :         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
    9038           0 :                 algs++;
    9039           0 :         if (params->auth_alg & WPA_AUTH_ALG_SHARED)
    9040           0 :                 algs++;
    9041           0 :         if (params->auth_alg & WPA_AUTH_ALG_LEAP)
    9042           0 :                 algs++;
    9043           0 :         if (algs > 1) {
    9044           0 :                 wpa_printf(MSG_DEBUG, "  * Leave out Auth Type for automatic "
    9045             :                            "selection");
    9046           0 :                 goto skip_auth_type;
    9047             :         }
    9048             : 
    9049           0 :         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
    9050           0 :                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
    9051           0 :         else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
    9052           0 :                 type = NL80211_AUTHTYPE_SHARED_KEY;
    9053           0 :         else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
    9054           0 :                 type = NL80211_AUTHTYPE_NETWORK_EAP;
    9055           0 :         else if (params->auth_alg & WPA_AUTH_ALG_FT)
    9056           0 :                 type = NL80211_AUTHTYPE_FT;
    9057             :         else
    9058           0 :                 goto nla_put_failure;
    9059             : 
    9060           0 :         wpa_printf(MSG_DEBUG, "  * Auth Type %d", type);
    9061           0 :         NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
    9062             : 
    9063             : skip_auth_type:
    9064           0 :         ret = nl80211_set_conn_keys(params, msg);
    9065           0 :         if (ret)
    9066           0 :                 goto nla_put_failure;
    9067             : 
    9068           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    9069           0 :         msg = NULL;
    9070           0 :         if (ret) {
    9071           0 :                 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
    9072             :                            "(%s)", ret, strerror(-ret));
    9073           0 :                 goto nla_put_failure;
    9074             :         }
    9075           0 :         ret = 0;
    9076           0 :         wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
    9077             : 
    9078             : nla_put_failure:
    9079           0 :         nlmsg_free(msg);
    9080           0 :         return ret;
    9081             : 
    9082             : }
    9083             : 
    9084             : 
    9085           0 : static int wpa_driver_nl80211_connect(
    9086             :         struct wpa_driver_nl80211_data *drv,
    9087             :         struct wpa_driver_associate_params *params)
    9088             : {
    9089           0 :         int ret = wpa_driver_nl80211_try_connect(drv, params);
    9090           0 :         if (ret == -EALREADY) {
    9091             :                 /*
    9092             :                  * cfg80211 does not currently accept new connections if
    9093             :                  * we are already connected. As a workaround, force
    9094             :                  * disconnection and try again.
    9095             :                  */
    9096           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
    9097             :                            "disconnecting before reassociation "
    9098             :                            "attempt");
    9099           0 :                 if (wpa_driver_nl80211_disconnect(
    9100             :                             drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
    9101           0 :                         return -1;
    9102           0 :                 ret = wpa_driver_nl80211_try_connect(drv, params);
    9103             :         }
    9104           0 :         return ret;
    9105             : }
    9106             : 
    9107             : 
    9108           0 : static int wpa_driver_nl80211_associate(
    9109             :         void *priv, struct wpa_driver_associate_params *params)
    9110             : {
    9111           0 :         struct i802_bss *bss = priv;
    9112           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9113             :         int ret;
    9114             :         struct nl_msg *msg;
    9115             : 
    9116           0 :         if (params->mode == IEEE80211_MODE_AP)
    9117           0 :                 return wpa_driver_nl80211_ap(drv, params);
    9118             : 
    9119           0 :         if (params->mode == IEEE80211_MODE_IBSS)
    9120           0 :                 return wpa_driver_nl80211_ibss(drv, params);
    9121             : 
    9122           0 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
    9123           0 :                 enum nl80211_iftype nlmode = params->p2p ?
    9124             :                         NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
    9125             : 
    9126           0 :                 if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
    9127           0 :                         return -1;
    9128           0 :                 return wpa_driver_nl80211_connect(drv, params);
    9129             :         }
    9130             : 
    9131           0 :         nl80211_mark_disconnected(drv);
    9132             : 
    9133           0 :         msg = nlmsg_alloc();
    9134           0 :         if (!msg)
    9135           0 :                 return -1;
    9136             : 
    9137           0 :         wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
    9138             :                    drv->ifindex);
    9139           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_ASSOCIATE);
    9140             : 
    9141           0 :         ret = nl80211_connect_common(drv, params, msg);
    9142           0 :         if (ret)
    9143           0 :                 goto nla_put_failure;
    9144             : 
    9145           0 :         if (params->prev_bssid) {
    9146           0 :                 wpa_printf(MSG_DEBUG, "  * prev_bssid=" MACSTR,
    9147           0 :                            MAC2STR(params->prev_bssid));
    9148           0 :                 NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
    9149             :                         params->prev_bssid);
    9150             :         }
    9151             : 
    9152           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    9153           0 :         msg = NULL;
    9154           0 :         if (ret) {
    9155           0 :                 wpa_dbg(drv->ctx, MSG_DEBUG,
    9156             :                         "nl80211: MLME command failed (assoc): ret=%d (%s)",
    9157             :                         ret, strerror(-ret));
    9158           0 :                 nl80211_dump_scan(drv);
    9159           0 :                 goto nla_put_failure;
    9160             :         }
    9161           0 :         ret = 0;
    9162           0 :         wpa_printf(MSG_DEBUG, "nl80211: Association request send "
    9163             :                    "successfully");
    9164             : 
    9165             : nla_put_failure:
    9166           0 :         nlmsg_free(msg);
    9167           0 :         return ret;
    9168             : }
    9169             : 
    9170             : 
    9171        1262 : static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
    9172             :                             int ifindex, enum nl80211_iftype mode)
    9173             : {
    9174             :         struct nl_msg *msg;
    9175        1262 :         int ret = -ENOBUFS;
    9176             : 
    9177        1262 :         wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
    9178             :                    ifindex, mode, nl80211_iftype_str(mode));
    9179             : 
    9180        1262 :         msg = nlmsg_alloc();
    9181        1262 :         if (!msg)
    9182           0 :                 return -ENOMEM;
    9183             : 
    9184        1262 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_INTERFACE);
    9185        1262 :         if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
    9186           0 :                 goto nla_put_failure;
    9187        1262 :         NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
    9188             : 
    9189        1262 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    9190        1262 :         msg = NULL;
    9191        1262 :         if (!ret)
    9192        1262 :                 return 0;
    9193             : nla_put_failure:
    9194           0 :         nlmsg_free(msg);
    9195           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
    9196             :                    " %d (%s)", ifindex, mode, ret, strerror(-ret));
    9197           0 :         return ret;
    9198             : }
    9199             : 
    9200             : 
    9201        1262 : static int wpa_driver_nl80211_set_mode_impl(
    9202             :                 struct i802_bss *bss,
    9203             :                 enum nl80211_iftype nlmode,
    9204             :                 struct hostapd_freq_params *desired_freq_params)
    9205             : {
    9206        1262 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9207        1262 :         int ret = -1;
    9208             :         int i;
    9209        1262 :         int was_ap = is_ap_interface(drv->nlmode);
    9210             :         int res;
    9211             :         int mode_switch_res;
    9212             : 
    9213        1262 :         mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
    9214        1262 :         if (mode_switch_res && nlmode == nl80211_get_ifmode(bss))
    9215           0 :                 mode_switch_res = 0;
    9216             : 
    9217        1262 :         if (mode_switch_res == 0) {
    9218        1262 :                 drv->nlmode = nlmode;
    9219        1262 :                 ret = 0;
    9220        1262 :                 goto done;
    9221             :         }
    9222             : 
    9223           0 :         if (mode_switch_res == -ENODEV)
    9224           0 :                 return -1;
    9225             : 
    9226           0 :         if (nlmode == drv->nlmode) {
    9227           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
    9228             :                            "requested mode - ignore error");
    9229           0 :                 ret = 0;
    9230           0 :                 goto done; /* Already in the requested mode */
    9231             :         }
    9232             : 
    9233             :         /* mac80211 doesn't allow mode changes while the device is up, so
    9234             :          * take the device down, try to set the mode again, and bring the
    9235             :          * device back up.
    9236             :          */
    9237           0 :         wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
    9238             :                    "interface down");
    9239           0 :         for (i = 0; i < 10; i++) {
    9240           0 :                 res = i802_set_iface_flags(bss, 0);
    9241           0 :                 if (res == -EACCES || res == -ENODEV)
    9242             :                         break;
    9243           0 :                 if (res != 0) {
    9244           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
    9245             :                                    "interface down");
    9246           0 :                         os_sleep(0, 100000);
    9247           0 :                         continue;
    9248             :                 }
    9249             : 
    9250             :                 /*
    9251             :                  * Setting the mode will fail for some drivers if the phy is
    9252             :                  * on a frequency that the mode is disallowed in.
    9253             :                  */
    9254           0 :                 if (desired_freq_params) {
    9255           0 :                         res = i802_set_freq(bss, desired_freq_params);
    9256           0 :                         if (res) {
    9257           0 :                                 wpa_printf(MSG_DEBUG,
    9258             :                                            "nl80211: Failed to set frequency on interface");
    9259             :                         }
    9260             :                 }
    9261             : 
    9262             :                 /* Try to set the mode again while the interface is down */
    9263           0 :                 mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
    9264           0 :                 if (mode_switch_res == -EBUSY) {
    9265           0 :                         wpa_printf(MSG_DEBUG,
    9266             :                                    "nl80211: Delaying mode set while interface going down");
    9267           0 :                         os_sleep(0, 100000);
    9268           0 :                         continue;
    9269             :                 }
    9270           0 :                 ret = mode_switch_res;
    9271           0 :                 break;
    9272             :         }
    9273             : 
    9274           0 :         if (!ret) {
    9275           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
    9276             :                            "interface is down");
    9277           0 :                 drv->nlmode = nlmode;
    9278           0 :                 drv->ignore_if_down_event = 1;
    9279             :         }
    9280             : 
    9281             :         /* Bring the interface back up */
    9282           0 :         res = linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
    9283           0 :         if (res != 0) {
    9284           0 :                 wpa_printf(MSG_DEBUG,
    9285             :                            "nl80211: Failed to set interface up after switching mode");
    9286           0 :                 ret = -1;
    9287             :         }
    9288             : 
    9289             : done:
    9290        1262 :         if (ret) {
    9291           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
    9292           0 :                            "from %d failed", nlmode, drv->nlmode);
    9293           0 :                 return ret;
    9294             :         }
    9295             : 
    9296        1262 :         if (is_p2p_net_interface(nlmode))
    9297           0 :                 nl80211_disable_11b_rates(drv, drv->ifindex, 1);
    9298        1262 :         else if (drv->disabled_11b_rates)
    9299           0 :                 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
    9300             : 
    9301        1262 :         if (is_ap_interface(nlmode)) {
    9302         631 :                 nl80211_mgmt_unsubscribe(bss, "start AP");
    9303             :                 /* Setup additional AP mode functionality if needed */
    9304         631 :                 if (nl80211_setup_ap(bss))
    9305           0 :                         return -1;
    9306         631 :         } else if (was_ap) {
    9307             :                 /* Remove additional AP mode functionality */
    9308         631 :                 nl80211_teardown_ap(bss);
    9309             :         } else {
    9310           0 :                 nl80211_mgmt_unsubscribe(bss, "mode change");
    9311             :         }
    9312             : 
    9313        1262 :         if (!bss->in_deinit && !is_ap_interface(nlmode) &&
    9314           0 :             nl80211_mgmt_subscribe_non_ap(bss) < 0)
    9315           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
    9316             :                            "frame processing - ignore for now");
    9317             : 
    9318        1262 :         return 0;
    9319             : }
    9320             : 
    9321             : 
    9322           0 : static int dfs_info_handler(struct nl_msg *msg, void *arg)
    9323             : {
    9324             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    9325           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    9326           0 :         int *dfs_capability_ptr = arg;
    9327             : 
    9328           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    9329             :                   genlmsg_attrlen(gnlh, 0), NULL);
    9330             : 
    9331           0 :         if (tb[NL80211_ATTR_VENDOR_DATA]) {
    9332           0 :                 struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
    9333             :                 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
    9334             : 
    9335           0 :                 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
    9336           0 :                           nla_data(nl_vend), nla_len(nl_vend), NULL);
    9337             : 
    9338           0 :                 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
    9339             :                         u32 val;
    9340           0 :                         val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
    9341           0 :                         wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
    9342             :                                    val);
    9343           0 :                         *dfs_capability_ptr = val;
    9344             :                 }
    9345             :         }
    9346             : 
    9347           0 :         return NL_SKIP;
    9348             : }
    9349             : 
    9350             : 
    9351        1262 : static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
    9352             :                                        enum nl80211_iftype nlmode)
    9353             : {
    9354        1262 :         return wpa_driver_nl80211_set_mode_impl(bss, nlmode, NULL);
    9355             : }
    9356             : 
    9357             : 
    9358           0 : static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
    9359             :                                             struct hostapd_freq_params *freq)
    9360             : {
    9361           0 :         return wpa_driver_nl80211_set_mode_impl(bss, NL80211_IFTYPE_ADHOC,
    9362             :                                                 freq);
    9363             : }
    9364             : 
    9365             : 
    9366         631 : static int wpa_driver_nl80211_get_capa(void *priv,
    9367             :                                        struct wpa_driver_capa *capa)
    9368             : {
    9369         631 :         struct i802_bss *bss = priv;
    9370         631 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9371             :         struct nl_msg *msg;
    9372         631 :         int dfs_capability = 0;
    9373         631 :         int ret = 0;
    9374             : 
    9375         631 :         if (!drv->has_capability)
    9376           0 :                 return -1;
    9377         631 :         os_memcpy(capa, &drv->capa, sizeof(*capa));
    9378         631 :         if (drv->extended_capa && drv->extended_capa_mask) {
    9379         631 :                 capa->extended_capa = drv->extended_capa;
    9380         631 :                 capa->extended_capa_mask = drv->extended_capa_mask;
    9381         631 :                 capa->extended_capa_len = drv->extended_capa_len;
    9382             :         }
    9383             : 
    9384        1262 :         if ((capa->flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
    9385         631 :             !drv->allow_p2p_device) {
    9386         631 :                 wpa_printf(MSG_DEBUG, "nl80211: Do not indicate P2P_DEVICE support (p2p_device=1 driver param not specified)");
    9387         631 :                 capa->flags &= ~WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
    9388             :         }
    9389             : 
    9390         631 :         if (drv->dfs_vendor_cmd_avail == 1) {
    9391           0 :                 msg = nlmsg_alloc();
    9392           0 :                 if (!msg)
    9393           0 :                         return -ENOMEM;
    9394             : 
    9395           0 :                 nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
    9396             : 
    9397           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    9398           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
    9399           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD,
    9400             :                             QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY);
    9401             : 
    9402           0 :                 ret = send_and_recv_msgs(drv, msg, dfs_info_handler,
    9403             :                                          &dfs_capability);
    9404           0 :                 if (!ret) {
    9405           0 :                         if (dfs_capability)
    9406           0 :                                 capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
    9407             :                 }
    9408             :         }
    9409             : 
    9410         631 :         return ret;
    9411             : 
    9412             :  nla_put_failure:
    9413           0 :         nlmsg_free(msg);
    9414           0 :         return -ENOBUFS;
    9415             : }
    9416             : 
    9417             : 
    9418         633 : static int wpa_driver_nl80211_set_operstate(void *priv, int state)
    9419             : {
    9420         633 :         struct i802_bss *bss = priv;
    9421         633 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9422             : 
    9423        1266 :         wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
    9424         633 :                    bss->ifname, drv->operstate, state,
    9425             :                    state ? "UP" : "DORMANT");
    9426         633 :         drv->operstate = state;
    9427         633 :         return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
    9428             :                                       state ? IF_OPER_UP : IF_OPER_DORMANT);
    9429             : }
    9430             : 
    9431             : 
    9432           0 : static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
    9433             : {
    9434           0 :         struct i802_bss *bss = priv;
    9435           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9436             :         struct nl_msg *msg;
    9437             :         struct nl80211_sta_flag_update upd;
    9438           0 :         int ret = -ENOBUFS;
    9439             : 
    9440           0 :         if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
    9441           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
    9442           0 :                 return 0;
    9443             :         }
    9444             : 
    9445           0 :         wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
    9446           0 :                    MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
    9447             : 
    9448           0 :         msg = nlmsg_alloc();
    9449           0 :         if (!msg)
    9450           0 :                 return -ENOMEM;
    9451             : 
    9452           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
    9453             : 
    9454           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
    9455             :                     if_nametoindex(bss->ifname));
    9456           0 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
    9457             : 
    9458           0 :         os_memset(&upd, 0, sizeof(upd));
    9459           0 :         upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
    9460           0 :         if (authorized)
    9461           0 :                 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
    9462           0 :         NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
    9463             : 
    9464           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    9465           0 :         msg = NULL;
    9466           0 :         if (!ret)
    9467           0 :                 return 0;
    9468             :  nla_put_failure:
    9469           0 :         nlmsg_free(msg);
    9470           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
    9471             :                    ret, strerror(-ret));
    9472           0 :         return ret;
    9473             : }
    9474             : 
    9475             : 
    9476             : /* Set kernel driver on given frequency (MHz) */
    9477         618 : static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
    9478             : {
    9479         618 :         struct i802_bss *bss = priv;
    9480         618 :         return nl80211_set_channel(bss, freq, 0);
    9481             : }
    9482             : 
    9483             : 
    9484         840 : static inline int min_int(int a, int b)
    9485             : {
    9486         840 :         if (a < b)
    9487           0 :                 return a;
    9488         840 :         return b;
    9489             : }
    9490             : 
    9491             : 
    9492         840 : static int get_key_handler(struct nl_msg *msg, void *arg)
    9493             : {
    9494             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    9495         840 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    9496             : 
    9497         840 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    9498             :                   genlmsg_attrlen(gnlh, 0), NULL);
    9499             : 
    9500             :         /*
    9501             :          * TODO: validate the key index and mac address!
    9502             :          * Otherwise, there's a race condition as soon as
    9503             :          * the kernel starts sending key notifications.
    9504             :          */
    9505             : 
    9506         840 :         if (tb[NL80211_ATTR_KEY_SEQ])
    9507         840 :                 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
    9508         840 :                        min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
    9509         840 :         return NL_SKIP;
    9510             : }
    9511             : 
    9512             : 
    9513         840 : static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
    9514             :                            int idx, u8 *seq)
    9515             : {
    9516         840 :         struct i802_bss *bss = priv;
    9517         840 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9518             :         struct nl_msg *msg;
    9519             : 
    9520         840 :         msg = nlmsg_alloc();
    9521         840 :         if (!msg)
    9522           0 :                 return -ENOMEM;
    9523             : 
    9524         840 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_KEY);
    9525             : 
    9526         840 :         if (addr)
    9527           0 :                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
    9528         840 :         NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
    9529         840 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
    9530             : 
    9531         840 :         memset(seq, 0, 6);
    9532             : 
    9533         840 :         return send_and_recv_msgs(drv, msg, get_key_handler, seq);
    9534             :  nla_put_failure:
    9535           0 :         nlmsg_free(msg);
    9536           0 :         return -ENOBUFS;
    9537             : }
    9538             : 
    9539             : 
    9540           1 : static int i802_set_rts(void *priv, int rts)
    9541             : {
    9542           1 :         struct i802_bss *bss = priv;
    9543           1 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9544             :         struct nl_msg *msg;
    9545           1 :         int ret = -ENOBUFS;
    9546             :         u32 val;
    9547             : 
    9548           1 :         msg = nlmsg_alloc();
    9549           1 :         if (!msg)
    9550           0 :                 return -ENOMEM;
    9551             : 
    9552           1 :         if (rts >= 2347)
    9553           0 :                 val = (u32) -1;
    9554             :         else
    9555           1 :                 val = rts;
    9556             : 
    9557           1 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
    9558           1 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    9559           1 :         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
    9560             : 
    9561           1 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    9562           1 :         msg = NULL;
    9563           1 :         if (!ret)
    9564           1 :                 return 0;
    9565             : nla_put_failure:
    9566           0 :         nlmsg_free(msg);
    9567           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
    9568             :                    "%d (%s)", rts, ret, strerror(-ret));
    9569           0 :         return ret;
    9570             : }
    9571             : 
    9572             : 
    9573           3 : static int i802_set_frag(void *priv, int frag)
    9574             : {
    9575           3 :         struct i802_bss *bss = priv;
    9576           3 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9577             :         struct nl_msg *msg;
    9578           3 :         int ret = -ENOBUFS;
    9579             :         u32 val;
    9580             : 
    9581           3 :         msg = nlmsg_alloc();
    9582           3 :         if (!msg)
    9583           0 :                 return -ENOMEM;
    9584             : 
    9585           3 :         if (frag >= 2346)
    9586           0 :                 val = (u32) -1;
    9587             :         else
    9588           3 :                 val = frag;
    9589             : 
    9590           3 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
    9591           3 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
    9592           3 :         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
    9593             : 
    9594           3 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    9595           3 :         msg = NULL;
    9596           3 :         if (!ret)
    9597           3 :                 return 0;
    9598             : nla_put_failure:
    9599           0 :         nlmsg_free(msg);
    9600           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
    9601             :                    "%d: %d (%s)", frag, ret, strerror(-ret));
    9602           0 :         return ret;
    9603             : }
    9604             : 
    9605             : 
    9606         673 : static int i802_flush(void *priv)
    9607             : {
    9608         673 :         struct i802_bss *bss = priv;
    9609         673 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9610             :         struct nl_msg *msg;
    9611             :         int res;
    9612             : 
    9613         673 :         msg = nlmsg_alloc();
    9614         673 :         if (!msg)
    9615           0 :                 return -1;
    9616             : 
    9617         673 :         wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
    9618         673 :                    bss->ifname);
    9619         673 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
    9620             : 
    9621             :         /*
    9622             :          * XXX: FIX! this needs to flush all VLANs too
    9623             :          */
    9624         673 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
    9625             :                     if_nametoindex(bss->ifname));
    9626             : 
    9627         673 :         res = send_and_recv_msgs(drv, msg, NULL, NULL);
    9628         673 :         if (res) {
    9629           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
    9630             :                            "(%s)", res, strerror(-res));
    9631             :         }
    9632         673 :         return res;
    9633             :  nla_put_failure:
    9634           0 :         nlmsg_free(msg);
    9635           0 :         return -ENOBUFS;
    9636             : }
    9637             : 
    9638             : 
    9639          52 : static int get_sta_handler(struct nl_msg *msg, void *arg)
    9640             : {
    9641             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
    9642          52 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
    9643          52 :         struct hostap_sta_driver_data *data = arg;
    9644             :         struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
    9645             :         static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
    9646             :                 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
    9647             :                 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
    9648             :                 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
    9649             :                 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
    9650             :                 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
    9651             :                 [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
    9652             :         };
    9653             : 
    9654          52 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
    9655             :                   genlmsg_attrlen(gnlh, 0), NULL);
    9656             : 
    9657             :         /*
    9658             :          * TODO: validate the interface and mac address!
    9659             :          * Otherwise, there's a race condition as soon as
    9660             :          * the kernel starts sending station notifications.
    9661             :          */
    9662             : 
    9663          52 :         if (!tb[NL80211_ATTR_STA_INFO]) {
    9664           0 :                 wpa_printf(MSG_DEBUG, "sta stats missing!");
    9665           0 :                 return NL_SKIP;
    9666             :         }
    9667          52 :         if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
    9668             :                              tb[NL80211_ATTR_STA_INFO],
    9669             :                              stats_policy)) {
    9670           0 :                 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
    9671           0 :                 return NL_SKIP;
    9672             :         }
    9673             : 
    9674          52 :         if (stats[NL80211_STA_INFO_INACTIVE_TIME])
    9675          52 :                 data->inactive_msec =
    9676          52 :                         nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
    9677          52 :         if (stats[NL80211_STA_INFO_RX_BYTES])
    9678          52 :                 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
    9679          52 :         if (stats[NL80211_STA_INFO_TX_BYTES])
    9680          52 :                 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
    9681          52 :         if (stats[NL80211_STA_INFO_RX_PACKETS])
    9682          52 :                 data->rx_packets =
    9683          52 :                         nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
    9684          52 :         if (stats[NL80211_STA_INFO_TX_PACKETS])
    9685          52 :                 data->tx_packets =
    9686          52 :                         nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
    9687          52 :         if (stats[NL80211_STA_INFO_TX_FAILED])
    9688          52 :                 data->tx_retry_failed =
    9689          52 :                         nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
    9690             : 
    9691          52 :         return NL_SKIP;
    9692             : }
    9693             : 
    9694          53 : static int i802_read_sta_data(struct i802_bss *bss,
    9695             :                               struct hostap_sta_driver_data *data,
    9696             :                               const u8 *addr)
    9697             : {
    9698          53 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9699             :         struct nl_msg *msg;
    9700             : 
    9701          53 :         os_memset(data, 0, sizeof(*data));
    9702          53 :         msg = nlmsg_alloc();
    9703          53 :         if (!msg)
    9704           0 :                 return -ENOMEM;
    9705             : 
    9706          53 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
    9707             : 
    9708          53 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
    9709          53 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
    9710             : 
    9711          53 :         return send_and_recv_msgs(drv, msg, get_sta_handler, data);
    9712             :  nla_put_failure:
    9713           0 :         nlmsg_free(msg);
    9714           0 :         return -ENOBUFS;
    9715             : }
    9716             : 
    9717             : 
    9718        2456 : static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
    9719             :                                     int cw_min, int cw_max, int burst_time)
    9720             : {
    9721        2456 :         struct i802_bss *bss = priv;
    9722        2456 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9723             :         struct nl_msg *msg;
    9724             :         struct nlattr *txq, *params;
    9725             : 
    9726        2456 :         msg = nlmsg_alloc();
    9727        2456 :         if (!msg)
    9728           0 :                 return -1;
    9729             : 
    9730        2456 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
    9731             : 
    9732        2456 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
    9733             : 
    9734        2456 :         txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
    9735        2456 :         if (!txq)
    9736           0 :                 goto nla_put_failure;
    9737             : 
    9738             :         /* We are only sending parameters for a single TXQ at a time */
    9739        2456 :         params = nla_nest_start(msg, 1);
    9740        2456 :         if (!params)
    9741           0 :                 goto nla_put_failure;
    9742             : 
    9743        2456 :         switch (queue) {
    9744             :         case 0:
    9745         614 :                 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO);
    9746         614 :                 break;
    9747             :         case 1:
    9748         614 :                 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI);
    9749         614 :                 break;
    9750             :         case 2:
    9751         614 :                 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE);
    9752         614 :                 break;
    9753             :         case 3:
    9754         614 :                 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK);
    9755         614 :                 break;
    9756             :         }
    9757             :         /* Burst time is configured in units of 0.1 msec and TXOP parameter in
    9758             :          * 32 usec, so need to convert the value here. */
    9759        2456 :         NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
    9760        2456 :         NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
    9761        2456 :         NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
    9762        2456 :         NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
    9763             : 
    9764        2456 :         nla_nest_end(msg, params);
    9765             : 
    9766        2456 :         nla_nest_end(msg, txq);
    9767             : 
    9768        2456 :         if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
    9769        2456 :                 return 0;
    9770           0 :         msg = NULL;
    9771             :  nla_put_failure:
    9772           0 :         nlmsg_free(msg);
    9773           0 :         return -1;
    9774             : }
    9775             : 
    9776             : 
    9777          14 : static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
    9778             :                              const char *ifname, int vlan_id)
    9779             : {
    9780          14 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9781             :         struct nl_msg *msg;
    9782          14 :         int ret = -ENOBUFS;
    9783             : 
    9784          14 :         msg = nlmsg_alloc();
    9785          14 :         if (!msg)
    9786           0 :                 return -ENOMEM;
    9787             : 
    9788         126 :         wpa_printf(MSG_DEBUG, "nl80211: %s[%d]: set_sta_vlan(" MACSTR
    9789             :                    ", ifname=%s[%d], vlan_id=%d)",
    9790          28 :                    bss->ifname, if_nametoindex(bss->ifname),
    9791          84 :                    MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
    9792          14 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
    9793             : 
    9794          14 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
    9795             :                     if_nametoindex(bss->ifname));
    9796          14 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
    9797          14 :         NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
    9798             :                     if_nametoindex(ifname));
    9799             : 
    9800          14 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
    9801          14 :         msg = NULL;
    9802          14 :         if (ret < 0) {
    9803           0 :                 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
    9804             :                            MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
    9805           0 :                            MAC2STR(addr), ifname, vlan_id, ret,
    9806             :                            strerror(-ret));
    9807             :         }
    9808             :  nla_put_failure:
    9809          14 :         nlmsg_free(msg);
    9810          14 :         return ret;
    9811             : }
    9812             : 
    9813             : 
    9814           6 : static int i802_get_inact_sec(void *priv, const u8 *addr)
    9815             : {
    9816             :         struct hostap_sta_driver_data data;
    9817             :         int ret;
    9818             : 
    9819           6 :         data.inactive_msec = (unsigned long) -1;
    9820           6 :         ret = i802_read_sta_data(priv, &data, addr);
    9821           6 :         if (ret || data.inactive_msec == (unsigned long) -1)
    9822           0 :                 return -1;
    9823           6 :         return data.inactive_msec / 1000;
    9824             : }
    9825             : 
    9826             : 
    9827         771 : static int i802_sta_clear_stats(void *priv, const u8 *addr)
    9828             : {
    9829             : #if 0
    9830             :         /* TODO */
    9831             : #endif
    9832         771 :         return 0;
    9833             : }
    9834             : 
    9835             : 
    9836        1492 : static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
    9837             :                            int reason)
    9838             : {
    9839        1492 :         struct i802_bss *bss = priv;
    9840        1492 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9841             :         struct ieee80211_mgmt mgmt;
    9842             : 
    9843        1492 :         if (drv->device_ap_sme)
    9844           0 :                 return wpa_driver_nl80211_sta_remove(bss, addr);
    9845             : 
    9846        1492 :         memset(&mgmt, 0, sizeof(mgmt));
    9847        1492 :         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    9848             :                                           WLAN_FC_STYPE_DEAUTH);
    9849        1492 :         memcpy(mgmt.da, addr, ETH_ALEN);
    9850        1492 :         memcpy(mgmt.sa, own_addr, ETH_ALEN);
    9851        1492 :         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
    9852        1492 :         mgmt.u.deauth.reason_code = host_to_le16(reason);
    9853        1492 :         return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
    9854             :                                             IEEE80211_HDRLEN +
    9855             :                                             sizeof(mgmt.u.deauth), 0, 0, 0, 0,
    9856             :                                             0);
    9857             : }
    9858             : 
    9859             : 
    9860           3 : static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
    9861             :                              int reason)
    9862             : {
    9863           3 :         struct i802_bss *bss = priv;
    9864           3 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9865             :         struct ieee80211_mgmt mgmt;
    9866             : 
    9867           3 :         if (drv->device_ap_sme)
    9868           0 :                 return wpa_driver_nl80211_sta_remove(bss, addr);
    9869             : 
    9870           3 :         memset(&mgmt, 0, sizeof(mgmt));
    9871           3 :         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    9872             :                                           WLAN_FC_STYPE_DISASSOC);
    9873           3 :         memcpy(mgmt.da, addr, ETH_ALEN);
    9874           3 :         memcpy(mgmt.sa, own_addr, ETH_ALEN);
    9875           3 :         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
    9876           3 :         mgmt.u.disassoc.reason_code = host_to_le16(reason);
    9877           3 :         return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
    9878             :                                             IEEE80211_HDRLEN +
    9879             :                                             sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
    9880             :                                             0);
    9881             : }
    9882             : 
    9883             : 
    9884         716 : static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
    9885             : {
    9886             :         char buf[200], *pos, *end;
    9887             :         int i, res;
    9888             : 
    9889         716 :         pos = buf;
    9890         716 :         end = pos + sizeof(buf);
    9891             : 
    9892       12172 :         for (i = 0; i < drv->num_if_indices; i++) {
    9893       11456 :                 if (!drv->if_indices[i])
    9894       10615 :                         continue;
    9895         841 :                 res = os_snprintf(pos, end - pos, " %d", drv->if_indices[i]);
    9896         841 :                 if (res < 0 || res >= end - pos)
    9897             :                         break;
    9898         841 :                 pos += res;
    9899             :         }
    9900         716 :         *pos = '\0';
    9901             : 
    9902         716 :         wpa_printf(MSG_DEBUG, "nl80211: if_indices[%d]:%s",
    9903             :                    drv->num_if_indices, buf);
    9904         716 : }
    9905             : 
    9906             : 
    9907         776 : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
    9908             : {
    9909             :         int i;
    9910             :         int *old;
    9911             : 
    9912         776 :         wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
    9913             :                    ifidx);
    9914         776 :         if (have_ifidx(drv, ifidx)) {
    9915          97 :                 wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
    9916             :                            ifidx);
    9917          97 :                 return;
    9918             :         }
    9919         767 :         for (i = 0; i < drv->num_if_indices; i++) {
    9920         767 :                 if (drv->if_indices[i] == 0) {
    9921         679 :                         drv->if_indices[i] = ifidx;
    9922         679 :                         dump_ifidx(drv);
    9923         679 :                         return;
    9924             :                 }
    9925             :         }
    9926             : 
    9927           0 :         if (drv->if_indices != drv->default_if_indices)
    9928           0 :                 old = drv->if_indices;
    9929             :         else
    9930           0 :                 old = NULL;
    9931             : 
    9932           0 :         drv->if_indices = os_realloc_array(old, drv->num_if_indices + 1,
    9933             :                                            sizeof(int));
    9934           0 :         if (!drv->if_indices) {
    9935           0 :                 if (!old)
    9936           0 :                         drv->if_indices = drv->default_if_indices;
    9937             :                 else
    9938           0 :                         drv->if_indices = old;
    9939           0 :                 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
    9940             :                            "interfaces");
    9941           0 :                 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
    9942           0 :                 return;
    9943           0 :         } else if (!old)
    9944           0 :                 os_memcpy(drv->if_indices, drv->default_if_indices,
    9945             :                           sizeof(drv->default_if_indices));
    9946           0 :         drv->if_indices[drv->num_if_indices] = ifidx;
    9947           0 :         drv->num_if_indices++;
    9948           0 :         dump_ifidx(drv);
    9949             : }
    9950             : 
    9951             : 
    9952          37 : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
    9953             : {
    9954             :         int i;
    9955             : 
    9956          91 :         for (i = 0; i < drv->num_if_indices; i++) {
    9957          91 :                 if (drv->if_indices[i] == ifidx) {
    9958          37 :                         drv->if_indices[i] = 0;
    9959          37 :                         break;
    9960             :                 }
    9961             :         }
    9962          37 :         dump_ifidx(drv);
    9963          37 : }
    9964             : 
    9965             : 
    9966       15163 : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
    9967             : {
    9968             :         int i;
    9969             : 
    9970      186342 :         for (i = 0; i < drv->num_if_indices; i++)
    9971      175680 :                 if (drv->if_indices[i] == ifidx)
    9972        4501 :                         return 1;
    9973             : 
    9974       10662 :         return 0;
    9975             : }
    9976             : 
    9977             : 
    9978           2 : static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
    9979             :                             const char *bridge_ifname, char *ifname_wds)
    9980             : {
    9981           2 :         struct i802_bss *bss = priv;
    9982           2 :         struct wpa_driver_nl80211_data *drv = bss->drv;
    9983             :         char name[IFNAMSIZ + 1];
    9984             : 
    9985           2 :         os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
    9986           2 :         if (ifname_wds)
    9987           1 :                 os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
    9988             : 
    9989          12 :         wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
    9990          12 :                    " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
    9991           2 :         if (val) {
    9992           1 :                 if (!if_nametoindex(name)) {
    9993           1 :                         if (nl80211_create_iface(drv, name,
    9994             :                                                  NL80211_IFTYPE_AP_VLAN,
    9995           1 :                                                  bss->addr, 1, NULL, NULL, 0) <
    9996             :                             0)
    9997           0 :                                 return -1;
    9998           2 :                         if (bridge_ifname &&
    9999           1 :                             linux_br_add_if(drv->global->ioctl_sock,
   10000             :                                             bridge_ifname, name) < 0)
   10001           0 :                                 return -1;
   10002             :                 }
   10003           1 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
   10004           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
   10005             :                                    "interface %s up", name);
   10006             :                 }
   10007           1 :                 return i802_set_sta_vlan(priv, addr, name, 0);
   10008             :         } else {
   10009           1 :                 if (bridge_ifname)
   10010           1 :                         linux_br_del_if(drv->global->ioctl_sock, bridge_ifname,
   10011             :                                         name);
   10012             : 
   10013           1 :                 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
   10014           1 :                 nl80211_remove_iface(drv, if_nametoindex(name));
   10015           1 :                 return 0;
   10016             :         }
   10017             : }
   10018             : 
   10019             : 
   10020       10060 : static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
   10021             : {
   10022       10060 :         struct wpa_driver_nl80211_data *drv = eloop_ctx;
   10023             :         struct sockaddr_ll lladdr;
   10024             :         unsigned char buf[3000];
   10025             :         int len;
   10026       10060 :         socklen_t fromlen = sizeof(lladdr);
   10027             : 
   10028       10060 :         len = recvfrom(sock, buf, sizeof(buf), 0,
   10029             :                        (struct sockaddr *)&lladdr, &fromlen);
   10030       10060 :         if (len < 0) {
   10031           0 :                 wpa_printf(MSG_ERROR, "nl80211: EAPOL recv failed: %s",
   10032           0 :                            strerror(errno));
   10033       10060 :                 return;
   10034             :         }
   10035             : 
   10036       10060 :         if (have_ifidx(drv, lladdr.sll_ifindex))
   10037        4171 :                 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
   10038             : }
   10039             : 
   10040             : 
   10041           5 : static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
   10042             :                              struct i802_bss *bss,
   10043             :                              const char *brname, const char *ifname)
   10044             : {
   10045             :         int ifindex;
   10046             :         char in_br[IFNAMSIZ];
   10047             : 
   10048           5 :         os_strlcpy(bss->brname, brname, IFNAMSIZ);
   10049           5 :         ifindex = if_nametoindex(brname);
   10050           5 :         if (ifindex == 0) {
   10051             :                 /*
   10052             :                  * Bridge was configured, but the bridge device does
   10053             :                  * not exist. Try to add it now.
   10054             :                  */
   10055           3 :                 if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
   10056           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
   10057             :                                    "bridge interface %s: %s",
   10058           0 :                                    brname, strerror(errno));
   10059           0 :                         return -1;
   10060             :                 }
   10061           3 :                 bss->added_bridge = 1;
   10062           3 :                 add_ifidx(drv, if_nametoindex(brname));
   10063             :         }
   10064             : 
   10065           5 :         if (linux_br_get(in_br, ifname) == 0) {
   10066           0 :                 if (os_strcmp(in_br, brname) == 0)
   10067           0 :                         return 0; /* already in the bridge */
   10068             : 
   10069           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
   10070             :                            "bridge %s", ifname, in_br);
   10071           0 :                 if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
   10072             :                     0) {
   10073           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to "
   10074             :                                    "remove interface %s from bridge "
   10075             :                                    "%s: %s",
   10076           0 :                                    ifname, brname, strerror(errno));
   10077           0 :                         return -1;
   10078             :                 }
   10079             :         }
   10080             : 
   10081           5 :         wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
   10082             :                    ifname, brname);
   10083           5 :         if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
   10084           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
   10085             :                            "into bridge %s: %s",
   10086           0 :                            ifname, brname, strerror(errno));
   10087           0 :                 return -1;
   10088             :         }
   10089           5 :         bss->added_if_into_bridge = 1;
   10090             : 
   10091           5 :         return 0;
   10092             : }
   10093             : 
   10094             : 
   10095         631 : static void *i802_init(struct hostapd_data *hapd,
   10096             :                        struct wpa_init_params *params)
   10097             : {
   10098             :         struct wpa_driver_nl80211_data *drv;
   10099             :         struct i802_bss *bss;
   10100             :         size_t i;
   10101             :         char brname[IFNAMSIZ];
   10102             :         int ifindex, br_ifindex;
   10103         631 :         int br_added = 0;
   10104             : 
   10105         631 :         bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
   10106             :                                           params->global_priv, 1,
   10107             :                                           params->bssid);
   10108         631 :         if (bss == NULL)
   10109           0 :                 return NULL;
   10110             : 
   10111         631 :         drv = bss->drv;
   10112             : 
   10113         631 :         if (linux_br_get(brname, params->ifname) == 0) {
   10114           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
   10115             :                            params->ifname, brname);
   10116           0 :                 br_ifindex = if_nametoindex(brname);
   10117             :         } else {
   10118         631 :                 brname[0] = '\0';
   10119         631 :                 br_ifindex = 0;
   10120             :         }
   10121             : 
   10122        1269 :         for (i = 0; i < params->num_bridge; i++) {
   10123         638 :                 if (params->bridge[i]) {
   10124           5 :                         ifindex = if_nametoindex(params->bridge[i]);
   10125           5 :                         if (ifindex)
   10126           2 :                                 add_ifidx(drv, ifindex);
   10127           5 :                         if (ifindex == br_ifindex)
   10128           3 :                                 br_added = 1;
   10129             :                 }
   10130             :         }
   10131         631 :         if (!br_added && br_ifindex &&
   10132           0 :             (params->num_bridge == 0 || !params->bridge[0]))
   10133           0 :                 add_ifidx(drv, br_ifindex);
   10134             : 
   10135             :         /* start listening for EAPOL on the default AP interface */
   10136         631 :         add_ifidx(drv, drv->ifindex);
   10137             : 
   10138         636 :         if (params->num_bridge && params->bridge[0] &&
   10139           5 :             i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
   10140           0 :                 goto failed;
   10141             : 
   10142             : #ifdef CONFIG_LIBNL3_ROUTE
   10143         631 :         if (bss->added_if_into_bridge) {
   10144           5 :                 drv->rtnl_sk = nl_socket_alloc();
   10145           5 :                 if (drv->rtnl_sk == NULL) {
   10146           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
   10147           0 :                         goto failed;
   10148             :                 }
   10149             : 
   10150           5 :                 if (nl_connect(drv->rtnl_sk, NETLINK_ROUTE)) {
   10151           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
   10152           0 :                                    strerror(errno));
   10153           0 :                         goto failed;
   10154             :                 }
   10155             :         }
   10156             : #endif /* CONFIG_LIBNL3_ROUTE */
   10157             : 
   10158         631 :         drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
   10159         631 :         if (drv->eapol_sock < 0) {
   10160           0 :                 wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
   10161           0 :                            strerror(errno));
   10162           0 :                 goto failed;
   10163             :         }
   10164             : 
   10165         631 :         if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
   10166             :         {
   10167           0 :                 wpa_printf(MSG_INFO, "nl80211: Could not register read socket for eapol");
   10168           0 :                 goto failed;
   10169             :         }
   10170             : 
   10171         631 :         if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
   10172             :                                params->own_addr))
   10173           0 :                 goto failed;
   10174         631 :         os_memcpy(drv->perm_addr, params->own_addr, ETH_ALEN);
   10175             : 
   10176         631 :         memcpy(bss->addr, params->own_addr, ETH_ALEN);
   10177             : 
   10178         631 :         return bss;
   10179             : 
   10180             : failed:
   10181           0 :         wpa_driver_nl80211_deinit(bss);
   10182           0 :         return NULL;
   10183             : }
   10184             : 
   10185             : 
   10186         631 : static void i802_deinit(void *priv)
   10187             : {
   10188         631 :         struct i802_bss *bss = priv;
   10189         631 :         wpa_driver_nl80211_deinit(bss);
   10190         631 : }
   10191             : 
   10192             : 
   10193          30 : static enum nl80211_iftype wpa_driver_nl80211_if_type(
   10194             :         enum wpa_driver_if_type type)
   10195             : {
   10196          30 :         switch (type) {
   10197             :         case WPA_IF_STATION:
   10198           0 :                 return NL80211_IFTYPE_STATION;
   10199             :         case WPA_IF_P2P_CLIENT:
   10200             :         case WPA_IF_P2P_GROUP:
   10201           0 :                 return NL80211_IFTYPE_P2P_CLIENT;
   10202             :         case WPA_IF_AP_VLAN:
   10203          11 :                 return NL80211_IFTYPE_AP_VLAN;
   10204             :         case WPA_IF_AP_BSS:
   10205          19 :                 return NL80211_IFTYPE_AP;
   10206             :         case WPA_IF_P2P_GO:
   10207           0 :                 return NL80211_IFTYPE_P2P_GO;
   10208             :         case WPA_IF_P2P_DEVICE:
   10209           0 :                 return NL80211_IFTYPE_P2P_DEVICE;
   10210             :         }
   10211           0 :         return -1;
   10212             : }
   10213             : 
   10214             : 
   10215             : #ifdef CONFIG_P2P
   10216             : 
   10217             : static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
   10218             : {
   10219             :         struct wpa_driver_nl80211_data *drv;
   10220             :         dl_list_for_each(drv, &global->interfaces,
   10221             :                          struct wpa_driver_nl80211_data, list) {
   10222             :                 if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
   10223             :                         return 1;
   10224             :         }
   10225             :         return 0;
   10226             : }
   10227             : 
   10228             : 
   10229             : static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data *drv,
   10230             :                                       u8 *new_addr)
   10231             : {
   10232             :         unsigned int idx;
   10233             : 
   10234             :         if (!drv->global)
   10235             :                 return -1;
   10236             : 
   10237             :         os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
   10238             :         for (idx = 0; idx < 64; idx++) {
   10239             :                 new_addr[0] = drv->first_bss->addr[0] | 0x02;
   10240             :                 new_addr[0] ^= idx << 2;
   10241             :                 if (!nl80211_addr_in_use(drv->global, new_addr))
   10242             :                         break;
   10243             :         }
   10244             :         if (idx == 64)
   10245             :                 return -1;
   10246             : 
   10247             :         wpa_printf(MSG_DEBUG, "nl80211: Assigned new P2P Interface Address "
   10248             :                    MACSTR, MAC2STR(new_addr));
   10249             : 
   10250             :         return 0;
   10251             : }
   10252             : 
   10253             : #endif /* CONFIG_P2P */
   10254             : 
   10255             : 
   10256             : struct wdev_info {
   10257             :         u64 wdev_id;
   10258             :         int wdev_id_set;
   10259             :         u8 macaddr[ETH_ALEN];
   10260             : };
   10261             : 
   10262           0 : static int nl80211_wdev_handler(struct nl_msg *msg, void *arg)
   10263             : {
   10264           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   10265             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
   10266           0 :         struct wdev_info *wi = arg;
   10267             : 
   10268           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
   10269             :                   genlmsg_attrlen(gnlh, 0), NULL);
   10270           0 :         if (tb[NL80211_ATTR_WDEV]) {
   10271           0 :                 wi->wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
   10272           0 :                 wi->wdev_id_set = 1;
   10273             :         }
   10274             : 
   10275           0 :         if (tb[NL80211_ATTR_MAC])
   10276           0 :                 os_memcpy(wi->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
   10277             :                           ETH_ALEN);
   10278             : 
   10279           0 :         return NL_SKIP;
   10280             : }
   10281             : 
   10282             : 
   10283          30 : static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
   10284             :                                      const char *ifname, const u8 *addr,
   10285             :                                      void *bss_ctx, void **drv_priv,
   10286             :                                      char *force_ifname, u8 *if_addr,
   10287             :                                      const char *bridge, int use_existing)
   10288             : {
   10289             :         enum nl80211_iftype nlmode;
   10290          30 :         struct i802_bss *bss = priv;
   10291          30 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10292             :         int ifidx;
   10293          30 :         int added = 1;
   10294             : 
   10295          30 :         if (addr)
   10296          30 :                 os_memcpy(if_addr, addr, ETH_ALEN);
   10297          30 :         nlmode = wpa_driver_nl80211_if_type(type);
   10298          30 :         if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
   10299             :                 struct wdev_info p2pdev_info;
   10300             : 
   10301           0 :                 os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
   10302           0 :                 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
   10303             :                                              0, nl80211_wdev_handler,
   10304             :                                              &p2pdev_info, use_existing);
   10305           0 :                 if (!p2pdev_info.wdev_id_set || ifidx != 0) {
   10306           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
   10307             :                                    ifname);
   10308           0 :                         return -1;
   10309             :                 }
   10310             : 
   10311           0 :                 drv->global->if_add_wdevid = p2pdev_info.wdev_id;
   10312           0 :                 drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
   10313           0 :                 if (!is_zero_ether_addr(p2pdev_info.macaddr))
   10314           0 :                         os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
   10315           0 :                 wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
   10316             :                            ifname,
   10317           0 :                            (long long unsigned int) p2pdev_info.wdev_id);
   10318             :         } else {
   10319          30 :                 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
   10320             :                                              0, NULL, NULL, use_existing);
   10321          30 :                 if (use_existing && ifidx == -ENFILE) {
   10322           0 :                         added = 0;
   10323           0 :                         ifidx = if_nametoindex(ifname);
   10324          30 :                 } else if (ifidx < 0) {
   10325           0 :                         return -1;
   10326             :                 }
   10327             :         }
   10328             : 
   10329          30 :         if (!addr) {
   10330           0 :                 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
   10331           0 :                         os_memcpy(if_addr, bss->addr, ETH_ALEN);
   10332           0 :                 else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
   10333           0 :                                             bss->ifname, if_addr) < 0) {
   10334           0 :                         if (added)
   10335           0 :                                 nl80211_remove_iface(drv, ifidx);
   10336           0 :                         return -1;
   10337             :                 }
   10338             :         }
   10339             : 
   10340             : #ifdef CONFIG_P2P
   10341             :         if (!addr &&
   10342             :             (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
   10343             :              type == WPA_IF_P2P_GO)) {
   10344             :                 /* Enforce unique P2P Interface Address */
   10345             :                 u8 new_addr[ETH_ALEN];
   10346             : 
   10347             :                 if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
   10348             :                                        new_addr) < 0) {
   10349             :                         if (added)
   10350             :                                 nl80211_remove_iface(drv, ifidx);
   10351             :                         return -1;
   10352             :                 }
   10353             :                 if (nl80211_addr_in_use(drv->global, new_addr)) {
   10354             :                         wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
   10355             :                                    "for P2P group interface");
   10356             :                         if (nl80211_p2p_interface_addr(drv, new_addr) < 0) {
   10357             :                                 if (added)
   10358             :                                         nl80211_remove_iface(drv, ifidx);
   10359             :                                 return -1;
   10360             :                         }
   10361             :                         if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
   10362             :                                                new_addr) < 0) {
   10363             :                                 if (added)
   10364             :                                         nl80211_remove_iface(drv, ifidx);
   10365             :                                 return -1;
   10366             :                         }
   10367             :                 }
   10368             :                 os_memcpy(if_addr, new_addr, ETH_ALEN);
   10369             :         }
   10370             : #endif /* CONFIG_P2P */
   10371             : 
   10372          30 :         if (type == WPA_IF_AP_BSS) {
   10373          19 :                 struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
   10374          19 :                 if (new_bss == NULL) {
   10375           0 :                         if (added)
   10376           0 :                                 nl80211_remove_iface(drv, ifidx);
   10377           0 :                         return -1;
   10378             :                 }
   10379             : 
   10380          19 :                 if (bridge &&
   10381           0 :                     i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
   10382           0 :                         wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
   10383             :                                    "interface %s to a bridge %s",
   10384             :                                    ifname, bridge);
   10385           0 :                         if (added)
   10386           0 :                                 nl80211_remove_iface(drv, ifidx);
   10387           0 :                         os_free(new_bss);
   10388           0 :                         return -1;
   10389             :                 }
   10390             : 
   10391          19 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
   10392             :                 {
   10393           0 :                         if (added)
   10394           0 :                                 nl80211_remove_iface(drv, ifidx);
   10395           0 :                         os_free(new_bss);
   10396           0 :                         return -1;
   10397             :                 }
   10398          19 :                 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
   10399          19 :                 os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
   10400          19 :                 new_bss->ifindex = ifidx;
   10401          19 :                 new_bss->drv = drv;
   10402          19 :                 new_bss->next = drv->first_bss->next;
   10403          19 :                 new_bss->freq = drv->first_bss->freq;
   10404          19 :                 new_bss->ctx = bss_ctx;
   10405          19 :                 new_bss->added_if = added;
   10406          19 :                 drv->first_bss->next = new_bss;
   10407          19 :                 if (drv_priv)
   10408          19 :                         *drv_priv = new_bss;
   10409          19 :                 nl80211_init_bss(new_bss);
   10410             : 
   10411             :                 /* Subscribe management frames for this WPA_IF_AP_BSS */
   10412          19 :                 if (nl80211_setup_ap(new_bss))
   10413           0 :                         return -1;
   10414             :         }
   10415             : 
   10416          30 :         if (drv->global)
   10417          30 :                 drv->global->if_add_ifindex = ifidx;
   10418             : 
   10419             :         /*
   10420             :          * Some virtual interfaces need to process EAPOL packets and events on
   10421             :          * the parent interface. This is used mainly with hostapd.
   10422             :          */
   10423          60 :         if (ifidx > 0 &&
   10424          30 :             (drv->hostapd ||
   10425           0 :              nlmode == NL80211_IFTYPE_AP_VLAN ||
   10426           0 :              nlmode == NL80211_IFTYPE_WDS ||
   10427             :              nlmode == NL80211_IFTYPE_MONITOR))
   10428          30 :                 add_ifidx(drv, ifidx);
   10429             : 
   10430          30 :         return 0;
   10431             : }
   10432             : 
   10433             : 
   10434          30 : static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
   10435             :                                         enum wpa_driver_if_type type,
   10436             :                                         const char *ifname)
   10437             : {
   10438          30 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10439          30 :         int ifindex = if_nametoindex(ifname);
   10440             : 
   10441          30 :         wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d",
   10442          30 :                    __func__, type, ifname, ifindex, bss->added_if);
   10443          30 :         if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex))
   10444          30 :                 nl80211_remove_iface(drv, ifindex);
   10445           0 :         else if (ifindex > 0 && !bss->added_if) {
   10446             :                 struct wpa_driver_nl80211_data *drv2;
   10447           0 :                 dl_list_for_each(drv2, &drv->global->interfaces,
   10448             :                                  struct wpa_driver_nl80211_data, list)
   10449           0 :                         del_ifidx(drv2, ifindex);
   10450             :         }
   10451             : 
   10452          30 :         if (type != WPA_IF_AP_BSS)
   10453          11 :                 return 0;
   10454             : 
   10455          19 :         if (bss->added_if_into_bridge) {
   10456           0 :                 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
   10457           0 :                                     bss->ifname) < 0)
   10458           0 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
   10459             :                                    "interface %s from bridge %s: %s",
   10460           0 :                                    bss->ifname, bss->brname, strerror(errno));
   10461             :         }
   10462          19 :         if (bss->added_bridge) {
   10463           0 :                 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
   10464           0 :                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
   10465             :                                    "bridge %s: %s",
   10466           0 :                                    bss->brname, strerror(errno));
   10467             :         }
   10468             : 
   10469          19 :         if (bss != drv->first_bss) {
   10470             :                 struct i802_bss *tbss;
   10471             : 
   10472          19 :                 wpa_printf(MSG_DEBUG, "nl80211: Not the first BSS - remove it");
   10473          22 :                 for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
   10474          22 :                         if (tbss->next == bss) {
   10475          19 :                                 tbss->next = bss->next;
   10476             :                                 /* Unsubscribe management frames */
   10477          19 :                                 nl80211_teardown_ap(bss);
   10478          19 :                                 nl80211_destroy_bss(bss);
   10479          19 :                                 if (!bss->added_if)
   10480           0 :                                         i802_set_iface_flags(bss, 0);
   10481          19 :                                 os_free(bss);
   10482          19 :                                 bss = NULL;
   10483          19 :                                 break;
   10484             :                         }
   10485             :                 }
   10486          19 :                 if (bss)
   10487           0 :                         wpa_printf(MSG_INFO, "nl80211: %s - could not find "
   10488             :                                    "BSS %p in the list", __func__, bss);
   10489             :         } else {
   10490           0 :                 wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
   10491           0 :                 nl80211_teardown_ap(bss);
   10492           0 :                 if (!bss->added_if && !drv->first_bss->next)
   10493           0 :                         wpa_driver_nl80211_del_beacon(drv);
   10494           0 :                 nl80211_destroy_bss(bss);
   10495           0 :                 if (!bss->added_if)
   10496           0 :                         i802_set_iface_flags(bss, 0);
   10497           0 :                 if (drv->first_bss->next) {
   10498           0 :                         drv->first_bss = drv->first_bss->next;
   10499           0 :                         drv->ctx = drv->first_bss->ctx;
   10500           0 :                         os_free(bss);
   10501             :                 } else {
   10502           0 :                         wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
   10503             :                 }
   10504             :         }
   10505             : 
   10506          19 :         return 0;
   10507             : }
   10508             : 
   10509             : 
   10510        4134 : static int cookie_handler(struct nl_msg *msg, void *arg)
   10511             : {
   10512             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
   10513        4134 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   10514        4134 :         u64 *cookie = arg;
   10515        4134 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
   10516             :                   genlmsg_attrlen(gnlh, 0), NULL);
   10517        4134 :         if (tb[NL80211_ATTR_COOKIE])
   10518        4134 :                 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
   10519        4134 :         return NL_SKIP;
   10520             : }
   10521             : 
   10522             : 
   10523        6022 : static int nl80211_send_frame_cmd(struct i802_bss *bss,
   10524             :                                   unsigned int freq, unsigned int wait,
   10525             :                                   const u8 *buf, size_t buf_len,
   10526             :                                   u64 *cookie_out, int no_cck, int no_ack,
   10527             :                                   int offchanok)
   10528             : {
   10529        6022 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10530             :         struct nl_msg *msg;
   10531             :         u64 cookie;
   10532        6022 :         int ret = -1;
   10533             : 
   10534        6022 :         msg = nlmsg_alloc();
   10535        6022 :         if (!msg)
   10536           0 :                 return -1;
   10537             : 
   10538        6022 :         wpa_printf(MSG_MSGDUMP, "nl80211: CMD_FRAME freq=%u wait=%u no_cck=%d "
   10539             :                    "no_ack=%d offchanok=%d",
   10540             :                    freq, wait, no_cck, no_ack, offchanok);
   10541        6022 :         wpa_hexdump(MSG_MSGDUMP, "CMD_FRAME", buf, buf_len);
   10542        6022 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME);
   10543             : 
   10544        6022 :         if (nl80211_set_iface_id(msg, bss) < 0)
   10545           0 :                 goto nla_put_failure;
   10546        6022 :         if (freq)
   10547        6007 :                 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
   10548        6022 :         if (wait)
   10549           0 :                 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
   10550        6022 :         if (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
   10551             :                           drv->test_use_roc_tx))
   10552         239 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
   10553        6022 :         if (no_cck)
   10554           0 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
   10555        6022 :         if (no_ack)
   10556        1235 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK);
   10557             : 
   10558        6022 :         NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
   10559             : 
   10560        6022 :         cookie = 0;
   10561        6022 :         ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
   10562        6022 :         msg = NULL;
   10563        6022 :         if (ret) {
   10564         656 :                 wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
   10565             :                            "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
   10566             :                            freq, wait);
   10567         656 :                 goto nla_put_failure;
   10568             :         }
   10569        5366 :         wpa_printf(MSG_MSGDUMP, "nl80211: Frame TX command accepted%s; "
   10570             :                    "cookie 0x%llx", no_ack ? " (no ACK)" : "",
   10571             :                    (long long unsigned int) cookie);
   10572             : 
   10573        5366 :         if (cookie_out)
   10574        5366 :                 *cookie_out = no_ack ? (u64) -1 : cookie;
   10575             : 
   10576             : nla_put_failure:
   10577        6022 :         nlmsg_free(msg);
   10578        6022 :         return ret;
   10579             : }
   10580             : 
   10581             : 
   10582         239 : static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
   10583             :                                           unsigned int freq,
   10584             :                                           unsigned int wait_time,
   10585             :                                           const u8 *dst, const u8 *src,
   10586             :                                           const u8 *bssid,
   10587             :                                           const u8 *data, size_t data_len,
   10588             :                                           int no_cck)
   10589             : {
   10590         239 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10591         239 :         int ret = -1;
   10592             :         u8 *buf;
   10593             :         struct ieee80211_hdr *hdr;
   10594             : 
   10595         239 :         wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
   10596             :                    "freq=%u MHz wait=%d ms no_cck=%d)",
   10597             :                    drv->ifindex, freq, wait_time, no_cck);
   10598             : 
   10599         239 :         buf = os_zalloc(24 + data_len);
   10600         239 :         if (buf == NULL)
   10601           0 :                 return ret;
   10602         239 :         os_memcpy(buf + 24, data, data_len);
   10603         239 :         hdr = (struct ieee80211_hdr *) buf;
   10604         239 :         hdr->frame_control =
   10605             :                 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
   10606         239 :         os_memcpy(hdr->addr1, dst, ETH_ALEN);
   10607         239 :         os_memcpy(hdr->addr2, src, ETH_ALEN);
   10608         239 :         os_memcpy(hdr->addr3, bssid, ETH_ALEN);
   10609             : 
   10610         478 :         if (is_ap_interface(drv->nlmode) &&
   10611         478 :             (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
   10612         239 :              (int) freq == bss->freq || drv->device_ap_sme ||
   10613           0 :              !drv->use_monitor))
   10614         239 :                 ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
   10615             :                                                    0, freq, no_cck, 1,
   10616             :                                                    wait_time);
   10617             :         else
   10618           0 :                 ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
   10619             :                                              24 + data_len,
   10620             :                                              &drv->send_action_cookie,
   10621             :                                              no_cck, 0, 1);
   10622             : 
   10623         239 :         os_free(buf);
   10624         239 :         return ret;
   10625             : }
   10626             : 
   10627             : 
   10628           0 : static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
   10629             : {
   10630           0 :         struct i802_bss *bss = priv;
   10631           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10632             :         struct nl_msg *msg;
   10633             :         int ret;
   10634             : 
   10635           0 :         msg = nlmsg_alloc();
   10636           0 :         if (!msg)
   10637           0 :                 return;
   10638             : 
   10639           0 :         wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
   10640           0 :                    (long long unsigned int) drv->send_action_cookie);
   10641           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME_WAIT_CANCEL);
   10642             : 
   10643           0 :         if (nl80211_set_iface_id(msg, bss) < 0)
   10644           0 :                 goto nla_put_failure;
   10645           0 :         NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie);
   10646             : 
   10647           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   10648           0 :         msg = NULL;
   10649           0 :         if (ret)
   10650           0 :                 wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
   10651             :                            "(%s)", ret, strerror(-ret));
   10652             : 
   10653             :  nla_put_failure:
   10654           0 :         nlmsg_free(msg);
   10655             : }
   10656             : 
   10657             : 
   10658           0 : static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
   10659             :                                                 unsigned int duration)
   10660             : {
   10661           0 :         struct i802_bss *bss = priv;
   10662           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10663             :         struct nl_msg *msg;
   10664             :         int ret;
   10665             :         u64 cookie;
   10666             : 
   10667           0 :         msg = nlmsg_alloc();
   10668           0 :         if (!msg)
   10669           0 :                 return -1;
   10670             : 
   10671           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL);
   10672             : 
   10673           0 :         if (nl80211_set_iface_id(msg, bss) < 0)
   10674           0 :                 goto nla_put_failure;
   10675             : 
   10676           0 :         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
   10677           0 :         NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
   10678             : 
   10679           0 :         cookie = 0;
   10680           0 :         ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
   10681           0 :         msg = NULL;
   10682           0 :         if (ret == 0) {
   10683           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
   10684             :                            "0x%llx for freq=%u MHz duration=%u",
   10685             :                            (long long unsigned int) cookie, freq, duration);
   10686           0 :                 drv->remain_on_chan_cookie = cookie;
   10687           0 :                 drv->pending_remain_on_chan = 1;
   10688           0 :                 return 0;
   10689             :         }
   10690           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
   10691             :                    "(freq=%d duration=%u): %d (%s)",
   10692             :                    freq, duration, ret, strerror(-ret));
   10693             : nla_put_failure:
   10694           0 :         nlmsg_free(msg);
   10695           0 :         return -1;
   10696             : }
   10697             : 
   10698             : 
   10699           0 : static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
   10700             : {
   10701           0 :         struct i802_bss *bss = priv;
   10702           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10703             :         struct nl_msg *msg;
   10704             :         int ret;
   10705             : 
   10706           0 :         if (!drv->pending_remain_on_chan) {
   10707           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
   10708             :                            "to cancel");
   10709           0 :                 return -1;
   10710             :         }
   10711             : 
   10712           0 :         wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
   10713             :                    "0x%llx",
   10714           0 :                    (long long unsigned int) drv->remain_on_chan_cookie);
   10715             : 
   10716           0 :         msg = nlmsg_alloc();
   10717           0 :         if (!msg)
   10718           0 :                 return -1;
   10719             : 
   10720           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
   10721             : 
   10722           0 :         if (nl80211_set_iface_id(msg, bss) < 0)
   10723           0 :                 goto nla_put_failure;
   10724             : 
   10725           0 :         NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
   10726             : 
   10727           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   10728           0 :         msg = NULL;
   10729           0 :         if (ret == 0)
   10730           0 :                 return 0;
   10731           0 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
   10732             :                    "%d (%s)", ret, strerror(-ret));
   10733             : nla_put_failure:
   10734           0 :         nlmsg_free(msg);
   10735           0 :         return -1;
   10736             : }
   10737             : 
   10738             : 
   10739         650 : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
   10740             : {
   10741         650 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10742             : 
   10743         650 :         if (!report) {
   10744         650 :                 if (bss->nl_preq && drv->device_ap_sme &&
   10745           0 :                     is_ap_interface(drv->nlmode) && !bss->in_deinit &&
   10746           0 :                     !bss->static_ap) {
   10747             :                         /*
   10748             :                          * Do not disable Probe Request reporting that was
   10749             :                          * enabled in nl80211_setup_ap().
   10750             :                          */
   10751           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Skip disabling of "
   10752             :                                    "Probe Request reporting nl_preq=%p while "
   10753             :                                    "in AP mode", bss->nl_preq);
   10754         650 :                 } else if (bss->nl_preq) {
   10755           0 :                         wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
   10756             :                                    "reporting nl_preq=%p", bss->nl_preq);
   10757           0 :                         nl80211_destroy_eloop_handle(&bss->nl_preq);
   10758             :                 }
   10759         650 :                 return 0;
   10760             :         }
   10761             : 
   10762           0 :         if (bss->nl_preq) {
   10763           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
   10764             :                            "already on! nl_preq=%p", bss->nl_preq);
   10765           0 :                 return 0;
   10766             :         }
   10767             : 
   10768           0 :         bss->nl_preq = nl_create_handle(drv->global->nl_cb, "preq");
   10769           0 :         if (bss->nl_preq == NULL)
   10770           0 :                 return -1;
   10771           0 :         wpa_printf(MSG_DEBUG, "nl80211: Enable Probe Request "
   10772             :                    "reporting nl_preq=%p", bss->nl_preq);
   10773             : 
   10774           0 :         if (nl80211_register_frame(bss, bss->nl_preq,
   10775             :                                    (WLAN_FC_TYPE_MGMT << 2) |
   10776             :                                    (WLAN_FC_STYPE_PROBE_REQ << 4),
   10777             :                                    NULL, 0) < 0)
   10778           0 :                 goto out_err;
   10779             : 
   10780           0 :         nl80211_register_eloop_read(&bss->nl_preq,
   10781             :                                     wpa_driver_nl80211_event_receive,
   10782           0 :                                     bss->nl_cb);
   10783             : 
   10784           0 :         return 0;
   10785             : 
   10786             :  out_err:
   10787           0 :         nl_destroy_handles(&bss->nl_preq);
   10788           0 :         return -1;
   10789             : }
   10790             : 
   10791             : 
   10792           0 : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
   10793             :                                      int ifindex, int disabled)
   10794             : {
   10795             :         struct nl_msg *msg;
   10796             :         struct nlattr *bands, *band;
   10797             :         int ret;
   10798             : 
   10799           0 :         msg = nlmsg_alloc();
   10800           0 :         if (!msg)
   10801           0 :                 return -1;
   10802             : 
   10803           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_TX_BITRATE_MASK);
   10804           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
   10805             : 
   10806           0 :         bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
   10807           0 :         if (!bands)
   10808           0 :                 goto nla_put_failure;
   10809             : 
   10810             :         /*
   10811             :          * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
   10812             :          * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
   10813             :          * rates. All 5 GHz rates are left enabled.
   10814             :          */
   10815           0 :         band = nla_nest_start(msg, NL80211_BAND_2GHZ);
   10816           0 :         if (!band)
   10817           0 :                 goto nla_put_failure;
   10818           0 :         if (disabled) {
   10819           0 :                 NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
   10820             :                         "\x0c\x12\x18\x24\x30\x48\x60\x6c");
   10821             :         }
   10822           0 :         nla_nest_end(msg, band);
   10823             : 
   10824           0 :         nla_nest_end(msg, bands);
   10825             : 
   10826           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   10827           0 :         msg = NULL;
   10828           0 :         if (ret) {
   10829           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
   10830             :                            "(%s)", ret, strerror(-ret));
   10831             :         } else
   10832           0 :                 drv->disabled_11b_rates = disabled;
   10833             : 
   10834           0 :         return ret;
   10835             : 
   10836             : nla_put_failure:
   10837           0 :         nlmsg_free(msg);
   10838           0 :         return -1;
   10839             : }
   10840             : 
   10841             : 
   10842           0 : static int wpa_driver_nl80211_deinit_ap(void *priv)
   10843             : {
   10844           0 :         struct i802_bss *bss = priv;
   10845           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10846           0 :         if (!is_ap_interface(drv->nlmode))
   10847           0 :                 return -1;
   10848           0 :         wpa_driver_nl80211_del_beacon(drv);
   10849             : 
   10850             :         /*
   10851             :          * If the P2P GO interface was dynamically added, then it is
   10852             :          * possible that the interface change to station is not possible.
   10853             :          */
   10854           0 :         if (drv->nlmode == NL80211_IFTYPE_P2P_GO && bss->if_dynamic)
   10855           0 :                 return 0;
   10856             : 
   10857           0 :         return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
   10858             : }
   10859             : 
   10860             : 
   10861           0 : static int wpa_driver_nl80211_stop_ap(void *priv)
   10862             : {
   10863           0 :         struct i802_bss *bss = priv;
   10864           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10865           0 :         if (!is_ap_interface(drv->nlmode))
   10866           0 :                 return -1;
   10867           0 :         wpa_driver_nl80211_del_beacon(drv);
   10868           0 :         bss->beacon_set = 0;
   10869           0 :         return 0;
   10870             : }
   10871             : 
   10872             : 
   10873           0 : static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
   10874             : {
   10875           0 :         struct i802_bss *bss = priv;
   10876           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10877           0 :         if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
   10878           0 :                 return -1;
   10879             : 
   10880             :         /*
   10881             :          * If the P2P Client interface was dynamically added, then it is
   10882             :          * possible that the interface change to station is not possible.
   10883             :          */
   10884           0 :         if (bss->if_dynamic)
   10885           0 :                 return 0;
   10886             : 
   10887           0 :         return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
   10888             : }
   10889             : 
   10890             : 
   10891           0 : static void wpa_driver_nl80211_resume(void *priv)
   10892             : {
   10893           0 :         struct i802_bss *bss = priv;
   10894             : 
   10895           0 :         if (i802_set_iface_flags(bss, 1))
   10896           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on resume event");
   10897           0 : }
   10898             : 
   10899             : 
   10900           0 : static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
   10901             :                                   const u8 *ies, size_t ies_len)
   10902             : {
   10903           0 :         struct i802_bss *bss = priv;
   10904           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10905             :         int ret;
   10906             :         u8 *data, *pos;
   10907             :         size_t data_len;
   10908           0 :         const u8 *own_addr = bss->addr;
   10909             : 
   10910           0 :         if (action != 1) {
   10911           0 :                 wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
   10912             :                            "action %d", action);
   10913           0 :                 return -1;
   10914             :         }
   10915             : 
   10916             :         /*
   10917             :          * Action frame payload:
   10918             :          * Category[1] = 6 (Fast BSS Transition)
   10919             :          * Action[1] = 1 (Fast BSS Transition Request)
   10920             :          * STA Address
   10921             :          * Target AP Address
   10922             :          * FT IEs
   10923             :          */
   10924             : 
   10925           0 :         data_len = 2 + 2 * ETH_ALEN + ies_len;
   10926           0 :         data = os_malloc(data_len);
   10927           0 :         if (data == NULL)
   10928           0 :                 return -1;
   10929           0 :         pos = data;
   10930           0 :         *pos++ = 0x06; /* FT Action category */
   10931           0 :         *pos++ = action;
   10932           0 :         os_memcpy(pos, own_addr, ETH_ALEN);
   10933           0 :         pos += ETH_ALEN;
   10934           0 :         os_memcpy(pos, target_ap, ETH_ALEN);
   10935           0 :         pos += ETH_ALEN;
   10936           0 :         os_memcpy(pos, ies, ies_len);
   10937             : 
   10938           0 :         ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, 0,
   10939           0 :                                              drv->bssid, own_addr, drv->bssid,
   10940             :                                              data, data_len, 0);
   10941           0 :         os_free(data);
   10942             : 
   10943           0 :         return ret;
   10944             : }
   10945             : 
   10946             : 
   10947           0 : static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
   10948             : {
   10949           0 :         struct i802_bss *bss = priv;
   10950           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   10951             :         struct nl_msg *msg;
   10952             :         struct nlattr *cqm;
   10953           0 :         int ret = -1;
   10954             : 
   10955           0 :         wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
   10956             :                    "hysteresis=%d", threshold, hysteresis);
   10957             : 
   10958           0 :         msg = nlmsg_alloc();
   10959           0 :         if (!msg)
   10960           0 :                 return -1;
   10961             : 
   10962           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_CQM);
   10963             : 
   10964           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
   10965             : 
   10966           0 :         cqm = nla_nest_start(msg, NL80211_ATTR_CQM);
   10967           0 :         if (cqm == NULL)
   10968           0 :                 goto nla_put_failure;
   10969             : 
   10970           0 :         NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
   10971           0 :         NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
   10972           0 :         nla_nest_end(msg, cqm);
   10973             : 
   10974           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   10975           0 :         msg = NULL;
   10976             : 
   10977             : nla_put_failure:
   10978           0 :         nlmsg_free(msg);
   10979           0 :         return ret;
   10980             : }
   10981             : 
   10982             : 
   10983           0 : static int get_channel_width(struct nl_msg *msg, void *arg)
   10984             : {
   10985             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
   10986           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   10987           0 :         struct wpa_signal_info *sig_change = arg;
   10988             : 
   10989           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
   10990             :                   genlmsg_attrlen(gnlh, 0), NULL);
   10991             : 
   10992           0 :         sig_change->center_frq1 = -1;
   10993           0 :         sig_change->center_frq2 = -1;
   10994           0 :         sig_change->chanwidth = CHAN_WIDTH_UNKNOWN;
   10995             : 
   10996           0 :         if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
   10997           0 :                 sig_change->chanwidth = convert2width(
   10998           0 :                         nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
   10999           0 :                 if (tb[NL80211_ATTR_CENTER_FREQ1])
   11000           0 :                         sig_change->center_frq1 =
   11001           0 :                                 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
   11002           0 :                 if (tb[NL80211_ATTR_CENTER_FREQ2])
   11003           0 :                         sig_change->center_frq2 =
   11004           0 :                                 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
   11005             :         }
   11006             : 
   11007           0 :         return NL_SKIP;
   11008             : }
   11009             : 
   11010             : 
   11011           0 : static int nl80211_get_channel_width(struct wpa_driver_nl80211_data *drv,
   11012             :                                      struct wpa_signal_info *sig)
   11013             : {
   11014             :         struct nl_msg *msg;
   11015             : 
   11016           0 :         msg = nlmsg_alloc();
   11017           0 :         if (!msg)
   11018           0 :                 return -ENOMEM;
   11019             : 
   11020           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_INTERFACE);
   11021           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   11022             : 
   11023           0 :         return send_and_recv_msgs(drv, msg, get_channel_width, sig);
   11024             : 
   11025             : nla_put_failure:
   11026           0 :         nlmsg_free(msg);
   11027           0 :         return -ENOBUFS;
   11028             : }
   11029             : 
   11030             : 
   11031           0 : static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
   11032             : {
   11033           0 :         struct i802_bss *bss = priv;
   11034           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11035             :         int res;
   11036             : 
   11037           0 :         os_memset(si, 0, sizeof(*si));
   11038           0 :         res = nl80211_get_link_signal(drv, si);
   11039           0 :         if (res != 0)
   11040           0 :                 return res;
   11041             : 
   11042           0 :         res = nl80211_get_channel_width(drv, si);
   11043           0 :         if (res != 0)
   11044           0 :                 return res;
   11045             : 
   11046           0 :         return nl80211_get_link_noise(drv, si);
   11047             : }
   11048             : 
   11049             : 
   11050           0 : static int wpa_driver_nl80211_shared_freq(void *priv)
   11051             : {
   11052           0 :         struct i802_bss *bss = priv;
   11053           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11054             :         struct wpa_driver_nl80211_data *driver;
   11055           0 :         int freq = 0;
   11056             : 
   11057             :         /*
   11058             :          * If the same PHY is in connected state with some other interface,
   11059             :          * then retrieve the assoc freq.
   11060             :          */
   11061           0 :         wpa_printf(MSG_DEBUG, "nl80211: Get shared freq for PHY %s",
   11062           0 :                    drv->phyname);
   11063             : 
   11064           0 :         dl_list_for_each(driver, &drv->global->interfaces,
   11065             :                          struct wpa_driver_nl80211_data, list) {
   11066           0 :                 if (drv == driver ||
   11067           0 :                     os_strcmp(drv->phyname, driver->phyname) != 0 ||
   11068           0 :                     !driver->associated)
   11069           0 :                         continue;
   11070             : 
   11071           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s "
   11072             :                            MACSTR,
   11073           0 :                            driver->phyname, driver->first_bss->ifname,
   11074           0 :                            MAC2STR(driver->first_bss->addr));
   11075           0 :                 if (is_ap_interface(driver->nlmode))
   11076           0 :                         freq = driver->first_bss->freq;
   11077             :                 else
   11078           0 :                         freq = nl80211_get_assoc_freq(driver);
   11079           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",
   11080           0 :                            drv->phyname, freq);
   11081             :         }
   11082             : 
   11083           0 :         if (!freq)
   11084           0 :                 wpa_printf(MSG_DEBUG, "nl80211: No shared interface for "
   11085           0 :                            "PHY (%s) in associated state", drv->phyname);
   11086             : 
   11087           0 :         return freq;
   11088             : }
   11089             : 
   11090             : 
   11091           2 : static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
   11092             :                               int encrypt)
   11093             : {
   11094           2 :         struct i802_bss *bss = priv;
   11095           2 :         return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
   11096             :                                              0, 0, 0, 0);
   11097             : }
   11098             : 
   11099             : 
   11100           0 : static int nl80211_set_param(void *priv, const char *param)
   11101             : {
   11102           0 :         wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
   11103           0 :         if (param == NULL)
   11104           0 :                 return 0;
   11105             : 
   11106             : #ifdef CONFIG_P2P
   11107             :         if (os_strstr(param, "use_p2p_group_interface=1")) {
   11108             :                 struct i802_bss *bss = priv;
   11109             :                 struct wpa_driver_nl80211_data *drv = bss->drv;
   11110             : 
   11111             :                 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
   11112             :                            "interface");
   11113             :                 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
   11114             :                 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
   11115             :         }
   11116             : 
   11117             :         if (os_strstr(param, "p2p_device=1")) {
   11118             :                 struct i802_bss *bss = priv;
   11119             :                 struct wpa_driver_nl80211_data *drv = bss->drv;
   11120             :                 drv->allow_p2p_device = 1;
   11121             :         }
   11122             : #endif /* CONFIG_P2P */
   11123             : 
   11124           0 :         if (os_strstr(param, "use_monitor=1")) {
   11125           0 :                 struct i802_bss *bss = priv;
   11126           0 :                 struct wpa_driver_nl80211_data *drv = bss->drv;
   11127           0 :                 drv->use_monitor = 1;
   11128             :         }
   11129             : 
   11130           0 :         if (os_strstr(param, "force_connect_cmd=1")) {
   11131           0 :                 struct i802_bss *bss = priv;
   11132           0 :                 struct wpa_driver_nl80211_data *drv = bss->drv;
   11133           0 :                 drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
   11134           0 :                 drv->force_connect_cmd = 1;
   11135             :         }
   11136             : 
   11137           0 :         if (os_strstr(param, "no_offchannel_tx=1")) {
   11138           0 :                 struct i802_bss *bss = priv;
   11139           0 :                 struct wpa_driver_nl80211_data *drv = bss->drv;
   11140           0 :                 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
   11141           0 :                 drv->test_use_roc_tx = 1;
   11142             :         }
   11143             : 
   11144           0 :         return 0;
   11145             : }
   11146             : 
   11147             : 
   11148           1 : static void * nl80211_global_init(void)
   11149             : {
   11150             :         struct nl80211_global *global;
   11151             :         struct netlink_config *cfg;
   11152             : 
   11153           1 :         global = os_zalloc(sizeof(*global));
   11154           1 :         if (global == NULL)
   11155           0 :                 return NULL;
   11156           1 :         global->ioctl_sock = -1;
   11157           1 :         dl_list_init(&global->interfaces);
   11158           1 :         global->if_add_ifindex = -1;
   11159             : 
   11160           1 :         cfg = os_zalloc(sizeof(*cfg));
   11161           1 :         if (cfg == NULL)
   11162           0 :                 goto err;
   11163             : 
   11164           1 :         cfg->ctx = global;
   11165           1 :         cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
   11166           1 :         cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
   11167           1 :         global->netlink = netlink_init(cfg);
   11168           1 :         if (global->netlink == NULL) {
   11169           0 :                 os_free(cfg);
   11170           0 :                 goto err;
   11171             :         }
   11172             : 
   11173           1 :         if (wpa_driver_nl80211_init_nl_global(global) < 0)
   11174           0 :                 goto err;
   11175             : 
   11176           1 :         global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
   11177           1 :         if (global->ioctl_sock < 0) {
   11178           0 :                 wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
   11179           0 :                            strerror(errno));
   11180           0 :                 goto err;
   11181             :         }
   11182             : 
   11183           1 :         return global;
   11184             : 
   11185             : err:
   11186           0 :         nl80211_global_deinit(global);
   11187           0 :         return NULL;
   11188             : }
   11189             : 
   11190             : 
   11191           1 : static void nl80211_global_deinit(void *priv)
   11192             : {
   11193           1 :         struct nl80211_global *global = priv;
   11194           1 :         if (global == NULL)
   11195           1 :                 return;
   11196           1 :         if (!dl_list_empty(&global->interfaces)) {
   11197           0 :                 wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
   11198             :                            "nl80211_global_deinit",
   11199             :                            dl_list_len(&global->interfaces));
   11200             :         }
   11201             : 
   11202           1 :         if (global->netlink)
   11203           1 :                 netlink_deinit(global->netlink);
   11204             : 
   11205           1 :         nl_destroy_handles(&global->nl);
   11206             : 
   11207           1 :         if (global->nl_event)
   11208           1 :                 nl80211_destroy_eloop_handle(&global->nl_event);
   11209             : 
   11210           1 :         nl_cb_put(global->nl_cb);
   11211             : 
   11212           1 :         if (global->ioctl_sock >= 0)
   11213           1 :                 close(global->ioctl_sock);
   11214             : 
   11215           1 :         os_free(global);
   11216             : }
   11217             : 
   11218             : 
   11219         616 : static const char * nl80211_get_radio_name(void *priv)
   11220             : {
   11221         616 :         struct i802_bss *bss = priv;
   11222         616 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11223         616 :         return drv->phyname;
   11224             : }
   11225             : 
   11226             : 
   11227           0 : static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
   11228             :                          const u8 *pmkid)
   11229             : {
   11230             :         struct nl_msg *msg;
   11231             : 
   11232           0 :         msg = nlmsg_alloc();
   11233           0 :         if (!msg)
   11234           0 :                 return -ENOMEM;
   11235             : 
   11236           0 :         nl80211_cmd(bss->drv, msg, 0, cmd);
   11237             : 
   11238           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
   11239           0 :         if (pmkid)
   11240           0 :                 NLA_PUT(msg, NL80211_ATTR_PMKID, 16, pmkid);
   11241           0 :         if (bssid)
   11242           0 :                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
   11243             : 
   11244           0 :         return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
   11245             :  nla_put_failure:
   11246           0 :         nlmsg_free(msg);
   11247           0 :         return -ENOBUFS;
   11248             : }
   11249             : 
   11250             : 
   11251           0 : static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
   11252             : {
   11253           0 :         struct i802_bss *bss = priv;
   11254           0 :         wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
   11255           0 :         return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
   11256             : }
   11257             : 
   11258             : 
   11259           0 : static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
   11260             : {
   11261           0 :         struct i802_bss *bss = priv;
   11262           0 :         wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
   11263           0 :                    MAC2STR(bssid));
   11264           0 :         return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
   11265             : }
   11266             : 
   11267             : 
   11268           0 : static int nl80211_flush_pmkid(void *priv)
   11269             : {
   11270           0 :         struct i802_bss *bss = priv;
   11271           0 :         wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
   11272           0 :         return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
   11273             : }
   11274             : 
   11275             : 
   11276          35 : static void clean_survey_results(struct survey_results *survey_results)
   11277             : {
   11278             :         struct freq_survey *survey, *tmp;
   11279             : 
   11280          35 :         if (dl_list_empty(&survey_results->survey_list))
   11281          55 :                 return;
   11282             : 
   11283          30 :         dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
   11284             :                               struct freq_survey, list) {
   11285          15 :                 dl_list_del(&survey->list);
   11286          15 :                 os_free(survey);
   11287             :         }
   11288             : }
   11289             : 
   11290             : 
   11291          35 : static void add_survey(struct nlattr **sinfo, u32 ifidx,
   11292             :                        struct dl_list *survey_list)
   11293             : {
   11294             :         struct freq_survey *survey;
   11295             : 
   11296          35 :         survey = os_zalloc(sizeof(struct freq_survey));
   11297          35 :         if  (!survey)
   11298          35 :                 return;
   11299             : 
   11300          35 :         survey->ifidx = ifidx;
   11301          35 :         survey->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
   11302          35 :         survey->filled = 0;
   11303             : 
   11304          35 :         if (sinfo[NL80211_SURVEY_INFO_NOISE]) {
   11305          35 :                 survey->nf = (int8_t)
   11306          35 :                         nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
   11307          35 :                 survey->filled |= SURVEY_HAS_NF;
   11308             :         }
   11309             : 
   11310          35 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) {
   11311           0 :                 survey->channel_time =
   11312           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
   11313           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME;
   11314             :         }
   11315             : 
   11316          35 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {
   11317           0 :                 survey->channel_time_busy =
   11318           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);
   11319           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
   11320             :         }
   11321             : 
   11322          35 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) {
   11323           0 :                 survey->channel_time_rx =
   11324           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);
   11325           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
   11326             :         }
   11327             : 
   11328          35 :         if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) {
   11329           0 :                 survey->channel_time_tx =
   11330           0 :                         nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);
   11331           0 :                 survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
   11332             :         }
   11333             : 
   11334          70 :         wpa_printf(MSG_DEBUG, "nl80211: Freq survey dump event (freq=%d MHz noise=%d channel_time=%ld busy_time=%ld tx_time=%ld rx_time=%ld filled=%04x)",
   11335             :                    survey->freq,
   11336          35 :                    survey->nf,
   11337             :                    (unsigned long int) survey->channel_time,
   11338             :                    (unsigned long int) survey->channel_time_busy,
   11339             :                    (unsigned long int) survey->channel_time_tx,
   11340             :                    (unsigned long int) survey->channel_time_rx,
   11341             :                    survey->filled);
   11342             : 
   11343          35 :         dl_list_add_tail(survey_list, &survey->list);
   11344             : }
   11345             : 
   11346             : 
   11347          35 : static int check_survey_ok(struct nlattr **sinfo, u32 surveyed_freq,
   11348             :                            unsigned int freq_filter)
   11349             : {
   11350          35 :         if (!freq_filter)
   11351          35 :                 return 1;
   11352             : 
   11353           0 :         return freq_filter == surveyed_freq;
   11354             : }
   11355             : 
   11356             : 
   11357          35 : static int survey_handler(struct nl_msg *msg, void *arg)
   11358             : {
   11359             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
   11360          35 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   11361             :         struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
   11362             :         struct survey_results *survey_results;
   11363          35 :         u32 surveyed_freq = 0;
   11364             :         u32 ifidx;
   11365             : 
   11366             :         static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
   11367             :                 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
   11368             :                 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
   11369             :         };
   11370             : 
   11371          35 :         survey_results = (struct survey_results *) arg;
   11372             : 
   11373          35 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
   11374             :                   genlmsg_attrlen(gnlh, 0), NULL);
   11375             : 
   11376          35 :         if (!tb[NL80211_ATTR_IFINDEX])
   11377           0 :                 return NL_SKIP;
   11378             : 
   11379          35 :         ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
   11380             : 
   11381          35 :         if (!tb[NL80211_ATTR_SURVEY_INFO])
   11382           0 :                 return NL_SKIP;
   11383             : 
   11384          35 :         if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
   11385             :                              tb[NL80211_ATTR_SURVEY_INFO],
   11386             :                              survey_policy))
   11387           0 :                 return NL_SKIP;
   11388             : 
   11389          35 :         if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) {
   11390           0 :                 wpa_printf(MSG_ERROR, "nl80211: Invalid survey data");
   11391           0 :                 return NL_SKIP;
   11392             :         }
   11393             : 
   11394          35 :         surveyed_freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
   11395             : 
   11396          35 :         if (!check_survey_ok(sinfo, surveyed_freq,
   11397             :                              survey_results->freq_filter))
   11398           0 :                 return NL_SKIP;
   11399             : 
   11400          35 :         if (survey_results->freq_filter &&
   11401           0 :             survey_results->freq_filter != surveyed_freq) {
   11402           0 :                 wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
   11403             :                            surveyed_freq);
   11404           0 :                 return NL_SKIP;
   11405             :         }
   11406             : 
   11407          35 :         add_survey(sinfo, ifidx, &survey_results->survey_list);
   11408             : 
   11409          35 :         return NL_SKIP;
   11410             : }
   11411             : 
   11412             : 
   11413          35 : static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
   11414             : {
   11415          35 :         struct i802_bss *bss = priv;
   11416          35 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11417             :         struct nl_msg *msg;
   11418          35 :         int err = -ENOBUFS;
   11419             :         union wpa_event_data data;
   11420             :         struct survey_results *survey_results;
   11421             : 
   11422          35 :         os_memset(&data, 0, sizeof(data));
   11423          35 :         survey_results = &data.survey_results;
   11424             : 
   11425          35 :         dl_list_init(&survey_results->survey_list);
   11426             : 
   11427          35 :         msg = nlmsg_alloc();
   11428          35 :         if (!msg)
   11429           0 :                 goto nla_put_failure;
   11430             : 
   11431          35 :         nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
   11432             : 
   11433          35 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   11434             : 
   11435          35 :         if (freq)
   11436           0 :                 data.survey_results.freq_filter = freq;
   11437             : 
   11438             :         do {
   11439          35 :                 wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
   11440          35 :                 err = send_and_recv_msgs(drv, msg, survey_handler,
   11441             :                                          survey_results);
   11442          35 :         } while (err > 0);
   11443             : 
   11444          35 :         if (err) {
   11445           0 :                 wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
   11446           0 :                 goto out_clean;
   11447             :         }
   11448             : 
   11449          35 :         wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
   11450             : 
   11451             : out_clean:
   11452          35 :         clean_survey_results(survey_results);
   11453             : nla_put_failure:
   11454          35 :         return err;
   11455             : }
   11456             : 
   11457             : 
   11458           0 : static void nl80211_set_rekey_info(void *priv, const u8 *kek, const u8 *kck,
   11459             :                                    const u8 *replay_ctr)
   11460             : {
   11461           0 :         struct i802_bss *bss = priv;
   11462           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11463             :         struct nlattr *replay_nested;
   11464             :         struct nl_msg *msg;
   11465             : 
   11466           0 :         msg = nlmsg_alloc();
   11467           0 :         if (!msg)
   11468           0 :                 return;
   11469             : 
   11470           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
   11471             : 
   11472           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
   11473             : 
   11474           0 :         replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
   11475           0 :         if (!replay_nested)
   11476           0 :                 goto nla_put_failure;
   11477             : 
   11478           0 :         NLA_PUT(msg, NL80211_REKEY_DATA_KEK, NL80211_KEK_LEN, kek);
   11479           0 :         NLA_PUT(msg, NL80211_REKEY_DATA_KCK, NL80211_KCK_LEN, kck);
   11480           0 :         NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
   11481             :                 replay_ctr);
   11482             : 
   11483           0 :         nla_nest_end(msg, replay_nested);
   11484             : 
   11485           0 :         send_and_recv_msgs(drv, msg, NULL, NULL);
   11486           0 :         return;
   11487             :  nla_put_failure:
   11488           0 :         nlmsg_free(msg);
   11489             : }
   11490             : 
   11491             : 
   11492           0 : static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
   11493             :                                     const u8 *addr, int qos)
   11494             : {
   11495             :         /* send data frame to poll STA and check whether
   11496             :          * this frame is ACKed */
   11497             :         struct {
   11498             :                 struct ieee80211_hdr hdr;
   11499             :                 u16 qos_ctl;
   11500             :         } STRUCT_PACKED nulldata;
   11501             :         size_t size;
   11502             : 
   11503             :         /* Send data frame to poll STA and check whether this frame is ACKed */
   11504             : 
   11505           0 :         os_memset(&nulldata, 0, sizeof(nulldata));
   11506             : 
   11507           0 :         if (qos) {
   11508           0 :                 nulldata.hdr.frame_control =
   11509             :                         IEEE80211_FC(WLAN_FC_TYPE_DATA,
   11510             :                                      WLAN_FC_STYPE_QOS_NULL);
   11511           0 :                 size = sizeof(nulldata);
   11512             :         } else {
   11513           0 :                 nulldata.hdr.frame_control =
   11514             :                         IEEE80211_FC(WLAN_FC_TYPE_DATA,
   11515             :                                      WLAN_FC_STYPE_NULLFUNC);
   11516           0 :                 size = sizeof(struct ieee80211_hdr);
   11517             :         }
   11518             : 
   11519           0 :         nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
   11520           0 :         os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
   11521           0 :         os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
   11522           0 :         os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
   11523             : 
   11524           0 :         if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
   11525             :                                          0, 0) < 0)
   11526           0 :                 wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
   11527             :                            "send poll frame");
   11528           0 : }
   11529             : 
   11530           1 : static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
   11531             :                                 int qos)
   11532             : {
   11533           1 :         struct i802_bss *bss = priv;
   11534           1 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11535             :         struct nl_msg *msg;
   11536             : 
   11537           1 :         if (!drv->poll_command_supported) {
   11538           0 :                 nl80211_send_null_frame(bss, own_addr, addr, qos);
   11539           0 :                 return;
   11540             :         }
   11541             : 
   11542           1 :         msg = nlmsg_alloc();
   11543           1 :         if (!msg)
   11544           0 :                 return;
   11545             : 
   11546           1 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_PROBE_CLIENT);
   11547             : 
   11548           1 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
   11549           1 :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
   11550             : 
   11551           1 :         send_and_recv_msgs(drv, msg, NULL, NULL);
   11552           1 :         return;
   11553             :  nla_put_failure:
   11554           0 :         nlmsg_free(msg);
   11555             : }
   11556             : 
   11557             : 
   11558           0 : static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
   11559             : {
   11560             :         struct nl_msg *msg;
   11561             : 
   11562           0 :         msg = nlmsg_alloc();
   11563           0 :         if (!msg)
   11564           0 :                 return -ENOMEM;
   11565             : 
   11566           0 :         nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_SET_POWER_SAVE);
   11567           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
   11568           0 :         NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE,
   11569             :                     enabled ? NL80211_PS_ENABLED : NL80211_PS_DISABLED);
   11570           0 :         return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
   11571             : nla_put_failure:
   11572           0 :         nlmsg_free(msg);
   11573           0 :         return -ENOBUFS;
   11574             : }
   11575             : 
   11576             : 
   11577           0 : static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps,
   11578             :                                      int ctwindow)
   11579             : {
   11580           0 :         struct i802_bss *bss = priv;
   11581             : 
   11582           0 :         wpa_printf(MSG_DEBUG, "nl80211: set_p2p_powersave (legacy_ps=%d "
   11583             :                    "opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
   11584             : 
   11585           0 :         if (opp_ps != -1 || ctwindow != -1) {
   11586             : #ifdef ANDROID_P2P
   11587             :                 wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
   11588             : #else /* ANDROID_P2P */
   11589           0 :                 return -1; /* Not yet supported */
   11590             : #endif /* ANDROID_P2P */
   11591             :         }
   11592             : 
   11593           0 :         if (legacy_ps == -1)
   11594           0 :                 return 0;
   11595           0 :         if (legacy_ps != 0 && legacy_ps != 1)
   11596           0 :                 return -1; /* Not yet supported */
   11597             : 
   11598           0 :         return nl80211_set_power_save(bss, legacy_ps);
   11599             : }
   11600             : 
   11601             : 
   11602           6 : static int nl80211_start_radar_detection(void *priv,
   11603             :                                          struct hostapd_freq_params *freq)
   11604             : {
   11605           6 :         struct i802_bss *bss = priv;
   11606           6 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11607             :         struct nl_msg *msg;
   11608             :         int ret;
   11609             : 
   11610           6 :         wpa_printf(MSG_DEBUG, "nl80211: Start radar detection (CAC) %d MHz (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
   11611             :                    freq->freq, freq->ht_enabled, freq->vht_enabled,
   11612             :                    freq->bandwidth, freq->center_freq1, freq->center_freq2);
   11613             : 
   11614           6 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) {
   11615           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar "
   11616             :                            "detection");
   11617           0 :                 return -1;
   11618             :         }
   11619             : 
   11620           6 :         msg = nlmsg_alloc();
   11621           6 :         if (!msg)
   11622           0 :                 return -1;
   11623             : 
   11624           6 :         nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_RADAR_DETECT);
   11625           6 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   11626             : 
   11627           6 :         if (nl80211_put_freq_params(msg, freq) < 0)
   11628           0 :                 goto nla_put_failure;
   11629             : 
   11630           6 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   11631           6 :         msg = NULL;
   11632           6 :         if (ret == 0)
   11633           5 :                 return 0;
   11634           1 :         wpa_printf(MSG_DEBUG, "nl80211: Failed to start radar detection: "
   11635             :                    "%d (%s)", ret, strerror(-ret));
   11636             : nla_put_failure:
   11637           1 :         nlmsg_free(msg);
   11638           1 :         return -1;
   11639             : }
   11640             : 
   11641             : #ifdef CONFIG_TDLS
   11642             : 
   11643             : static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
   11644             :                                   u8 dialog_token, u16 status_code,
   11645             :                                   u32 peer_capab, int initiator, const u8 *buf,
   11646             :                                   size_t len)
   11647             : {
   11648             :         struct i802_bss *bss = priv;
   11649             :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11650             :         struct nl_msg *msg;
   11651             : 
   11652             :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
   11653             :                 return -EOPNOTSUPP;
   11654             : 
   11655             :         if (!dst)
   11656             :                 return -EINVAL;
   11657             : 
   11658             :         msg = nlmsg_alloc();
   11659             :         if (!msg)
   11660             :                 return -ENOMEM;
   11661             : 
   11662             :         nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_MGMT);
   11663             :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   11664             :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
   11665             :         NLA_PUT_U8(msg, NL80211_ATTR_TDLS_ACTION, action_code);
   11666             :         NLA_PUT_U8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token);
   11667             :         NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status_code);
   11668             :         if (peer_capab) {
   11669             :                 /*
   11670             :                  * The internal enum tdls_peer_capability definition is
   11671             :                  * currently identical with the nl80211 enum
   11672             :                  * nl80211_tdls_peer_capability, so no conversion is needed
   11673             :                  * here.
   11674             :                  */
   11675             :                 NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY, peer_capab);
   11676             :         }
   11677             :         if (initiator)
   11678             :                 NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_INITIATOR);
   11679             :         NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
   11680             : 
   11681             :         return send_and_recv_msgs(drv, msg, NULL, NULL);
   11682             : 
   11683             : nla_put_failure:
   11684             :         nlmsg_free(msg);
   11685             :         return -ENOBUFS;
   11686             : }
   11687             : 
   11688             : 
   11689             : static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
   11690             : {
   11691             :         struct i802_bss *bss = priv;
   11692             :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11693             :         struct nl_msg *msg;
   11694             :         enum nl80211_tdls_operation nl80211_oper;
   11695             : 
   11696             :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
   11697             :                 return -EOPNOTSUPP;
   11698             : 
   11699             :         switch (oper) {
   11700             :         case TDLS_DISCOVERY_REQ:
   11701             :                 nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
   11702             :                 break;
   11703             :         case TDLS_SETUP:
   11704             :                 nl80211_oper = NL80211_TDLS_SETUP;
   11705             :                 break;
   11706             :         case TDLS_TEARDOWN:
   11707             :                 nl80211_oper = NL80211_TDLS_TEARDOWN;
   11708             :                 break;
   11709             :         case TDLS_ENABLE_LINK:
   11710             :                 nl80211_oper = NL80211_TDLS_ENABLE_LINK;
   11711             :                 break;
   11712             :         case TDLS_DISABLE_LINK:
   11713             :                 nl80211_oper = NL80211_TDLS_DISABLE_LINK;
   11714             :                 break;
   11715             :         case TDLS_ENABLE:
   11716             :                 return 0;
   11717             :         case TDLS_DISABLE:
   11718             :                 return 0;
   11719             :         default:
   11720             :                 return -EINVAL;
   11721             :         }
   11722             : 
   11723             :         msg = nlmsg_alloc();
   11724             :         if (!msg)
   11725             :                 return -ENOMEM;
   11726             : 
   11727             :         nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_OPER);
   11728             :         NLA_PUT_U8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper);
   11729             :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   11730             :         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
   11731             : 
   11732             :         return send_and_recv_msgs(drv, msg, NULL, NULL);
   11733             : 
   11734             : nla_put_failure:
   11735             :         nlmsg_free(msg);
   11736             :         return -ENOBUFS;
   11737             : }
   11738             : 
   11739             : #endif /* CONFIG TDLS */
   11740             : 
   11741             : 
   11742             : #ifdef ANDROID
   11743             : 
   11744             : typedef struct android_wifi_priv_cmd {
   11745             :         char *buf;
   11746             :         int used_len;
   11747             :         int total_len;
   11748             : } android_wifi_priv_cmd;
   11749             : 
   11750             : static int drv_errors = 0;
   11751             : 
   11752             : static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
   11753             : {
   11754             :         drv_errors++;
   11755             :         if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
   11756             :                 drv_errors = 0;
   11757             :                 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
   11758             :         }
   11759             : }
   11760             : 
   11761             : 
   11762             : static int android_priv_cmd(struct i802_bss *bss, const char *cmd)
   11763             : {
   11764             :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11765             :         struct ifreq ifr;
   11766             :         android_wifi_priv_cmd priv_cmd;
   11767             :         char buf[MAX_DRV_CMD_SIZE];
   11768             :         int ret;
   11769             : 
   11770             :         os_memset(&ifr, 0, sizeof(ifr));
   11771             :         os_memset(&priv_cmd, 0, sizeof(priv_cmd));
   11772             :         os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
   11773             : 
   11774             :         os_memset(buf, 0, sizeof(buf));
   11775             :         os_strlcpy(buf, cmd, sizeof(buf));
   11776             : 
   11777             :         priv_cmd.buf = buf;
   11778             :         priv_cmd.used_len = sizeof(buf);
   11779             :         priv_cmd.total_len = sizeof(buf);
   11780             :         ifr.ifr_data = &priv_cmd;
   11781             : 
   11782             :         ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
   11783             :         if (ret < 0) {
   11784             :                 wpa_printf(MSG_ERROR, "%s: failed to issue private commands",
   11785             :                            __func__);
   11786             :                 wpa_driver_send_hang_msg(drv);
   11787             :                 return ret;
   11788             :         }
   11789             : 
   11790             :         drv_errors = 0;
   11791             :         return 0;
   11792             : }
   11793             : 
   11794             : 
   11795             : static int android_pno_start(struct i802_bss *bss,
   11796             :                              struct wpa_driver_scan_params *params)
   11797             : {
   11798             :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11799             :         struct ifreq ifr;
   11800             :         android_wifi_priv_cmd priv_cmd;
   11801             :         int ret = 0, i = 0, bp;
   11802             :         char buf[WEXT_PNO_MAX_COMMAND_SIZE];
   11803             : 
   11804             :         bp = WEXT_PNOSETUP_HEADER_SIZE;
   11805             :         os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
   11806             :         buf[bp++] = WEXT_PNO_TLV_PREFIX;
   11807             :         buf[bp++] = WEXT_PNO_TLV_VERSION;
   11808             :         buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
   11809             :         buf[bp++] = WEXT_PNO_TLV_RESERVED;
   11810             : 
   11811             :         while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) {
   11812             :                 /* Check that there is enough space needed for 1 more SSID, the
   11813             :                  * other sections and null termination */
   11814             :                 if ((bp + WEXT_PNO_SSID_HEADER_SIZE + MAX_SSID_LEN +
   11815             :                      WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf))
   11816             :                         break;
   11817             :                 wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan",
   11818             :                                   params->ssids[i].ssid,
   11819             :                                   params->ssids[i].ssid_len);
   11820             :                 buf[bp++] = WEXT_PNO_SSID_SECTION;
   11821             :                 buf[bp++] = params->ssids[i].ssid_len;
   11822             :                 os_memcpy(&buf[bp], params->ssids[i].ssid,
   11823             :                           params->ssids[i].ssid_len);
   11824             :                 bp += params->ssids[i].ssid_len;
   11825             :                 i++;
   11826             :         }
   11827             : 
   11828             :         buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
   11829             :         os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x",
   11830             :                     WEXT_PNO_SCAN_INTERVAL);
   11831             :         bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
   11832             : 
   11833             :         buf[bp++] = WEXT_PNO_REPEAT_SECTION;
   11834             :         os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x",
   11835             :                     WEXT_PNO_REPEAT);
   11836             :         bp += WEXT_PNO_REPEAT_LENGTH;
   11837             : 
   11838             :         buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
   11839             :         os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x",
   11840             :                     WEXT_PNO_MAX_REPEAT);
   11841             :         bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
   11842             : 
   11843             :         memset(&ifr, 0, sizeof(ifr));
   11844             :         memset(&priv_cmd, 0, sizeof(priv_cmd));
   11845             :         os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
   11846             : 
   11847             :         priv_cmd.buf = buf;
   11848             :         priv_cmd.used_len = bp;
   11849             :         priv_cmd.total_len = bp;
   11850             :         ifr.ifr_data = &priv_cmd;
   11851             : 
   11852             :         ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
   11853             : 
   11854             :         if (ret < 0) {
   11855             :                 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
   11856             :                            ret);
   11857             :                 wpa_driver_send_hang_msg(drv);
   11858             :                 return ret;
   11859             :         }
   11860             : 
   11861             :         drv_errors = 0;
   11862             : 
   11863             :         return android_priv_cmd(bss, "PNOFORCE 1");
   11864             : }
   11865             : 
   11866             : 
   11867             : static int android_pno_stop(struct i802_bss *bss)
   11868             : {
   11869             :         return android_priv_cmd(bss, "PNOFORCE 0");
   11870             : }
   11871             : 
   11872             : #endif /* ANDROID */
   11873             : 
   11874             : 
   11875        9752 : static int driver_nl80211_set_key(const char *ifname, void *priv,
   11876             :                                   enum wpa_alg alg, const u8 *addr,
   11877             :                                   int key_idx, int set_tx,
   11878             :                                   const u8 *seq, size_t seq_len,
   11879             :                                   const u8 *key, size_t key_len)
   11880             : {
   11881        9752 :         struct i802_bss *bss = priv;
   11882        9752 :         return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
   11883             :                                           set_tx, seq, seq_len, key, key_len);
   11884             : }
   11885             : 
   11886             : 
   11887          68 : static int driver_nl80211_scan2(void *priv,
   11888             :                                 struct wpa_driver_scan_params *params)
   11889             : {
   11890          68 :         struct i802_bss *bss = priv;
   11891          68 :         return wpa_driver_nl80211_scan(bss, params);
   11892             : }
   11893             : 
   11894             : 
   11895           0 : static int driver_nl80211_deauthenticate(void *priv, const u8 *addr,
   11896             :                                          int reason_code)
   11897             : {
   11898           0 :         struct i802_bss *bss = priv;
   11899           0 :         return wpa_driver_nl80211_deauthenticate(bss, addr, reason_code);
   11900             : }
   11901             : 
   11902             : 
   11903           0 : static int driver_nl80211_authenticate(void *priv,
   11904             :                                        struct wpa_driver_auth_params *params)
   11905             : {
   11906           0 :         struct i802_bss *bss = priv;
   11907           0 :         return wpa_driver_nl80211_authenticate(bss, params);
   11908             : }
   11909             : 
   11910             : 
   11911           0 : static void driver_nl80211_deinit(void *priv)
   11912             : {
   11913           0 :         struct i802_bss *bss = priv;
   11914           0 :         wpa_driver_nl80211_deinit(bss);
   11915           0 : }
   11916             : 
   11917             : 
   11918          30 : static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
   11919             :                                     const char *ifname)
   11920             : {
   11921          30 :         struct i802_bss *bss = priv;
   11922          30 :         return wpa_driver_nl80211_if_remove(bss, type, ifname);
   11923             : }
   11924             : 
   11925             : 
   11926        4286 : static int driver_nl80211_send_mlme(void *priv, const u8 *data,
   11927             :                                     size_t data_len, int noack)
   11928             : {
   11929        4286 :         struct i802_bss *bss = priv;
   11930        4286 :         return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
   11931             :                                             0, 0, 0, 0);
   11932             : }
   11933             : 
   11934             : 
   11935        2340 : static int driver_nl80211_sta_remove(void *priv, const u8 *addr)
   11936             : {
   11937        2340 :         struct i802_bss *bss = priv;
   11938        2340 :         return wpa_driver_nl80211_sta_remove(bss, addr);
   11939             : }
   11940             : 
   11941             : 
   11942          12 : static int driver_nl80211_set_sta_vlan(void *priv, const u8 *addr,
   11943             :                                        const char *ifname, int vlan_id)
   11944             : {
   11945          12 :         struct i802_bss *bss = priv;
   11946          12 :         return i802_set_sta_vlan(bss, addr, ifname, vlan_id);
   11947             : }
   11948             : 
   11949             : 
   11950          47 : static int driver_nl80211_read_sta_data(void *priv,
   11951             :                                         struct hostap_sta_driver_data *data,
   11952             :                                         const u8 *addr)
   11953             : {
   11954          47 :         struct i802_bss *bss = priv;
   11955          47 :         return i802_read_sta_data(bss, data, addr);
   11956             : }
   11957             : 
   11958             : 
   11959         239 : static int driver_nl80211_send_action(void *priv, unsigned int freq,
   11960             :                                       unsigned int wait_time,
   11961             :                                       const u8 *dst, const u8 *src,
   11962             :                                       const u8 *bssid,
   11963             :                                       const u8 *data, size_t data_len,
   11964             :                                       int no_cck)
   11965             : {
   11966         239 :         struct i802_bss *bss = priv;
   11967         239 :         return wpa_driver_nl80211_send_action(bss, freq, wait_time, dst, src,
   11968             :                                               bssid, data, data_len, no_cck);
   11969             : }
   11970             : 
   11971             : 
   11972           0 : static int driver_nl80211_probe_req_report(void *priv, int report)
   11973             : {
   11974           0 :         struct i802_bss *bss = priv;
   11975           0 :         return wpa_driver_nl80211_probe_req_report(bss, report);
   11976             : }
   11977             : 
   11978             : 
   11979           0 : static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
   11980             :                                             const u8 *ies, size_t ies_len)
   11981             : {
   11982             :         int ret;
   11983             :         struct nl_msg *msg;
   11984           0 :         struct i802_bss *bss = priv;
   11985           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   11986           0 :         u16 mdid = WPA_GET_LE16(md);
   11987             : 
   11988           0 :         msg = nlmsg_alloc();
   11989           0 :         if (!msg)
   11990           0 :                 return -ENOMEM;
   11991             : 
   11992           0 :         wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
   11993           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_UPDATE_FT_IES);
   11994           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   11995           0 :         NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies);
   11996           0 :         NLA_PUT_U16(msg, NL80211_ATTR_MDID, mdid);
   11997             : 
   11998           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   11999           0 :         if (ret) {
   12000           0 :                 wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
   12001             :                            "err=%d (%s)", ret, strerror(-ret));
   12002             :         }
   12003             : 
   12004           0 :         return ret;
   12005             : 
   12006             : nla_put_failure:
   12007           0 :         nlmsg_free(msg);
   12008           0 :         return -ENOBUFS;
   12009             : }
   12010             : 
   12011             : 
   12012           0 : const u8 * wpa_driver_nl80211_get_macaddr(void *priv)
   12013             : {
   12014           0 :         struct i802_bss *bss = priv;
   12015           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12016             : 
   12017           0 :         if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE)
   12018           0 :                 return NULL;
   12019             : 
   12020           0 :         return bss->addr;
   12021             : }
   12022             : 
   12023             : 
   12024           3 : static const char * scan_state_str(enum scan_states scan_state)
   12025             : {
   12026           3 :         switch (scan_state) {
   12027             :         case NO_SCAN:
   12028           3 :                 return "NO_SCAN";
   12029             :         case SCAN_REQUESTED:
   12030           0 :                 return "SCAN_REQUESTED";
   12031             :         case SCAN_STARTED:
   12032           0 :                 return "SCAN_STARTED";
   12033             :         case SCAN_COMPLETED:
   12034           0 :                 return "SCAN_COMPLETED";
   12035             :         case SCAN_ABORTED:
   12036           0 :                 return "SCAN_ABORTED";
   12037             :         case SCHED_SCAN_STARTED:
   12038           0 :                 return "SCHED_SCAN_STARTED";
   12039             :         case SCHED_SCAN_STOPPED:
   12040           0 :                 return "SCHED_SCAN_STOPPED";
   12041             :         case SCHED_SCAN_RESULTS:
   12042           0 :                 return "SCHED_SCAN_RESULTS";
   12043             :         }
   12044             : 
   12045           0 :         return "??";
   12046             : }
   12047             : 
   12048             : 
   12049           3 : static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
   12050             : {
   12051           3 :         struct i802_bss *bss = priv;
   12052           3 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12053             :         int res;
   12054             :         char *pos, *end;
   12055             : 
   12056           3 :         pos = buf;
   12057           3 :         end = buf + buflen;
   12058             : 
   12059          36 :         res = os_snprintf(pos, end - pos,
   12060             :                           "ifindex=%d\n"
   12061             :                           "ifname=%s\n"
   12062             :                           "brname=%s\n"
   12063             :                           "addr=" MACSTR "\n"
   12064             :                           "freq=%d\n"
   12065             :                           "%s%s%s%s%s",
   12066             :                           bss->ifindex,
   12067           3 :                           bss->ifname,
   12068           3 :                           bss->brname,
   12069          18 :                           MAC2STR(bss->addr),
   12070             :                           bss->freq,
   12071           3 :                           bss->beacon_set ? "beacon_set=1\n" : "",
   12072           3 :                           bss->added_if_into_bridge ?
   12073             :                           "added_if_into_bridge=1\n" : "",
   12074           3 :                           bss->added_bridge ? "added_bridge=1\n" : "",
   12075           3 :                           bss->in_deinit ? "in_deinit=1\n" : "",
   12076           3 :                           bss->if_dynamic ? "if_dynamic=1\n" : "");
   12077           3 :         if (res < 0 || res >= end - pos)
   12078           0 :                 return pos - buf;
   12079           3 :         pos += res;
   12080             : 
   12081           3 :         if (bss->wdev_id_set) {
   12082           0 :                 res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
   12083           0 :                                   (unsigned long long) bss->wdev_id);
   12084           0 :                 if (res < 0 || res >= end - pos)
   12085           0 :                         return pos - buf;
   12086           0 :                 pos += res;
   12087             :         }
   12088             : 
   12089         135 :         res = os_snprintf(pos, end - pos,
   12090             :                           "phyname=%s\n"
   12091             :                           "perm_addr=" MACSTR "\n"
   12092             :                           "drv_ifindex=%d\n"
   12093             :                           "operstate=%d\n"
   12094             :                           "scan_state=%s\n"
   12095             :                           "auth_bssid=" MACSTR "\n"
   12096             :                           "auth_attempt_bssid=" MACSTR "\n"
   12097             :                           "bssid=" MACSTR "\n"
   12098             :                           "prev_bssid=" MACSTR "\n"
   12099             :                           "associated=%d\n"
   12100             :                           "assoc_freq=%u\n"
   12101             :                           "monitor_sock=%d\n"
   12102             :                           "monitor_ifidx=%d\n"
   12103             :                           "monitor_refcount=%d\n"
   12104             :                           "last_mgmt_freq=%u\n"
   12105             :                           "eapol_tx_sock=%d\n"
   12106             :                           "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
   12107           3 :                           drv->phyname,
   12108          18 :                           MAC2STR(drv->perm_addr),
   12109             :                           drv->ifindex,
   12110             :                           drv->operstate,
   12111             :                           scan_state_str(drv->scan_state),
   12112          18 :                           MAC2STR(drv->auth_bssid),
   12113          18 :                           MAC2STR(drv->auth_attempt_bssid),
   12114          18 :                           MAC2STR(drv->bssid),
   12115          18 :                           MAC2STR(drv->prev_bssid),
   12116             :                           drv->associated,
   12117             :                           drv->assoc_freq,
   12118             :                           drv->monitor_sock,
   12119             :                           drv->monitor_ifidx,
   12120             :                           drv->monitor_refcount,
   12121             :                           drv->last_mgmt_freq,
   12122             :                           drv->eapol_tx_sock,
   12123           3 :                           drv->ignore_if_down_event ?
   12124             :                           "ignore_if_down_event=1\n" : "",
   12125           3 :                           drv->scan_complete_events ?
   12126             :                           "scan_complete_events=1\n" : "",
   12127           3 :                           drv->disabled_11b_rates ?
   12128             :                           "disabled_11b_rates=1\n" : "",
   12129           3 :                           drv->pending_remain_on_chan ?
   12130             :                           "pending_remain_on_chan=1\n" : "",
   12131           3 :                           drv->in_interface_list ? "in_interface_list=1\n" : "",
   12132           3 :                           drv->device_ap_sme ? "device_ap_sme=1\n" : "",
   12133           3 :                           drv->poll_command_supported ?
   12134             :                           "poll_command_supported=1\n" : "",
   12135           3 :                           drv->data_tx_status ? "data_tx_status=1\n" : "",
   12136           3 :                           drv->scan_for_auth ? "scan_for_auth=1\n" : "",
   12137           3 :                           drv->retry_auth ? "retry_auth=1\n" : "",
   12138           3 :                           drv->use_monitor ? "use_monitor=1\n" : "",
   12139           3 :                           drv->ignore_next_local_disconnect ?
   12140             :                           "ignore_next_local_disconnect=1\n" : "",
   12141           3 :                           drv->ignore_next_local_deauth ?
   12142             :                           "ignore_next_local_deauth=1\n" : "",
   12143           3 :                           drv->allow_p2p_device ? "allow_p2p_device=1\n" : "");
   12144           3 :         if (res < 0 || res >= end - pos)
   12145           0 :                 return pos - buf;
   12146           3 :         pos += res;
   12147             : 
   12148           3 :         if (drv->has_capability) {
   12149           3 :                 res = os_snprintf(pos, end - pos,
   12150             :                                   "capa.key_mgmt=0x%x\n"
   12151             :                                   "capa.enc=0x%x\n"
   12152             :                                   "capa.auth=0x%x\n"
   12153             :                                   "capa.flags=0x%x\n"
   12154             :                                   "capa.max_scan_ssids=%d\n"
   12155             :                                   "capa.max_sched_scan_ssids=%d\n"
   12156             :                                   "capa.sched_scan_supported=%d\n"
   12157             :                                   "capa.max_match_sets=%d\n"
   12158             :                                   "capa.max_remain_on_chan=%u\n"
   12159             :                                   "capa.max_stations=%u\n"
   12160             :                                   "capa.probe_resp_offloads=0x%x\n"
   12161             :                                   "capa.max_acl_mac_addrs=%u\n"
   12162             :                                   "capa.num_multichan_concurrent=%u\n",
   12163             :                                   drv->capa.key_mgmt,
   12164             :                                   drv->capa.enc,
   12165             :                                   drv->capa.auth,
   12166             :                                   drv->capa.flags,
   12167             :                                   drv->capa.max_scan_ssids,
   12168             :                                   drv->capa.max_sched_scan_ssids,
   12169             :                                   drv->capa.sched_scan_supported,
   12170             :                                   drv->capa.max_match_sets,
   12171             :                                   drv->capa.max_remain_on_chan,
   12172             :                                   drv->capa.max_stations,
   12173             :                                   drv->capa.probe_resp_offloads,
   12174             :                                   drv->capa.max_acl_mac_addrs,
   12175             :                                   drv->capa.num_multichan_concurrent);
   12176           3 :                 if (res < 0 || res >= end - pos)
   12177           0 :                         return pos - buf;
   12178           3 :                 pos += res;
   12179             :         }
   12180             : 
   12181           3 :         return pos - buf;
   12182             : }
   12183             : 
   12184             : 
   12185           2 : static int set_beacon_data(struct nl_msg *msg, struct beacon_data *settings)
   12186             : {
   12187           2 :         if (settings->head)
   12188           2 :                 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD,
   12189             :                         settings->head_len, settings->head);
   12190             : 
   12191           2 :         if (settings->tail)
   12192           2 :                 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL,
   12193             :                         settings->tail_len, settings->tail);
   12194             : 
   12195           2 :         if (settings->beacon_ies)
   12196           2 :                 NLA_PUT(msg, NL80211_ATTR_IE,
   12197             :                         settings->beacon_ies_len, settings->beacon_ies);
   12198             : 
   12199           2 :         if (settings->proberesp_ies)
   12200           2 :                 NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
   12201             :                         settings->proberesp_ies_len, settings->proberesp_ies);
   12202             : 
   12203           2 :         if (settings->assocresp_ies)
   12204           2 :                 NLA_PUT(msg,
   12205             :                         NL80211_ATTR_IE_ASSOC_RESP,
   12206             :                         settings->assocresp_ies_len, settings->assocresp_ies);
   12207             : 
   12208           2 :         if (settings->probe_resp)
   12209           0 :                 NLA_PUT(msg, NL80211_ATTR_PROBE_RESP,
   12210             :                         settings->probe_resp_len, settings->probe_resp);
   12211             : 
   12212           2 :         return 0;
   12213             : 
   12214             : nla_put_failure:
   12215           0 :         return -ENOBUFS;
   12216             : }
   12217             : 
   12218             : 
   12219           2 : static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
   12220             : {
   12221             :         struct nl_msg *msg;
   12222           2 :         struct i802_bss *bss = priv;
   12223           2 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12224             :         struct nlattr *beacon_csa;
   12225           2 :         int ret = -ENOBUFS;
   12226             : 
   12227           6 :         wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
   12228           4 :                    settings->cs_count, settings->block_tx,
   12229             :                    settings->freq_params.freq, settings->freq_params.bandwidth,
   12230             :                    settings->freq_params.center_freq1,
   12231             :                    settings->freq_params.center_freq2);
   12232             : 
   12233           2 :         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
   12234           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
   12235           0 :                 return -EOPNOTSUPP;
   12236             :         }
   12237             : 
   12238           2 :         if ((drv->nlmode != NL80211_IFTYPE_AP) &&
   12239           0 :             (drv->nlmode != NL80211_IFTYPE_P2P_GO))
   12240           0 :                 return -EOPNOTSUPP;
   12241             : 
   12242             :         /* check settings validity */
   12243           4 :         if (!settings->beacon_csa.tail ||
   12244           4 :             ((settings->beacon_csa.tail_len <=
   12245           4 :               settings->counter_offset_beacon) ||
   12246           2 :              (settings->beacon_csa.tail[settings->counter_offset_beacon] !=
   12247           2 :               settings->cs_count)))
   12248           0 :                 return -EINVAL;
   12249             : 
   12250           2 :         if (settings->beacon_csa.probe_resp &&
   12251           0 :             ((settings->beacon_csa.probe_resp_len <=
   12252           0 :               settings->counter_offset_presp) ||
   12253           0 :              (settings->beacon_csa.probe_resp[settings->counter_offset_presp] !=
   12254           0 :               settings->cs_count)))
   12255           0 :                 return -EINVAL;
   12256             : 
   12257           2 :         msg = nlmsg_alloc();
   12258           2 :         if (!msg)
   12259           0 :                 return -ENOMEM;
   12260             : 
   12261           2 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
   12262           2 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
   12263           2 :         NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count);
   12264           2 :         ret = nl80211_put_freq_params(msg, &settings->freq_params);
   12265           2 :         if (ret)
   12266           1 :                 goto error;
   12267             : 
   12268           1 :         if (settings->block_tx)
   12269           1 :                 NLA_PUT_FLAG(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX);
   12270             : 
   12271             :         /* beacon_after params */
   12272           1 :         ret = set_beacon_data(msg, &settings->beacon_after);
   12273           1 :         if (ret)
   12274           0 :                 goto error;
   12275             : 
   12276             :         /* beacon_csa params */
   12277           1 :         beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES);
   12278           1 :         if (!beacon_csa)
   12279           0 :                 goto nla_put_failure;
   12280             : 
   12281           1 :         ret = set_beacon_data(msg, &settings->beacon_csa);
   12282           1 :         if (ret)
   12283           0 :                 goto error;
   12284             : 
   12285           1 :         NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_BEACON,
   12286             :                     settings->counter_offset_beacon);
   12287             : 
   12288           1 :         if (settings->beacon_csa.probe_resp)
   12289           0 :                 NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_PRESP,
   12290             :                             settings->counter_offset_presp);
   12291             : 
   12292           1 :         nla_nest_end(msg, beacon_csa);
   12293           1 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   12294           1 :         if (ret) {
   12295           0 :                 wpa_printf(MSG_DEBUG, "nl80211: switch_channel failed err=%d (%s)",
   12296             :                            ret, strerror(-ret));
   12297             :         }
   12298           1 :         return ret;
   12299             : 
   12300             : nla_put_failure:
   12301           0 :         ret = -ENOBUFS;
   12302             : error:
   12303           1 :         nlmsg_free(msg);
   12304           1 :         wpa_printf(MSG_DEBUG, "nl80211: Could not build channel switch request");
   12305           1 :         return ret;
   12306             : }
   12307             : 
   12308             : 
   12309             : #ifdef CONFIG_TESTING_OPTIONS
   12310           0 : static int cmd_reply_handler(struct nl_msg *msg, void *arg)
   12311             : {
   12312           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   12313           0 :         struct wpabuf *buf = arg;
   12314             : 
   12315           0 :         if (!buf)
   12316           0 :                 return NL_SKIP;
   12317             : 
   12318           0 :         if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
   12319           0 :                 wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
   12320           0 :                 return NL_SKIP;
   12321             :         }
   12322             : 
   12323           0 :         wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
   12324           0 :                         genlmsg_attrlen(gnlh, 0));
   12325             : 
   12326           0 :         return NL_SKIP;
   12327             : }
   12328             : #endif /* CONFIG_TESTING_OPTIONS */
   12329             : 
   12330             : 
   12331           0 : static int vendor_reply_handler(struct nl_msg *msg, void *arg)
   12332             : {
   12333             :         struct nlattr *tb[NL80211_ATTR_MAX + 1];
   12334             :         struct nlattr *nl_vendor_reply, *nl;
   12335           0 :         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   12336           0 :         struct wpabuf *buf = arg;
   12337             :         int rem;
   12338             : 
   12339           0 :         if (!buf)
   12340           0 :                 return NL_SKIP;
   12341             : 
   12342           0 :         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
   12343             :                   genlmsg_attrlen(gnlh, 0), NULL);
   12344           0 :         nl_vendor_reply = tb[NL80211_ATTR_VENDOR_DATA];
   12345             : 
   12346           0 :         if (!nl_vendor_reply)
   12347           0 :                 return NL_SKIP;
   12348             : 
   12349           0 :         if ((size_t) nla_len(nl_vendor_reply) > wpabuf_tailroom(buf)) {
   12350           0 :                 wpa_printf(MSG_INFO, "nl80211: Vendor command: insufficient buffer space for reply");
   12351           0 :                 return NL_SKIP;
   12352             :         }
   12353             : 
   12354           0 :         nla_for_each_nested(nl, nl_vendor_reply, rem) {
   12355           0 :                 wpabuf_put_data(buf, nla_data(nl), nla_len(nl));
   12356             :         }
   12357             : 
   12358           0 :         return NL_SKIP;
   12359             : }
   12360             : 
   12361             : 
   12362           0 : static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
   12363             :                               unsigned int subcmd, const u8 *data,
   12364             :                               size_t data_len, struct wpabuf *buf)
   12365             : {
   12366           0 :         struct i802_bss *bss = priv;
   12367           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12368             :         struct nl_msg *msg;
   12369             :         int ret;
   12370             : 
   12371           0 :         msg = nlmsg_alloc();
   12372           0 :         if (!msg)
   12373           0 :                 return -ENOMEM;
   12374             : 
   12375             : #ifdef CONFIG_TESTING_OPTIONS
   12376           0 :         if (vendor_id == 0xffffffff) {
   12377           0 :                 nl80211_cmd(drv, msg, 0, subcmd);
   12378           0 :                 if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
   12379             :                     0)
   12380           0 :                         goto nla_put_failure;
   12381           0 :                 ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
   12382           0 :                 if (ret)
   12383           0 :                         wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
   12384             :                                    ret);
   12385           0 :                 return ret;
   12386             :         }
   12387             : #endif /* CONFIG_TESTING_OPTIONS */
   12388             : 
   12389           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
   12390           0 :         if (nl80211_set_iface_id(msg, bss) < 0)
   12391           0 :                 goto nla_put_failure;
   12392           0 :         NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, vendor_id);
   12393           0 :         NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd);
   12394           0 :         if (data)
   12395           0 :                 NLA_PUT(msg, NL80211_ATTR_VENDOR_DATA, data_len, data);
   12396             : 
   12397           0 :         ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, buf);
   12398           0 :         if (ret)
   12399           0 :                 wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d",
   12400             :                            ret);
   12401           0 :         return ret;
   12402             : 
   12403             : nla_put_failure:
   12404           0 :         nlmsg_free(msg);
   12405           0 :         return -ENOBUFS;
   12406             : }
   12407             : 
   12408             : 
   12409           3 : static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
   12410             :                                u8 qos_map_set_len)
   12411             : {
   12412           3 :         struct i802_bss *bss = priv;
   12413           3 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12414             :         struct nl_msg *msg;
   12415             :         int ret;
   12416             : 
   12417           3 :         msg = nlmsg_alloc();
   12418           3 :         if (!msg)
   12419           0 :                 return -ENOMEM;
   12420             : 
   12421           3 :         wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
   12422             :                     qos_map_set, qos_map_set_len);
   12423             : 
   12424           3 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_QOS_MAP);
   12425           3 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   12426           3 :         NLA_PUT(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set);
   12427             : 
   12428           3 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   12429           3 :         if (ret)
   12430           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
   12431             : 
   12432           3 :         return ret;
   12433             : 
   12434             : nla_put_failure:
   12435           0 :         nlmsg_free(msg);
   12436           0 :         return -ENOBUFS;
   12437             : }
   12438             : 
   12439             : 
   12440           0 : static int nl80211_set_wowlan(void *priv,
   12441             :                               const struct wowlan_triggers *triggers)
   12442             : {
   12443           0 :         struct i802_bss *bss = priv;
   12444           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12445             :         struct nl_msg *msg;
   12446             :         struct nlattr *wowlan_triggers;
   12447             :         int ret;
   12448             : 
   12449           0 :         msg = nlmsg_alloc();
   12450           0 :         if (!msg)
   12451           0 :                 return -ENOMEM;
   12452             : 
   12453           0 :         wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan");
   12454             : 
   12455           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WOWLAN);
   12456           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   12457             : 
   12458           0 :         wowlan_triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
   12459           0 :         if (!wowlan_triggers)
   12460           0 :                 goto nla_put_failure;
   12461             : 
   12462           0 :         if (triggers->any)
   12463           0 :                 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
   12464           0 :         if (triggers->disconnect)
   12465           0 :                 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
   12466           0 :         if (triggers->magic_pkt)
   12467           0 :                 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
   12468           0 :         if (triggers->gtk_rekey_failure)
   12469           0 :                 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
   12470           0 :         if (triggers->eap_identity_req)
   12471           0 :                 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
   12472           0 :         if (triggers->four_way_handshake)
   12473           0 :                 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
   12474           0 :         if (triggers->rfkill_release)
   12475           0 :                 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
   12476             : 
   12477           0 :         nla_nest_end(msg, wowlan_triggers);
   12478             : 
   12479           0 :         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
   12480           0 :         if (ret)
   12481           0 :                 wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan failed");
   12482             : 
   12483           0 :         return ret;
   12484             : 
   12485             : nla_put_failure:
   12486           0 :         nlmsg_free(msg);
   12487           0 :         return -ENOBUFS;
   12488             : }
   12489             : 
   12490             : 
   12491           0 : static int nl80211_roaming(void *priv, int allowed, const u8 *bssid)
   12492             : {
   12493           0 :         struct i802_bss *bss = priv;
   12494           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12495             :         struct nl_msg *msg;
   12496             :         struct nlattr *params;
   12497             : 
   12498           0 :         wpa_printf(MSG_DEBUG, "nl80211: Roaming policy: allowed=%d", allowed);
   12499             : 
   12500           0 :         if (!drv->roaming_vendor_cmd_avail) {
   12501           0 :                 wpa_printf(MSG_DEBUG,
   12502             :                            "nl80211: Ignore roaming policy change since driver does not provide command for setting it");
   12503           0 :                 return -1;
   12504             :         }
   12505             : 
   12506           0 :         msg = nlmsg_alloc();
   12507           0 :         if (!msg)
   12508           0 :                 return -ENOMEM;
   12509             : 
   12510           0 :         nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
   12511             : 
   12512           0 :         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
   12513           0 :         NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
   12514           0 :         NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD,
   12515             :                     QCA_NL80211_VENDOR_SUBCMD_ROAMING);
   12516             : 
   12517           0 :         params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
   12518           0 :         if (!params)
   12519           0 :                 goto nla_put_failure;
   12520           0 :         NLA_PUT_U32(msg, QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY,
   12521             :                     allowed ? QCA_ROAMING_ALLOWED_WITHIN_ESS :
   12522             :                     QCA_ROAMING_NOT_ALLOWED);
   12523           0 :         if (bssid)
   12524           0 :                 NLA_PUT(msg, QCA_WLAN_VENDOR_ATTR_MAC_ADDR, ETH_ALEN, bssid);
   12525           0 :         nla_nest_end(msg, params);
   12526             : 
   12527           0 :         return send_and_recv_msgs(drv, msg, NULL, NULL);
   12528             : 
   12529             :  nla_put_failure:
   12530           0 :         nlmsg_free(msg);
   12531           0 :         return -1;
   12532             : }
   12533             : 
   12534             : 
   12535           0 : static int nl80211_set_mac_addr(void *priv, const u8 *addr)
   12536             : {
   12537           0 :         struct i802_bss *bss = priv;
   12538           0 :         struct wpa_driver_nl80211_data *drv = bss->drv;
   12539           0 :         int new_addr = addr != NULL;
   12540             : 
   12541           0 :         if (!addr)
   12542           0 :                 addr = drv->perm_addr;
   12543             : 
   12544           0 :         if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) < 0)
   12545           0 :                 return -1;
   12546             : 
   12547           0 :         if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname, addr) < 0)
   12548             :         {
   12549           0 :                 wpa_printf(MSG_DEBUG,
   12550             :                            "nl80211: failed to set_mac_addr for %s to " MACSTR,
   12551           0 :                            bss->ifname, MAC2STR(addr));
   12552           0 :                 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
   12553             :                                           1) < 0) {
   12554           0 :                         wpa_printf(MSG_DEBUG,
   12555             :                                    "nl80211: Could not restore interface UP after failed set_mac_addr");
   12556             :                 }
   12557           0 :                 return -1;
   12558             :         }
   12559             : 
   12560           0 :         wpa_printf(MSG_DEBUG, "nl80211: set_mac_addr for %s to " MACSTR,
   12561           0 :                    bss->ifname, MAC2STR(addr));
   12562           0 :         drv->addr_changed = new_addr;
   12563           0 :         os_memcpy(bss->addr, addr, ETH_ALEN);
   12564             : 
   12565           0 :         if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1) < 0)
   12566             :         {
   12567           0 :                 wpa_printf(MSG_DEBUG,
   12568             :                            "nl80211: Could not restore interface UP after set_mac_addr");
   12569             :         }
   12570             : 
   12571           0 :         return 0;
   12572             : }
   12573             : 
   12574             : 
   12575             : const struct wpa_driver_ops wpa_driver_nl80211_ops = {
   12576             :         .name = "nl80211",
   12577             :         .desc = "Linux nl80211/cfg80211",
   12578             :         .get_bssid = wpa_driver_nl80211_get_bssid,
   12579             :         .get_ssid = wpa_driver_nl80211_get_ssid,
   12580             :         .set_key = driver_nl80211_set_key,
   12581             :         .scan2 = driver_nl80211_scan2,
   12582             :         .sched_scan = wpa_driver_nl80211_sched_scan,
   12583             :         .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
   12584             :         .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
   12585             :         .deauthenticate = driver_nl80211_deauthenticate,
   12586             :         .authenticate = driver_nl80211_authenticate,
   12587             :         .associate = wpa_driver_nl80211_associate,
   12588             :         .global_init = nl80211_global_init,
   12589             :         .global_deinit = nl80211_global_deinit,
   12590             :         .init2 = wpa_driver_nl80211_init,
   12591             :         .deinit = driver_nl80211_deinit,
   12592             :         .get_capa = wpa_driver_nl80211_get_capa,
   12593             :         .set_operstate = wpa_driver_nl80211_set_operstate,
   12594             :         .set_supp_port = wpa_driver_nl80211_set_supp_port,
   12595             :         .set_country = wpa_driver_nl80211_set_country,
   12596             :         .get_country = wpa_driver_nl80211_get_country,
   12597             :         .set_ap = wpa_driver_nl80211_set_ap,
   12598             :         .set_acl = wpa_driver_nl80211_set_acl,
   12599             :         .if_add = wpa_driver_nl80211_if_add,
   12600             :         .if_remove = driver_nl80211_if_remove,
   12601             :         .send_mlme = driver_nl80211_send_mlme,
   12602             :         .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
   12603             :         .sta_add = wpa_driver_nl80211_sta_add,
   12604             :         .sta_remove = driver_nl80211_sta_remove,
   12605             :         .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
   12606             :         .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
   12607             :         .hapd_init = i802_init,
   12608             :         .hapd_deinit = i802_deinit,
   12609             :         .set_wds_sta = i802_set_wds_sta,
   12610             :         .get_seqnum = i802_get_seqnum,
   12611             :         .flush = i802_flush,
   12612             :         .get_inact_sec = i802_get_inact_sec,
   12613             :         .sta_clear_stats = i802_sta_clear_stats,
   12614             :         .set_rts = i802_set_rts,
   12615             :         .set_frag = i802_set_frag,
   12616             :         .set_tx_queue_params = i802_set_tx_queue_params,
   12617             :         .set_sta_vlan = driver_nl80211_set_sta_vlan,
   12618             :         .sta_deauth = i802_sta_deauth,
   12619             :         .sta_disassoc = i802_sta_disassoc,
   12620             :         .read_sta_data = driver_nl80211_read_sta_data,
   12621             :         .set_freq = i802_set_freq,
   12622             :         .send_action = driver_nl80211_send_action,
   12623             :         .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
   12624             :         .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
   12625             :         .cancel_remain_on_channel =
   12626             :         wpa_driver_nl80211_cancel_remain_on_channel,
   12627             :         .probe_req_report = driver_nl80211_probe_req_report,
   12628             :         .deinit_ap = wpa_driver_nl80211_deinit_ap,
   12629             :         .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
   12630             :         .resume = wpa_driver_nl80211_resume,
   12631             :         .send_ft_action = nl80211_send_ft_action,
   12632             :         .signal_monitor = nl80211_signal_monitor,
   12633             :         .signal_poll = nl80211_signal_poll,
   12634             :         .send_frame = nl80211_send_frame,
   12635             :         .shared_freq = wpa_driver_nl80211_shared_freq,
   12636             :         .set_param = nl80211_set_param,
   12637             :         .get_radio_name = nl80211_get_radio_name,
   12638             :         .add_pmkid = nl80211_add_pmkid,
   12639             :         .remove_pmkid = nl80211_remove_pmkid,
   12640             :         .flush_pmkid = nl80211_flush_pmkid,
   12641             :         .set_rekey_info = nl80211_set_rekey_info,
   12642             :         .poll_client = nl80211_poll_client,
   12643             :         .set_p2p_powersave = nl80211_set_p2p_powersave,
   12644             :         .start_dfs_cac = nl80211_start_radar_detection,
   12645             :         .stop_ap = wpa_driver_nl80211_stop_ap,
   12646             : #ifdef CONFIG_TDLS
   12647             :         .send_tdls_mgmt = nl80211_send_tdls_mgmt,
   12648             :         .tdls_oper = nl80211_tdls_oper,
   12649             : #endif /* CONFIG_TDLS */
   12650             :         .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
   12651             :         .get_mac_addr = wpa_driver_nl80211_get_macaddr,
   12652             :         .get_survey = wpa_driver_nl80211_get_survey,
   12653             :         .status = wpa_driver_nl80211_status,
   12654             :         .switch_channel = nl80211_switch_channel,
   12655             : #ifdef ANDROID_P2P
   12656             :         .set_noa = wpa_driver_set_p2p_noa,
   12657             :         .get_noa = wpa_driver_get_p2p_noa,
   12658             :         .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
   12659             : #endif /* ANDROID_P2P */
   12660             : #ifdef ANDROID
   12661             :         .driver_cmd = wpa_driver_nl80211_driver_cmd,
   12662             : #endif /* ANDROID */
   12663             :         .vendor_cmd = nl80211_vendor_cmd,
   12664             :         .set_qos_map = nl80211_set_qos_map,
   12665             :         .set_wowlan = nl80211_set_wowlan,
   12666             :         .roaming = nl80211_roaming,
   12667             :         .set_mac_addr = nl80211_set_mac_addr,
   12668             : };

Generated by: LCOV version 1.10