]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/drivers/driver_nl80211.c
tests: Add more cred parameters into config file test
[thirdparty/hostap.git] / src / drivers / driver_nl80211.c
CommitLineData
3f5285e8 1/*
c5121837 2 * Driver interaction with Linux nl80211/cfg80211
90a545cc 3 * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
072ad14c
JM
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>
58f6fbe0 7 * Copyright (c) 2009-2010, Atheros Communications
3f5285e8 8 *
0f3d578e
JM
9 * This software may be distributed under the terms of the BSD license.
10 * See README for more details.
3f5285e8
JM
11 */
12
13#include "includes.h"
14#include <sys/ioctl.h>
6859f1cb
BG
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <fcntl.h>
37b7d082 18#include <net/if.h>
3f5285e8
JM
19#include <netlink/genl/genl.h>
20#include <netlink/genl/family.h>
21#include <netlink/genl/ctrl.h>
8602b0f2 22#include <linux/rtnetlink.h>
1b648c7e
JM
23#include <netpacket/packet.h>
24#include <linux/filter.h>
32ab4855 25#include <linux/errqueue.h>
7e45830a 26#include "nl80211_copy.h"
625f587b 27
3f5285e8 28#include "common.h"
1b648c7e 29#include "eloop.h"
f2ed8023 30#include "utils/list.h"
1682c623 31#include "common/qca-vendor.h"
a26582cb 32#include "common/qca-vendor-attr.h"
1b648c7e 33#include "common/ieee802_11_defs.h"
9b90955e 34#include "common/ieee802_11_common.h"
f10bfc9a 35#include "l2_packet/l2_packet.h"
e2d02c29 36#include "netlink.h"
34f2f814 37#include "linux_ioctl.h"
e2d02c29
JM
38#include "radiotap.h"
39#include "radiotap_iter.h"
8401a6b0 40#include "rfkill.h"
1b648c7e 41#include "driver.h"
0915d02c 42
32ab4855
JB
43#ifndef SO_WIFI_STATUS
44# if defined(__sparc__)
45# define SO_WIFI_STATUS 0x0025
46# elif defined(__parisc__)
47# define SO_WIFI_STATUS 0x4022
48# else
49# define SO_WIFI_STATUS 41
50# endif
51
52# define SCM_WIFI_STATUS SO_WIFI_STATUS
53#endif
54
55#ifndef SO_EE_ORIGIN_TXSTATUS
56#define SO_EE_ORIGIN_TXSTATUS 4
57#endif
58
59#ifndef PACKET_TX_TIMESTAMP
60#define PACKET_TX_TIMESTAMP 16
61#endif
62
216eede8
DS
63#ifdef ANDROID
64#include "android_drv.h"
65#endif /* ANDROID */
c5121837
JM
66#ifdef CONFIG_LIBNL20
67/* libnl 2.0 compatibility code */
2e8eac2d 68#define nl_handle nl_sock
a65a9aed
JB
69#define nl80211_handle_alloc nl_socket_alloc_cb
70#define nl80211_handle_destroy nl_socket_free
71#else
72/*
73 * libnl 1.1 has a bug, it tries to allocate socket numbers densely
74 * but when you free a socket again it will mess up its bitmap and
75 * and use the wrong number the next time it needs a socket ID.
76 * Therefore, we wrap the handle alloc/destroy and add our own pid
77 * accounting.
78 */
79static uint32_t port_bitmap[32] = { 0 };
80
81static struct nl_handle *nl80211_handle_alloc(void *cb)
82{
83 struct nl_handle *handle;
84 uint32_t pid = getpid() & 0x3FFFFF;
85 int i;
86
87 handle = nl_handle_alloc_cb(cb);
88
89 for (i = 0; i < 1024; i++) {
90 if (port_bitmap[i / 32] & (1 << (i % 32)))
91 continue;
92 port_bitmap[i / 32] |= 1 << (i % 32);
93 pid += i << 22;
94 break;
95 }
96
97 nl_socket_set_local_port(handle, pid);
98
99 return handle;
100}
101
102static void nl80211_handle_destroy(struct nl_handle *handle)
103{
104 uint32_t port = nl_socket_get_local_port(handle);
105
106 port >>= 22;
107 port_bitmap[port / 32] &= ~(1 << (port % 32));
108
109 nl_handle_destroy(handle);
110}
c5121837
JM
111#endif /* CONFIG_LIBNL20 */
112
c5121837 113
1c6edec6
JM
114#ifdef ANDROID
115/* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
116static int android_nl_socket_set_nonblocking(struct nl_handle *handle)
117{
118 return fcntl(nl_socket_get_fd(handle), F_SETFL, O_NONBLOCK);
119}
120#undef nl_socket_set_nonblocking
121#define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h)
122#endif /* ANDROID */
123
124
481234cf 125static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
a92dfde8 126{
481234cf 127 struct nl_handle *handle;
a92dfde8 128
481234cf
JM
129 handle = nl80211_handle_alloc(cb);
130 if (handle == NULL) {
a92dfde8
JB
131 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
132 "callbacks (%s)", dbg);
481234cf 133 return NULL;
a92dfde8
JB
134 }
135
481234cf 136 if (genl_connect(handle)) {
a92dfde8
JB
137 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
138 "netlink (%s)", dbg);
481234cf
JM
139 nl80211_handle_destroy(handle);
140 return NULL;
a92dfde8
JB
141 }
142
481234cf 143 return handle;
a92dfde8
JB
144}
145
146
481234cf 147static void nl_destroy_handles(struct nl_handle **handle)
a92dfde8 148{
481234cf 149 if (*handle == NULL)
a92dfde8 150 return;
481234cf
JM
151 nl80211_handle_destroy(*handle);
152 *handle = NULL;
a92dfde8
JB
153}
154
155
10b85921
JB
156#if __WORDSIZE == 64
157#define ELOOP_SOCKET_INVALID (intptr_t) 0x8888888888888889ULL
158#else
159#define ELOOP_SOCKET_INVALID (intptr_t) 0x88888889ULL
160#endif
161
5f65e9f7
JB
162static void nl80211_register_eloop_read(struct nl_handle **handle,
163 eloop_sock_handler handler,
164 void *eloop_data)
165{
10b85921 166 nl_socket_set_nonblocking(*handle);
5f65e9f7
JB
167 eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
168 eloop_data, *handle);
10b85921 169 *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
5f65e9f7
JB
170}
171
172
173static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
174{
10b85921 175 *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
5f65e9f7
JB
176 eloop_unregister_read_sock(nl_socket_get_fd(*handle));
177 nl_destroy_handles(handle);
178}
179
180
3f5285e8
JM
181#ifndef IFF_LOWER_UP
182#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
183#endif
184#ifndef IFF_DORMANT
185#define IFF_DORMANT 0x20000 /* driver signals dormant */
186#endif
187
188#ifndef IF_OPER_DORMANT
189#define IF_OPER_DORMANT 5
190#endif
191#ifndef IF_OPER_UP
192#define IF_OPER_UP 6
193#endif
194
f2ed8023
JM
195struct nl80211_global {
196 struct dl_list interfaces;
ff6a158b 197 int if_add_ifindex;
f632e483
AS
198 u64 if_add_wdevid;
199 int if_add_wdevid_set;
36d84860 200 struct netlink_data *netlink;
2a7b66f5 201 struct nl_cb *nl_cb;
481234cf 202 struct nl_handle *nl;
335d42b1 203 int nl80211_id;
c81eff1a 204 int ioctl_sock; /* socket for ioctl() use */
d6c9aab8 205
481234cf 206 struct nl_handle *nl_event;
f2ed8023
JM
207};
208
e32ad281
JB
209struct nl80211_wiphy_data {
210 struct dl_list list;
211 struct dl_list bsss;
212 struct dl_list drvs;
213
481234cf 214 struct nl_handle *nl_beacons;
e32ad281
JB
215 struct nl_cb *nl_cb;
216
217 int wiphy_idx;
218};
219
36d84860
BG
220static void nl80211_global_deinit(void *priv);
221
c5121837 222struct i802_bss {
a2e40bb6 223 struct wpa_driver_nl80211_data *drv;
c5121837 224 struct i802_bss *next;
b4fd6fab 225 int ifindex;
d3aaef80 226 u64 wdev_id;
a2e40bb6 227 char ifname[IFNAMSIZ + 1];
e17a2477 228 char brname[IFNAMSIZ];
c5121837 229 unsigned int beacon_set:1;
e17a2477
JM
230 unsigned int added_if_into_bridge:1;
231 unsigned int added_bridge:1;
873d0fcf 232 unsigned int in_deinit:1;
d3aaef80 233 unsigned int wdev_id_set:1;
390e489c 234 unsigned int added_if:1;
221a59c9 235
341eebee
JB
236 u8 addr[ETH_ALEN];
237
e4fb2167 238 int freq;
e87ef751 239 int bandwidth;
60b13c20 240 int if_dynamic;
e4fb2167 241
a5e1eb20 242 void *ctx;
481234cf 243 struct nl_handle *nl_preq, *nl_mgmt;
cc7a48d1 244 struct nl_cb *nl_cb;
e32ad281
JB
245
246 struct nl80211_wiphy_data *wiphy_data;
247 struct dl_list wiphy_list;
c5121837 248};
3f5285e8
JM
249
250struct wpa_driver_nl80211_data {
f2ed8023
JM
251 struct nl80211_global *global;
252 struct dl_list list;
e32ad281 253 struct dl_list wiphy_list;
6859f1cb 254 char phyname[32];
3f5285e8 255 void *ctx;
3f5285e8 256 int ifindex;
7524cfb1 257 int if_removed;
a63063b4 258 int if_disabled;
7d9c3698 259 int ignore_if_down_event;
8401a6b0 260 struct rfkill_data *rfkill;
c2a04078 261 struct wpa_driver_capa capa;
8cd6b7bc
JB
262 u8 *extended_capa, *extended_capa_mask;
263 unsigned int extended_capa_len;
c2a04078 264 int has_capability;
c2a04078 265
3f5285e8
JM
266 int operstate;
267
3f5285e8 268 int scan_complete_events;
a771c07d
JM
269 enum scan_states {
270 NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
271 SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
272 SCHED_SCAN_RESULTS
273 } scan_state;
3f5285e8 274
1afc986d 275 struct nl_cb *nl_cb;
1c873584 276
e6b8efeb 277 u8 auth_bssid[ETH_ALEN];
add9b7a4 278 u8 auth_attempt_bssid[ETH_ALEN];
c2a04078 279 u8 bssid[ETH_ALEN];
add9b7a4 280 u8 prev_bssid[ETH_ALEN];
c2a04078 281 int associated;
fd05d64e
JM
282 u8 ssid[32];
283 size_t ssid_len;
b1f625e0
EP
284 enum nl80211_iftype nlmode;
285 enum nl80211_iftype ap_scan_as_station;
4832ecd7 286 unsigned int assoc_freq;
d2440ba0 287
0915d02c
JM
288 int monitor_sock;
289 int monitor_ifidx;
3fd1cefb 290 int monitor_refcount;
7da3abe7 291
b3af99d2 292 unsigned int disabled_11b_rates:1;
55777702 293 unsigned int pending_remain_on_chan:1;
dac12351 294 unsigned int in_interface_list:1;
61cbe2ff 295 unsigned int device_ap_sme:1;
39718852 296 unsigned int poll_command_supported:1;
32ab4855 297 unsigned int data_tx_status:1;
536fd62d
JM
298 unsigned int scan_for_auth:1;
299 unsigned int retry_auth:1;
a11241fa 300 unsigned int use_monitor:1;
a8c5b43a 301 unsigned int ignore_next_local_disconnect:1;
d6a36f39 302 unsigned int ignore_next_local_deauth:1;
851b0c55 303 unsigned int allow_p2p_device:1;
0d547d5f 304 unsigned int hostapd:1;
49b4b205 305 unsigned int start_mode_ap:1;
146fa9b3 306 unsigned int start_iface_up:1;
64abb725 307 unsigned int test_use_roc_tx:1;
e8d70a73 308 unsigned int ignore_deauth_event:1;
65d645ce 309 unsigned int dfs_vendor_cmd_avail:1;
55777702
JM
310
311 u64 remain_on_chan_cookie;
58f6fbe0 312 u64 send_action_cookie;
c5121837 313
5582a5d1
JB
314 unsigned int last_mgmt_freq;
315
3812464c
JM
316 struct wpa_driver_scan_filter *filter_ssids;
317 size_t num_filter_ssids;
318
834ee56f 319 struct i802_bss *first_bss;
a2e40bb6 320
d12dab4c 321 int eapol_tx_sock;
f10bfc9a 322
c5121837 323 int eapol_sock; /* socket for EAPOL frames */
c5121837
JM
324
325 int default_if_indices[16];
326 int *if_indices;
327 int num_if_indices;
536fd62d
JM
328
329 /* From failed authentication command */
330 int auth_freq;
331 u8 auth_bssid_[ETH_ALEN];
332 u8 auth_ssid[32];
333 size_t auth_ssid_len;
334 int auth_alg;
335 u8 *auth_ie;
336 size_t auth_ie_len;
337 u8 auth_wep_key[4][16];
338 size_t auth_wep_key_len[4];
339 int auth_wep_tx_keyidx;
340 int auth_local_state_change;
341 int auth_p2p;
3f5285e8
JM
342};
343
344
9ebce9c5 345static void wpa_driver_nl80211_deinit(struct i802_bss *bss);
3f5285e8
JM
346static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
347 void *timeout_ctx);
b1f625e0
EP
348static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
349 enum nl80211_iftype nlmode);
362f781e 350static int
0d547d5f 351wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
49b4b205 352 const u8 *set_addr, int first);
d72aad94 353static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
77339912
JM
354 const u8 *addr, int cmd, u16 reason_code,
355 int local_state_change);
460456f8
JM
356static void nl80211_remove_monitor_interface(
357 struct wpa_driver_nl80211_data *drv);
88df0ef7 358static int nl80211_send_frame_cmd(struct i802_bss *bss,
5dfca53f 359 unsigned int freq, unsigned int wait,
b106173a 360 const u8 *buf, size_t buf_len, u64 *cookie,
88df0ef7 361 int no_cck, int no_ack, int offchanok);
b21990b4
AQ
362static int nl80211_register_frame(struct i802_bss *bss,
363 struct nl_handle *hl_handle,
364 u16 type, const u8 *match, size_t match_len);
9ebce9c5
JM
365static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
366 int report);
216eede8
DS
367#ifdef ANDROID
368static int android_pno_start(struct i802_bss *bss,
369 struct wpa_driver_scan_params *params);
370static int android_pno_stop(struct i802_bss *bss);
5e2c3490
JM
371extern int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
372 size_t buf_len);
216eede8 373#endif /* ANDROID */
0de38036
JM
374#ifdef ANDROID_P2P
375int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration);
376int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len);
377int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow);
378int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
379 const struct wpabuf *proberesp,
380 const struct wpabuf *assocresp);
381#endif /* ANDROID_P2P */
0915d02c 382
2135f224
JM
383static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
384static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
97cfcf64 385static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
9ebce9c5 386static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
fbbfcbac
FF
387 enum wpa_driver_if_type type,
388 const char *ifname);
072ad14c 389
e87ef751
PX
390static int nl80211_set_channel(struct i802_bss *bss,
391 struct hostapd_freq_params *freq, int set_chan);
4e5cb1a3
JM
392static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
393 int ifindex, int disabled);
504e905c 394
21bdbe38 395static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
536fd62d
JM
396static int wpa_driver_nl80211_authenticate_retry(
397 struct wpa_driver_nl80211_data *drv);
21bdbe38 398
bf83eab5
IP
399static int i802_set_iface_flags(struct i802_bss *bss, int up);
400
3f5285e8 401
2090a0b4
DS
402static const char * nl80211_command_to_string(enum nl80211_commands cmd)
403{
404#define C2S(x) case x: return #x;
405 switch (cmd) {
406 C2S(NL80211_CMD_UNSPEC)
407 C2S(NL80211_CMD_GET_WIPHY)
408 C2S(NL80211_CMD_SET_WIPHY)
409 C2S(NL80211_CMD_NEW_WIPHY)
410 C2S(NL80211_CMD_DEL_WIPHY)
411 C2S(NL80211_CMD_GET_INTERFACE)
412 C2S(NL80211_CMD_SET_INTERFACE)
413 C2S(NL80211_CMD_NEW_INTERFACE)
414 C2S(NL80211_CMD_DEL_INTERFACE)
415 C2S(NL80211_CMD_GET_KEY)
416 C2S(NL80211_CMD_SET_KEY)
417 C2S(NL80211_CMD_NEW_KEY)
418 C2S(NL80211_CMD_DEL_KEY)
419 C2S(NL80211_CMD_GET_BEACON)
420 C2S(NL80211_CMD_SET_BEACON)
421 C2S(NL80211_CMD_START_AP)
422 C2S(NL80211_CMD_STOP_AP)
423 C2S(NL80211_CMD_GET_STATION)
424 C2S(NL80211_CMD_SET_STATION)
425 C2S(NL80211_CMD_NEW_STATION)
426 C2S(NL80211_CMD_DEL_STATION)
427 C2S(NL80211_CMD_GET_MPATH)
428 C2S(NL80211_CMD_SET_MPATH)
429 C2S(NL80211_CMD_NEW_MPATH)
430 C2S(NL80211_CMD_DEL_MPATH)
431 C2S(NL80211_CMD_SET_BSS)
432 C2S(NL80211_CMD_SET_REG)
433 C2S(NL80211_CMD_REQ_SET_REG)
434 C2S(NL80211_CMD_GET_MESH_CONFIG)
435 C2S(NL80211_CMD_SET_MESH_CONFIG)
436 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
437 C2S(NL80211_CMD_GET_REG)
438 C2S(NL80211_CMD_GET_SCAN)
439 C2S(NL80211_CMD_TRIGGER_SCAN)
440 C2S(NL80211_CMD_NEW_SCAN_RESULTS)
441 C2S(NL80211_CMD_SCAN_ABORTED)
442 C2S(NL80211_CMD_REG_CHANGE)
443 C2S(NL80211_CMD_AUTHENTICATE)
444 C2S(NL80211_CMD_ASSOCIATE)
445 C2S(NL80211_CMD_DEAUTHENTICATE)
446 C2S(NL80211_CMD_DISASSOCIATE)
447 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
448 C2S(NL80211_CMD_REG_BEACON_HINT)
449 C2S(NL80211_CMD_JOIN_IBSS)
450 C2S(NL80211_CMD_LEAVE_IBSS)
451 C2S(NL80211_CMD_TESTMODE)
452 C2S(NL80211_CMD_CONNECT)
453 C2S(NL80211_CMD_ROAM)
454 C2S(NL80211_CMD_DISCONNECT)
455 C2S(NL80211_CMD_SET_WIPHY_NETNS)
456 C2S(NL80211_CMD_GET_SURVEY)
457 C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
458 C2S(NL80211_CMD_SET_PMKSA)
459 C2S(NL80211_CMD_DEL_PMKSA)
460 C2S(NL80211_CMD_FLUSH_PMKSA)
461 C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
462 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
463 C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
464 C2S(NL80211_CMD_REGISTER_FRAME)
465 C2S(NL80211_CMD_FRAME)
466 C2S(NL80211_CMD_FRAME_TX_STATUS)
467 C2S(NL80211_CMD_SET_POWER_SAVE)
468 C2S(NL80211_CMD_GET_POWER_SAVE)
469 C2S(NL80211_CMD_SET_CQM)
470 C2S(NL80211_CMD_NOTIFY_CQM)
471 C2S(NL80211_CMD_SET_CHANNEL)
472 C2S(NL80211_CMD_SET_WDS_PEER)
473 C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
474 C2S(NL80211_CMD_JOIN_MESH)
475 C2S(NL80211_CMD_LEAVE_MESH)
476 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
477 C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
478 C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
479 C2S(NL80211_CMD_GET_WOWLAN)
480 C2S(NL80211_CMD_SET_WOWLAN)
481 C2S(NL80211_CMD_START_SCHED_SCAN)
482 C2S(NL80211_CMD_STOP_SCHED_SCAN)
483 C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
484 C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
485 C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
486 C2S(NL80211_CMD_PMKSA_CANDIDATE)
487 C2S(NL80211_CMD_TDLS_OPER)
488 C2S(NL80211_CMD_TDLS_MGMT)
489 C2S(NL80211_CMD_UNEXPECTED_FRAME)
490 C2S(NL80211_CMD_PROBE_CLIENT)
491 C2S(NL80211_CMD_REGISTER_BEACONS)
492 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
493 C2S(NL80211_CMD_SET_NOACK_MAP)
494 C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
495 C2S(NL80211_CMD_START_P2P_DEVICE)
496 C2S(NL80211_CMD_STOP_P2P_DEVICE)
497 C2S(NL80211_CMD_CONN_FAILED)
498 C2S(NL80211_CMD_SET_MCAST_RATE)
499 C2S(NL80211_CMD_SET_MAC_ACL)
500 C2S(NL80211_CMD_RADAR_DETECT)
501 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
502 C2S(NL80211_CMD_UPDATE_FT_IES)
503 C2S(NL80211_CMD_FT_EVENT)
504 C2S(NL80211_CMD_CRIT_PROTOCOL_START)
505 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
17b79e65
JM
506 C2S(NL80211_CMD_GET_COALESCE)
507 C2S(NL80211_CMD_SET_COALESCE)
508 C2S(NL80211_CMD_CHANNEL_SWITCH)
509 C2S(NL80211_CMD_VENDOR)
510 C2S(NL80211_CMD_SET_QOS_MAP)
2090a0b4
DS
511 default:
512 return "NL80211_CMD_UNKNOWN";
513 }
514#undef C2S
515}
516
517
8d1fdde7
JD
518/* Converts nl80211_chan_width to a common format */
519static enum chan_width convert2width(int width)
520{
521 switch (width) {
522 case NL80211_CHAN_WIDTH_20_NOHT:
523 return CHAN_WIDTH_20_NOHT;
524 case NL80211_CHAN_WIDTH_20:
525 return CHAN_WIDTH_20;
526 case NL80211_CHAN_WIDTH_40:
527 return CHAN_WIDTH_40;
528 case NL80211_CHAN_WIDTH_80:
529 return CHAN_WIDTH_80;
530 case NL80211_CHAN_WIDTH_80P80:
531 return CHAN_WIDTH_80P80;
532 case NL80211_CHAN_WIDTH_160:
533 return CHAN_WIDTH_160;
534 }
535 return CHAN_WIDTH_UNKNOWN;
536}
537
538
b1f625e0
EP
539static int is_ap_interface(enum nl80211_iftype nlmode)
540{
0e80ea2c
JM
541 return nlmode == NL80211_IFTYPE_AP ||
542 nlmode == NL80211_IFTYPE_P2P_GO;
b1f625e0
EP
543}
544
545
546static int is_sta_interface(enum nl80211_iftype nlmode)
547{
0e80ea2c
JM
548 return nlmode == NL80211_IFTYPE_STATION ||
549 nlmode == NL80211_IFTYPE_P2P_CLIENT;
b1f625e0
EP
550}
551
552
6a71413e 553static int is_p2p_net_interface(enum nl80211_iftype nlmode)
b3af99d2 554{
0e80ea2c
JM
555 return nlmode == NL80211_IFTYPE_P2P_CLIENT ||
556 nlmode == NL80211_IFTYPE_P2P_GO;
b3af99d2
JM
557}
558
559
add9b7a4
JM
560static void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
561{
562 if (drv->associated)
563 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
564 drv->associated = 0;
565 os_memset(drv->bssid, 0, ETH_ALEN);
566}
567
568
f5a8d422
JM
569struct nl80211_bss_info_arg {
570 struct wpa_driver_nl80211_data *drv;
571 struct wpa_scan_results *res;
572 unsigned int assoc_freq;
20f5a4c2 573 u8 assoc_bssid[ETH_ALEN];
f5a8d422
JM
574};
575
576static int bss_info_handler(struct nl_msg *msg, void *arg);
577
578
6241fcb1
JM
579/* nl80211 code */
580static int ack_handler(struct nl_msg *msg, void *arg)
581{
582 int *err = arg;
583 *err = 0;
584 return NL_STOP;
585}
586
587static int finish_handler(struct nl_msg *msg, void *arg)
588{
8e8df255
JM
589 int *ret = arg;
590 *ret = 0;
6241fcb1
JM
591 return NL_SKIP;
592}
593
594static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
595 void *arg)
596{
597 int *ret = arg;
598 *ret = err->error;
599 return NL_SKIP;
600}
601
5b7b85f6
JM
602
603static int no_seq_check(struct nl_msg *msg, void *arg)
604{
605 return NL_OK;
606}
607
608
d6c9aab8 609static int send_and_recv(struct nl80211_global *global,
58f6fbe0
JM
610 struct nl_handle *nl_handle, struct nl_msg *msg,
611 int (*valid_handler)(struct nl_msg *, void *),
612 void *valid_data)
6241fcb1
JM
613{
614 struct nl_cb *cb;
615 int err = -ENOMEM;
616
d6c9aab8 617 cb = nl_cb_clone(global->nl_cb);
6241fcb1
JM
618 if (!cb)
619 goto out;
620
58f6fbe0 621 err = nl_send_auto_complete(nl_handle, msg);
6241fcb1
JM
622 if (err < 0)
623 goto out;
624
625 err = 1;
626
627 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
8e8df255 628 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
6241fcb1
JM
629 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
630
631 if (valid_handler)
632 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
633 valid_handler, valid_data);
634
34068ac3
JM
635 while (err > 0) {
636 int res = nl_recvmsgs(nl_handle, cb);
637 if (res) {
638 wpa_printf(MSG_INFO,
639 "nl80211: %s->nl_recvmsgs failed: %d",
640 __func__, res);
641 }
642 }
6241fcb1
JM
643 out:
644 nl_cb_put(cb);
645 nlmsg_free(msg);
646 return err;
647}
648
649
d6c9aab8
JB
650static int send_and_recv_msgs_global(struct nl80211_global *global,
651 struct nl_msg *msg,
652 int (*valid_handler)(struct nl_msg *, void *),
653 void *valid_data)
654{
481234cf 655 return send_and_recv(global, global->nl, msg, valid_handler,
d6c9aab8
JB
656 valid_data);
657}
658
659
98218963
DS
660static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
661 struct nl_msg *msg,
662 int (*valid_handler)(struct nl_msg *, void *),
663 void *valid_data)
58f6fbe0 664{
481234cf 665 return send_and_recv(drv->global, drv->global->nl, msg,
d6c9aab8 666 valid_handler, valid_data);
58f6fbe0
JM
667}
668
669
97865538
JM
670struct family_data {
671 const char *group;
672 int id;
673};
674
675
d3aaef80
DS
676static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
677{
678 if (bss->wdev_id_set)
679 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
680 else
681 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
682 return 0;
683
684nla_put_failure:
685 return -1;
686}
687
688
97865538
JM
689static int family_handler(struct nl_msg *msg, void *arg)
690{
691 struct family_data *res = arg;
692 struct nlattr *tb[CTRL_ATTR_MAX + 1];
693 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
694 struct nlattr *mcgrp;
695 int i;
696
697 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
698 genlmsg_attrlen(gnlh, 0), NULL);
699 if (!tb[CTRL_ATTR_MCAST_GROUPS])
700 return NL_SKIP;
701
702 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
703 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
704 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
705 nla_len(mcgrp), NULL);
706 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
707 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
708 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
709 res->group,
710 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
711 continue;
712 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
713 break;
714 };
715
716 return NL_SKIP;
717}
718
719
d6c9aab8 720static int nl_get_multicast_id(struct nl80211_global *global,
97865538
JM
721 const char *family, const char *group)
722{
723 struct nl_msg *msg;
724 int ret = -1;
725 struct family_data res = { group, -ENOENT };
726
727 msg = nlmsg_alloc();
728 if (!msg)
729 return -ENOMEM;
481234cf 730 genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
97865538
JM
731 0, 0, CTRL_CMD_GETFAMILY, 0);
732 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
733
d6c9aab8 734 ret = send_and_recv_msgs_global(global, msg, family_handler, &res);
97865538
JM
735 msg = NULL;
736 if (ret == 0)
737 ret = res.id;
738
739nla_put_failure:
740 nlmsg_free(msg);
741 return ret;
742}
743
744
9fb04070
JM
745static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
746 struct nl_msg *msg, int flags, uint8_t cmd)
747{
335d42b1 748 return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
276e2d67 749 0, flags, cmd, 0);
9fb04070
JM
750}
751
752
e32ad281
JB
753struct wiphy_idx_data {
754 int wiphy_idx;
01517c8b 755 enum nl80211_iftype nlmode;
597b94f5 756 u8 *macaddr;
e32ad281
JB
757};
758
759
760static int netdev_info_handler(struct nl_msg *msg, void *arg)
761{
762 struct nlattr *tb[NL80211_ATTR_MAX + 1];
763 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
764 struct wiphy_idx_data *info = arg;
765
766 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
767 genlmsg_attrlen(gnlh, 0), NULL);
768
769 if (tb[NL80211_ATTR_WIPHY])
770 info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
771
01517c8b
JB
772 if (tb[NL80211_ATTR_IFTYPE])
773 info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
774
597b94f5
AS
775 if (tb[NL80211_ATTR_MAC] && info->macaddr)
776 os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
777 ETH_ALEN);
778
e32ad281
JB
779 return NL_SKIP;
780}
781
782
783static int nl80211_get_wiphy_index(struct i802_bss *bss)
784{
785 struct nl_msg *msg;
786 struct wiphy_idx_data data = {
787 .wiphy_idx = -1,
597b94f5 788 .macaddr = NULL,
e32ad281
JB
789 };
790
791 msg = nlmsg_alloc();
792 if (!msg)
8e12685c 793 return NL80211_IFTYPE_UNSPECIFIED;
e32ad281
JB
794
795 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
796
27ce1d64
AS
797 if (nl80211_set_iface_id(msg, bss) < 0)
798 goto nla_put_failure;
e32ad281
JB
799
800 if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
801 return data.wiphy_idx;
802 msg = NULL;
803nla_put_failure:
804 nlmsg_free(msg);
805 return -1;
806}
807
808
01517c8b
JB
809static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
810{
811 struct nl_msg *msg;
812 struct wiphy_idx_data data = {
597b94f5
AS
813 .nlmode = NL80211_IFTYPE_UNSPECIFIED,
814 .macaddr = NULL,
01517c8b
JB
815 };
816
817 msg = nlmsg_alloc();
818 if (!msg)
819 return -1;
820
821 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
822
f632e483
AS
823 if (nl80211_set_iface_id(msg, bss) < 0)
824 goto nla_put_failure;
01517c8b
JB
825
826 if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
827 return data.nlmode;
828 msg = NULL;
829nla_put_failure:
830 nlmsg_free(msg);
831 return NL80211_IFTYPE_UNSPECIFIED;
832}
01517c8b
JB
833
834
597b94f5
AS
835static int nl80211_get_macaddr(struct i802_bss *bss)
836{
837 struct nl_msg *msg;
838 struct wiphy_idx_data data = {
839 .macaddr = bss->addr,
840 };
841
842 msg = nlmsg_alloc();
843 if (!msg)
844 return NL80211_IFTYPE_UNSPECIFIED;
845
846 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
847 if (nl80211_set_iface_id(msg, bss) < 0)
848 goto nla_put_failure;
849
850 return send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data);
851
852nla_put_failure:
853 nlmsg_free(msg);
854 return NL80211_IFTYPE_UNSPECIFIED;
855}
597b94f5
AS
856
857
e32ad281
JB
858static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
859 struct nl80211_wiphy_data *w)
860{
861 struct nl_msg *msg;
862 int ret = -1;
863
864 msg = nlmsg_alloc();
865 if (!msg)
866 return -1;
867
868 nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_BEACONS);
869
870 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, w->wiphy_idx);
871
481234cf 872 ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL);
e32ad281
JB
873 msg = NULL;
874 if (ret) {
875 wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
876 "failed: ret=%d (%s)",
877 ret, strerror(-ret));
878 goto nla_put_failure;
879 }
880 ret = 0;
881nla_put_failure:
882 nlmsg_free(msg);
883 return ret;
884}
885
886
887static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
888{
889 struct nl80211_wiphy_data *w = eloop_ctx;
34068ac3 890 int res;
e32ad281 891
ee9fc67a 892 wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
e32ad281 893
34068ac3
JM
894 res = nl_recvmsgs(handle, w->nl_cb);
895 if (res) {
896 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
897 __func__, res);
898 }
e32ad281
JB
899}
900
901
902static int process_beacon_event(struct nl_msg *msg, void *arg)
903{
904 struct nl80211_wiphy_data *w = arg;
905 struct wpa_driver_nl80211_data *drv;
906 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
907 struct nlattr *tb[NL80211_ATTR_MAX + 1];
908 union wpa_event_data event;
909
910 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
911 genlmsg_attrlen(gnlh, 0), NULL);
912
913 if (gnlh->cmd != NL80211_CMD_FRAME) {
914 wpa_printf(MSG_DEBUG, "nl80211: Unexpected beacon event? (%d)",
915 gnlh->cmd);
916 return NL_SKIP;
917 }
918
919 if (!tb[NL80211_ATTR_FRAME])
920 return NL_SKIP;
921
922 dl_list_for_each(drv, &w->drvs, struct wpa_driver_nl80211_data,
923 wiphy_list) {
924 os_memset(&event, 0, sizeof(event));
925 event.rx_mgmt.frame = nla_data(tb[NL80211_ATTR_FRAME]);
926 event.rx_mgmt.frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
927 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
928 }
929
930 return NL_SKIP;
931}
932
933
934static struct nl80211_wiphy_data *
935nl80211_get_wiphy_data_ap(struct i802_bss *bss)
936{
937 static DEFINE_DL_LIST(nl80211_wiphys);
938 struct nl80211_wiphy_data *w;
939 int wiphy_idx, found = 0;
940 struct i802_bss *tmp_bss;
941
942 if (bss->wiphy_data != NULL)
943 return bss->wiphy_data;
944
945 wiphy_idx = nl80211_get_wiphy_index(bss);
946
947 dl_list_for_each(w, &nl80211_wiphys, struct nl80211_wiphy_data, list) {
948 if (w->wiphy_idx == wiphy_idx)
949 goto add;
950 }
951
952 /* alloc new one */
953 w = os_zalloc(sizeof(*w));
954 if (w == NULL)
955 return NULL;
956 w->wiphy_idx = wiphy_idx;
957 dl_list_init(&w->bsss);
958 dl_list_init(&w->drvs);
959
960 w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
961 if (!w->nl_cb) {
962 os_free(w);
963 return NULL;
964 }
965 nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
966 nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event,
967 w);
968
481234cf
JM
969 w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
970 "wiphy beacons");
971 if (w->nl_beacons == NULL) {
e32ad281
JB
972 os_free(w);
973 return NULL;
974 }
975
976 if (nl80211_register_beacons(bss->drv, w)) {
977 nl_destroy_handles(&w->nl_beacons);
978 os_free(w);
979 return NULL;
980 }
981
5f65e9f7 982 nl80211_register_eloop_read(&w->nl_beacons, nl80211_recv_beacons, w);
e32ad281
JB
983
984 dl_list_add(&nl80211_wiphys, &w->list);
985
986add:
987 /* drv entry for this bss already there? */
988 dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
989 if (tmp_bss->drv == bss->drv) {
990 found = 1;
991 break;
992 }
993 }
994 /* if not add it */
995 if (!found)
996 dl_list_add(&w->drvs, &bss->drv->wiphy_list);
997
998 dl_list_add(&w->bsss, &bss->wiphy_list);
999 bss->wiphy_data = w;
1000 return w;
1001}
1002
1003
1004static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
1005{
1006 struct nl80211_wiphy_data *w = bss->wiphy_data;
1007 struct i802_bss *tmp_bss;
1008 int found = 0;
1009
1010 if (w == NULL)
1011 return;
1012 bss->wiphy_data = NULL;
1013 dl_list_del(&bss->wiphy_list);
1014
1015 /* still any for this drv present? */
1016 dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
1017 if (tmp_bss->drv == bss->drv) {
1018 found = 1;
1019 break;
1020 }
1021 }
1022 /* if not remove it */
1023 if (!found)
1024 dl_list_del(&bss->drv->wiphy_list);
1025
1026 if (!dl_list_empty(&w->bsss))
1027 return;
1028
5f65e9f7 1029 nl80211_destroy_eloop_handle(&w->nl_beacons);
e32ad281
JB
1030
1031 nl_cb_put(w->nl_cb);
e32ad281
JB
1032 dl_list_del(&w->list);
1033 os_free(w);
1034}
1035
1036
3f5285e8
JM
1037static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
1038{
a2e40bb6
FF
1039 struct i802_bss *bss = priv;
1040 struct wpa_driver_nl80211_data *drv = bss->drv;
c2a04078
JM
1041 if (!drv->associated)
1042 return -1;
1043 os_memcpy(bssid, drv->bssid, ETH_ALEN);
1044 return 0;
3f5285e8
JM
1045}
1046
1047
3f5285e8
JM
1048static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
1049{
a2e40bb6
FF
1050 struct i802_bss *bss = priv;
1051 struct wpa_driver_nl80211_data *drv = bss->drv;
fd05d64e
JM
1052 if (!drv->associated)
1053 return -1;
1054 os_memcpy(ssid, drv->ssid, drv->ssid_len);
1055 return drv->ssid_len;
3f5285e8
JM
1056}
1057
1058
90a545cc
JM
1059static void wpa_driver_nl80211_event_newlink(
1060 struct wpa_driver_nl80211_data *drv, char *ifname)
3f5285e8
JM
1061{
1062 union wpa_event_data event;
1063
90a545cc
JM
1064 if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
1065 if (if_nametoindex(drv->first_bss->ifname) == 0) {
1066 wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
1067 drv->first_bss->ifname);
1068 return;
1069 }
1070 if (!drv->if_removed)
1071 return;
1072 wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
1073 drv->first_bss->ifname);
1074 drv->if_removed = 0;
1075 }
1076
3f5285e8 1077 os_memset(&event, 0, sizeof(event));
90a545cc
JM
1078 os_strlcpy(event.interface_status.ifname, ifname,
1079 sizeof(event.interface_status.ifname));
1080 event.interface_status.ievent = EVENT_INTERFACE_ADDED;
1081 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
1082}
1083
1084
1085static void wpa_driver_nl80211_event_dellink(
1086 struct wpa_driver_nl80211_data *drv, char *ifname)
1087{
1088 union wpa_event_data event;
1089
1090 if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
1091 if (drv->if_removed) {
1092 wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
1093 ifname);
1094 return;
d1f4942b 1095 }
90a545cc
JM
1096 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
1097 ifname);
1098 drv->if_removed = 1;
1099 } else {
1100 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
1101 ifname);
7524cfb1
JM
1102 }
1103
90a545cc
JM
1104 os_memset(&event, 0, sizeof(event));
1105 os_strlcpy(event.interface_status.ifname, ifname,
1106 sizeof(event.interface_status.ifname));
1107 event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
08063178 1108 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
3f5285e8
JM
1109}
1110
1111
7524cfb1 1112static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
62d680c3 1113 u8 *buf, size_t len)
7524cfb1 1114{
62d680c3 1115 int attrlen, rta_len;
7524cfb1
JM
1116 struct rtattr *attr;
1117
62d680c3
JM
1118 attrlen = len;
1119 attr = (struct rtattr *) buf;
7524cfb1
JM
1120
1121 rta_len = RTA_ALIGN(sizeof(struct rtattr));
1122 while (RTA_OK(attr, attrlen)) {
1123 if (attr->rta_type == IFLA_IFNAME) {
834ee56f
KP
1124 if (os_strcmp(((char *) attr) + rta_len,
1125 drv->first_bss->ifname) == 0)
7524cfb1
JM
1126 return 1;
1127 else
1128 break;
1129 }
1130 attr = RTA_NEXT(attr, attrlen);
1131 }
1132
1133 return 0;
1134}
1135
1136
1137static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
62d680c3 1138 int ifindex, u8 *buf, size_t len)
7524cfb1
JM
1139{
1140 if (drv->ifindex == ifindex)
1141 return 1;
1142
62d680c3 1143 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
7524cfb1
JM
1144 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
1145 "interface");
49b4b205 1146 wpa_driver_nl80211_finish_drv_init(drv, NULL, 0);
7524cfb1
JM
1147 return 1;
1148 }
1149
1150 return 0;
1151}
1152
1153
36d84860
BG
1154static struct wpa_driver_nl80211_data *
1155nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
1156{
1157 struct wpa_driver_nl80211_data *drv;
1158 dl_list_for_each(drv, &global->interfaces,
1159 struct wpa_driver_nl80211_data, list) {
1160 if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
1161 have_ifidx(drv, idx))
1162 return drv;
1163 }
1164 return NULL;
1165}
1166
1167
62d680c3
JM
1168static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
1169 struct ifinfomsg *ifi,
1170 u8 *buf, size_t len)
3f5285e8 1171{
36d84860
BG
1172 struct nl80211_global *global = ctx;
1173 struct wpa_driver_nl80211_data *drv;
90a545cc 1174 int attrlen;
62d680c3 1175 struct rtattr *attr;
97cfcf64 1176 u32 brid = 0;
aef85ba2 1177 char namebuf[IFNAMSIZ];
90a545cc
JM
1178 char ifname[IFNAMSIZ + 1];
1179 char extra[100], *pos, *end;
3f5285e8 1180
36d84860
BG
1181 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
1182 if (!drv) {
90a545cc
JM
1183 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_NEWLINK event for foreign ifindex %d",
1184 ifi->ifi_index);
3f5285e8
JM
1185 return;
1186 }
1187
90a545cc
JM
1188 extra[0] = '\0';
1189 pos = extra;
1190 end = pos + sizeof(extra);
1191 ifname[0] = '\0';
1192
1193 attrlen = len;
1194 attr = (struct rtattr *) buf;
1195 while (RTA_OK(attr, attrlen)) {
1196 switch (attr->rta_type) {
1197 case IFLA_IFNAME:
1198 if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1199 break;
1200 os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1201 ifname[RTA_PAYLOAD(attr)] = '\0';
1202 break;
1203 case IFLA_MASTER:
1204 brid = nla_get_u32((struct nlattr *) attr);
1205 pos += os_snprintf(pos, end - pos, " master=%u", brid);
1206 break;
1207 case IFLA_WIRELESS:
1208 pos += os_snprintf(pos, end - pos, " wext");
1209 break;
1210 case IFLA_OPERSTATE:
1211 pos += os_snprintf(pos, end - pos, " operstate=%u",
1212 nla_get_u32((struct nlattr *) attr));
1213 break;
1214 case IFLA_LINKMODE:
1215 pos += os_snprintf(pos, end - pos, " linkmode=%u",
1216 nla_get_u32((struct nlattr *) attr));
1217 break;
1218 }
1219 attr = RTA_NEXT(attr, attrlen);
1220 }
1221 extra[sizeof(extra) - 1] = '\0';
1222
1223 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_flags=0x%x (%s%s%s%s)",
1224 ifi->ifi_index, ifname, extra, ifi->ifi_flags,
3f5285e8
JM
1225 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
1226 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
1227 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
1228 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
a63063b4
JM
1229
1230 if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
59d24925
JM
1231 if (if_indextoname(ifi->ifi_index, namebuf) &&
1232 linux_iface_up(drv->global->ioctl_sock,
834ee56f 1233 drv->first_bss->ifname) > 0) {
59d24925
JM
1234 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1235 "event since interface %s is up", namebuf);
1236 return;
1237 }
a63063b4 1238 wpa_printf(MSG_DEBUG, "nl80211: Interface down");
7d9c3698
JM
1239 if (drv->ignore_if_down_event) {
1240 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1241 "event generated by mode change");
1242 drv->ignore_if_down_event = 0;
1243 } else {
1244 drv->if_disabled = 1;
1245 wpa_supplicant_event(drv->ctx,
1246 EVENT_INTERFACE_DISABLED, NULL);
819f096f
AO
1247
1248 /*
1249 * Try to get drv again, since it may be removed as
1250 * part of the EVENT_INTERFACE_DISABLED handling for
1251 * dynamic interfaces
1252 */
1253 drv = nl80211_find_drv(global, ifi->ifi_index,
1254 buf, len);
1255 if (!drv)
1256 return;
7d9c3698 1257 }
a63063b4
JM
1258 }
1259
1260 if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
aef85ba2
JM
1261 if (if_indextoname(ifi->ifi_index, namebuf) &&
1262 linux_iface_up(drv->global->ioctl_sock,
834ee56f 1263 drv->first_bss->ifname) == 0) {
aef85ba2
JM
1264 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1265 "event since interface %s is down",
1266 namebuf);
834ee56f 1267 } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
d1f4942b
JM
1268 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1269 "event since interface %s does not exist",
834ee56f 1270 drv->first_bss->ifname);
d1f4942b
JM
1271 } else if (drv->if_removed) {
1272 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1273 "event since interface %s is marked "
834ee56f 1274 "removed", drv->first_bss->ifname);
aef85ba2
JM
1275 } else {
1276 wpa_printf(MSG_DEBUG, "nl80211: Interface up");
1277 drv->if_disabled = 0;
1278 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
1279 NULL);
1280 }
a63063b4
JM
1281 }
1282
3f5285e8
JM
1283 /*
1284 * Some drivers send the association event before the operup event--in
1285 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
1286 * fails. This will hit us when wpa_supplicant does not need to do
1287 * IEEE 802.1X authentication
1288 */
1289 if (drv->operstate == 1 &&
1290 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
90a545cc
JM
1291 !(ifi->ifi_flags & IFF_RUNNING)) {
1292 wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
36d84860 1293 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
e2d02c29 1294 -1, IF_OPER_UP);
3f5285e8 1295 }
97cfcf64 1296
90a545cc
JM
1297 if (ifname[0])
1298 wpa_driver_nl80211_event_newlink(drv, ifname);
1299
97cfcf64
B
1300 if (ifi->ifi_family == AF_BRIDGE && brid) {
1301 /* device has been added to bridge */
97cfcf64
B
1302 if_indextoname(brid, namebuf);
1303 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
1304 brid, namebuf);
1305 add_ifidx(drv, brid);
1306 }
3f5285e8
JM
1307}
1308
1309
62d680c3
JM
1310static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
1311 struct ifinfomsg *ifi,
1312 u8 *buf, size_t len)
3f5285e8 1313{
36d84860
BG
1314 struct nl80211_global *global = ctx;
1315 struct wpa_driver_nl80211_data *drv;
90a545cc 1316 int attrlen;
62d680c3 1317 struct rtattr *attr;
97cfcf64 1318 u32 brid = 0;
90a545cc 1319 char ifname[IFNAMSIZ + 1];
3f5285e8 1320
36d84860
BG
1321 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
1322 if (!drv) {
90a545cc
JM
1323 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_DELLINK event for foreign ifindex %d",
1324 ifi->ifi_index);
36d84860
BG
1325 return;
1326 }
1327
90a545cc
JM
1328 ifname[0] = '\0';
1329
62d680c3
JM
1330 attrlen = len;
1331 attr = (struct rtattr *) buf;
3f5285e8 1332 while (RTA_OK(attr, attrlen)) {
90a545cc
JM
1333 switch (attr->rta_type) {
1334 case IFLA_IFNAME:
1335 if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1336 break;
1337 os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1338 ifname[RTA_PAYLOAD(attr)] = '\0';
1339 break;
1340 case IFLA_MASTER:
97cfcf64 1341 brid = nla_get_u32((struct nlattr *) attr);
90a545cc
JM
1342 break;
1343 }
3f5285e8
JM
1344 attr = RTA_NEXT(attr, attrlen);
1345 }
97cfcf64 1346
90a545cc
JM
1347 if (ifname[0])
1348 wpa_driver_nl80211_event_dellink(drv, ifname);
1349
97cfcf64
B
1350 if (ifi->ifi_family == AF_BRIDGE && brid) {
1351 /* device has been removed from bridge */
1352 char namebuf[IFNAMSIZ];
1353 if_indextoname(brid, namebuf);
1354 wpa_printf(MSG_DEBUG, "nl80211: Remove ifindex %u for bridge "
1355 "%s", brid, namebuf);
1356 del_ifidx(drv, brid);
1357 }
3f5285e8
JM
1358}
1359
1360
c2a04078
JM
1361static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
1362 const u8 *frame, size_t len)
1363{
1364 const struct ieee80211_mgmt *mgmt;
1365 union wpa_event_data event;
1366
7d81932d 1367 wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
c2a04078
JM
1368 mgmt = (const struct ieee80211_mgmt *) frame;
1369 if (len < 24 + sizeof(mgmt->u.auth)) {
1370 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
1371 "frame");
1372 return;
1373 }
1374
e6b8efeb 1375 os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
add9b7a4 1376 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
c2a04078
JM
1377 os_memset(&event, 0, sizeof(event));
1378 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
1379 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
569fed90
JM
1380 event.auth.auth_transaction =
1381 le_to_host16(mgmt->u.auth.auth_transaction);
c2a04078
JM
1382 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
1383 if (len > 24 + sizeof(mgmt->u.auth)) {
1384 event.auth.ies = mgmt->u.auth.variable;
1385 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
1386 }
1387
1388 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
1389}
1390
1391
f5a8d422
JM
1392static unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
1393{
1394 struct nl_msg *msg;
1395 int ret;
1396 struct nl80211_bss_info_arg arg;
1397
1398 os_memset(&arg, 0, sizeof(arg));
1399 msg = nlmsg_alloc();
1400 if (!msg)
1401 goto nla_put_failure;
1402
9fb04070 1403 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
f5a8d422
JM
1404 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1405
1406 arg.drv = drv;
1407 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
1408 msg = NULL;
1409 if (ret == 0) {
1410 wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
1411 "associated BSS from scan results: %u MHz",
1412 arg.assoc_freq);
30158a0d
SD
1413 if (arg.assoc_freq)
1414 drv->assoc_freq = arg.assoc_freq;
1415 return drv->assoc_freq;
f5a8d422
JM
1416 }
1417 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1418 "(%s)", ret, strerror(-ret));
1419nla_put_failure:
1420 nlmsg_free(msg);
1421 return drv->assoc_freq;
1422}
1423
1424
c2a04078
JM
1425static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
1426 const u8 *frame, size_t len)
1427{
1428 const struct ieee80211_mgmt *mgmt;
1429 union wpa_event_data event;
1430 u16 status;
1431
7d81932d 1432 wpa_printf(MSG_DEBUG, "nl80211: Associate event");
c2a04078
JM
1433 mgmt = (const struct ieee80211_mgmt *) frame;
1434 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
1435 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
1436 "frame");
1437 return;
1438 }
1439
1440 status = le_to_host16(mgmt->u.assoc_resp.status_code);
1441 if (status != WLAN_STATUS_SUCCESS) {
efa46078 1442 os_memset(&event, 0, sizeof(event));
59ddf221 1443 event.assoc_reject.bssid = mgmt->bssid;
efa46078
JM
1444 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
1445 event.assoc_reject.resp_ies =
1446 (u8 *) mgmt->u.assoc_resp.variable;
1447 event.assoc_reject.resp_ies_len =
1448 len - 24 - sizeof(mgmt->u.assoc_resp);
1449 }
1450 event.assoc_reject.status_code = status;
1451
1452 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
c2a04078
JM
1453 return;
1454 }
1455
1456 drv->associated = 1;
1457 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
add9b7a4 1458 os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
c2a04078
JM
1459
1460 os_memset(&event, 0, sizeof(event));
1461 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
1462 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
1463 event.assoc_info.resp_ies_len =
efa46078 1464 len - 24 - sizeof(mgmt->u.assoc_resp);
c2a04078
JM
1465 }
1466
4832ecd7
JM
1467 event.assoc_info.freq = drv->assoc_freq;
1468
c2a04078
JM
1469 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
1470}
1471
c1bb3e0a 1472
da72a1c1
ZY
1473static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
1474 enum nl80211_commands cmd, struct nlattr *status,
1475 struct nlattr *addr, struct nlattr *req_ie,
1476 struct nlattr *resp_ie)
1477{
1478 union wpa_event_data event;
1479
7da2c527
JM
1480 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1481 /*
1482 * Avoid reporting two association events that would confuse
1483 * the core code.
1484 */
1485 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
1486 "when using userspace SME", cmd);
1487 return;
1488 }
1489
7d81932d
JM
1490 if (cmd == NL80211_CMD_CONNECT)
1491 wpa_printf(MSG_DEBUG, "nl80211: Connect event");
1492 else if (cmd == NL80211_CMD_ROAM)
1493 wpa_printf(MSG_DEBUG, "nl80211: Roam event");
1494
da72a1c1
ZY
1495 os_memset(&event, 0, sizeof(event));
1496 if (cmd == NL80211_CMD_CONNECT &&
1497 nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
df89c1c8
JM
1498 if (addr)
1499 event.assoc_reject.bssid = nla_data(addr);
da72a1c1
ZY
1500 if (resp_ie) {
1501 event.assoc_reject.resp_ies = nla_data(resp_ie);
1502 event.assoc_reject.resp_ies_len = nla_len(resp_ie);
1503 }
1504 event.assoc_reject.status_code = nla_get_u16(status);
1505 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
1506 return;
1507 }
1508
1509 drv->associated = 1;
add9b7a4 1510 if (addr) {
da72a1c1 1511 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
add9b7a4
JM
1512 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
1513 }
da72a1c1
ZY
1514
1515 if (req_ie) {
1516 event.assoc_info.req_ies = nla_data(req_ie);
1517 event.assoc_info.req_ies_len = nla_len(req_ie);
1518 }
1519 if (resp_ie) {
1520 event.assoc_info.resp_ies = nla_data(resp_ie);
1521 event.assoc_info.resp_ies_len = nla_len(resp_ie);
1522 }
1523
f5a8d422
JM
1524 event.assoc_info.freq = nl80211_get_assoc_freq(drv);
1525
da72a1c1
ZY
1526 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
1527}
c2a04078 1528
c1bb3e0a 1529
20f5a4c2 1530static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
3d9975d5
JM
1531 struct nlattr *reason, struct nlattr *addr,
1532 struct nlattr *by_ap)
20f5a4c2
JM
1533{
1534 union wpa_event_data data;
a8c5b43a 1535 unsigned int locally_generated = by_ap == NULL;
20f5a4c2
JM
1536
1537 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1538 /*
1539 * Avoid reporting two disassociation events that could
1540 * confuse the core code.
1541 */
1542 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1543 "event when using userspace SME");
1544 return;
1545 }
1546
a8c5b43a
CW
1547 if (drv->ignore_next_local_disconnect) {
1548 drv->ignore_next_local_disconnect = 0;
1549 if (locally_generated) {
1550 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1551 "event triggered during reassociation");
1552 return;
1553 }
1554 wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
1555 "disconnect but got another disconnect "
1556 "event first");
1557 }
1558
7d81932d 1559 wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
add9b7a4 1560 nl80211_mark_disconnected(drv);
20f5a4c2
JM
1561 os_memset(&data, 0, sizeof(data));
1562 if (reason)
2e9f078c
JM
1563 data.deauth_info.reason_code = nla_get_u16(reason);
1564 data.deauth_info.locally_generated = by_ap == NULL;
1565 wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
20f5a4c2
JM
1566}
1567
1568
4b0f2282
MK
1569static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
1570{
1571 int freq1 = 0;
1572
1573 switch (convert2width(width)) {
1574 case CHAN_WIDTH_20_NOHT:
1575 case CHAN_WIDTH_20:
1576 return 0;
1577 case CHAN_WIDTH_40:
1578 freq1 = cf1 - 10;
1579 break;
1580 case CHAN_WIDTH_80:
1581 freq1 = cf1 - 30;
1582 break;
1583 case CHAN_WIDTH_160:
1584 freq1 = cf1 - 70;
1585 break;
1586 case CHAN_WIDTH_UNKNOWN:
1587 case CHAN_WIDTH_80P80:
1588 /* FIXME: implement this */
1589 return 0;
1590 }
1591
1592 return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
1593}
1594
1595
1b487b8b 1596static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
8d1fdde7
JD
1597 struct nlattr *ifindex, struct nlattr *freq,
1598 struct nlattr *type, struct nlattr *bw,
1599 struct nlattr *cf1, struct nlattr *cf2)
1b487b8b 1600{
8d1fdde7 1601 struct i802_bss *bss;
1b487b8b
TP
1602 union wpa_event_data data;
1603 int ht_enabled = 1;
1604 int chan_offset = 0;
8d1fdde7 1605 int ifidx;
1b487b8b
TP
1606
1607 wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
1608
8d1fdde7 1609 if (!freq)
1b487b8b
TP
1610 return;
1611
8d1fdde7
JD
1612 ifidx = nla_get_u32(ifindex);
1613 for (bss = drv->first_bss; bss; bss = bss->next)
1614 if (bss->ifindex == ifidx)
1615 break;
1616
1617 if (bss == NULL) {
1618 wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
1619 ifidx);
1620 return;
1b487b8b
TP
1621 }
1622
8d1fdde7
JD
1623 if (type) {
1624 switch (nla_get_u32(type)) {
1625 case NL80211_CHAN_NO_HT:
1626 ht_enabled = 0;
1627 break;
1628 case NL80211_CHAN_HT20:
1629 break;
1630 case NL80211_CHAN_HT40PLUS:
1631 chan_offset = 1;
1632 break;
1633 case NL80211_CHAN_HT40MINUS:
1634 chan_offset = -1;
1635 break;
1636 }
4b0f2282
MK
1637 } else if (bw && cf1) {
1638 /* This can happen for example with VHT80 ch switch */
1639 chan_offset = calculate_chan_offset(nla_get_u32(bw),
1640 nla_get_u32(freq),
1641 nla_get_u32(cf1),
1642 cf2 ? nla_get_u32(cf2) : 0);
1643 } else {
1644 wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
8d1fdde7
JD
1645 }
1646
1647 os_memset(&data, 0, sizeof(data));
1b487b8b
TP
1648 data.ch_switch.freq = nla_get_u32(freq);
1649 data.ch_switch.ht_enabled = ht_enabled;
1650 data.ch_switch.ch_offset = chan_offset;
8d1fdde7
JD
1651 if (bw)
1652 data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
1653 if (cf1)
1654 data.ch_switch.cf1 = nla_get_u32(cf1);
1655 if (cf2)
1656 data.ch_switch.cf2 = nla_get_u32(cf2);
1b487b8b 1657
8d1fdde7 1658 bss->freq = data.ch_switch.freq;
1c4ffa87 1659
1b487b8b
TP
1660 wpa_supplicant_event(drv->ctx, EVENT_CH_SWITCH, &data);
1661}
1662
1663
da1fb17c
JM
1664static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
1665 enum nl80211_commands cmd, struct nlattr *addr)
1666{
1667 union wpa_event_data event;
1668 enum wpa_event_type ev;
1669
1670 if (nla_len(addr) != ETH_ALEN)
1671 return;
1672
1673 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
1674 cmd, MAC2STR((u8 *) nla_data(addr)));
1675
1676 if (cmd == NL80211_CMD_AUTHENTICATE)
1677 ev = EVENT_AUTH_TIMED_OUT;
1678 else if (cmd == NL80211_CMD_ASSOCIATE)
1679 ev = EVENT_ASSOC_TIMED_OUT;
1680 else
1681 return;
1682
1683 os_memset(&event, 0, sizeof(event));
1684 os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
1685 wpa_supplicant_event(drv->ctx, ev, &event);
1686}
1687
1688
1d91f504 1689static void mlme_event_mgmt(struct i802_bss *bss,
da873dbb
JB
1690 struct nlattr *freq, struct nlattr *sig,
1691 const u8 *frame, size_t len)
58f6fbe0 1692{
1d91f504 1693 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0
JM
1694 const struct ieee80211_mgmt *mgmt;
1695 union wpa_event_data event;
1696 u16 fc, stype;
da873dbb 1697 int ssi_signal = 0;
f18b7817 1698 int rx_freq = 0;
58f6fbe0 1699
cc2ada86 1700 wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
58f6fbe0
JM
1701 mgmt = (const struct ieee80211_mgmt *) frame;
1702 if (len < 24) {
dbfb8e82 1703 wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
58f6fbe0
JM
1704 return;
1705 }
1706
1707 fc = le_to_host16(mgmt->frame_control);
1708 stype = WLAN_FC_GET_STYPE(fc);
1709
da873dbb
JB
1710 if (sig)
1711 ssi_signal = (s32) nla_get_u32(sig);
1712
58f6fbe0 1713 os_memset(&event, 0, sizeof(event));
5582a5d1 1714 if (freq) {
dbfb8e82
JM
1715 event.rx_mgmt.freq = nla_get_u32(freq);
1716 rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
5582a5d1 1717 }
f18b7817
JM
1718 wpa_printf(MSG_DEBUG,
1719 "nl80211: RX frame freq=%d ssi_signal=%d stype=%u len=%u",
1720 rx_freq, ssi_signal, stype, (unsigned int) len);
dbfb8e82
JM
1721 event.rx_mgmt.frame = frame;
1722 event.rx_mgmt.frame_len = len;
1723 event.rx_mgmt.ssi_signal = ssi_signal;
1d91f504 1724 event.rx_mgmt.drv_priv = bss;
dbfb8e82 1725 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
58f6fbe0
JM
1726}
1727
1728
a11241fa
JB
1729static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
1730 struct nlattr *cookie, const u8 *frame,
1731 size_t len, struct nlattr *ack)
58f6fbe0
JM
1732{
1733 union wpa_event_data event;
1734 const struct ieee80211_hdr *hdr;
1735 u16 fc;
58f6fbe0 1736
7d81932d 1737 wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
a11241fa
JB
1738 if (!is_ap_interface(drv->nlmode)) {
1739 u64 cookie_val;
58f6fbe0 1740
a11241fa
JB
1741 if (!cookie)
1742 return;
1743
1744 cookie_val = nla_get_u64(cookie);
1745 wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
1746 " cookie=0%llx%s (ack=%d)",
1747 (long long unsigned int) cookie_val,
1748 cookie_val == drv->send_action_cookie ?
1749 " (match)" : " (unknown)", ack != NULL);
1750 if (cookie_val != drv->send_action_cookie)
1751 return;
1752 }
58f6fbe0
JM
1753
1754 hdr = (const struct ieee80211_hdr *) frame;
1755 fc = le_to_host16(hdr->frame_control);
1756
1757 os_memset(&event, 0, sizeof(event));
1758 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
1759 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
1760 event.tx_status.dst = hdr->addr1;
1761 event.tx_status.data = frame;
1762 event.tx_status.data_len = len;
1763 event.tx_status.ack = ack != NULL;
1764 wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
1765}
1766
1767
0544b242
JM
1768static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
1769 enum wpa_event_type type,
1770 const u8 *frame, size_t len)
1771{
1772 const struct ieee80211_mgmt *mgmt;
1773 union wpa_event_data event;
1774 const u8 *bssid = NULL;
1775 u16 reason_code = 0;
1776
7d81932d
JM
1777 if (type == EVENT_DEAUTH)
1778 wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
1779 else
1780 wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
1781
cb30b297
PS
1782 mgmt = (const struct ieee80211_mgmt *) frame;
1783 if (len >= 24) {
1784 bssid = mgmt->bssid;
1785
add9b7a4
JM
1786 if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
1787 !drv->associated &&
1788 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
1789 os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
1790 os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
1791 /*
1792 * Avoid issues with some roaming cases where
1793 * disconnection event for the old AP may show up after
1794 * we have started connection with the new AP.
1795 */
1796 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
1797 MAC2STR(bssid),
1798 MAC2STR(drv->auth_attempt_bssid));
1799 return;
1800 }
1801
cb30b297
PS
1802 if (drv->associated != 0 &&
1803 os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
1804 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
1805 /*
1806 * We have presumably received this deauth as a
1807 * response to a clear_state_mismatch() outgoing
1808 * deauth. Don't let it take us offline!
1809 */
1810 wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
1811 "from Unknown BSSID " MACSTR " -- ignoring",
1812 MAC2STR(bssid));
1813 return;
1814 }
1815 }
1816
add9b7a4 1817 nl80211_mark_disconnected(drv);
0544b242
JM
1818 os_memset(&event, 0, sizeof(event));
1819
0544b242
JM
1820 /* Note: Same offset for Reason Code in both frame subtypes */
1821 if (len >= 24 + sizeof(mgmt->u.deauth))
1822 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1823
1824 if (type == EVENT_DISASSOC) {
3d9975d5 1825 event.disassoc_info.locally_generated =
834ee56f 1826 !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
0544b242
JM
1827 event.disassoc_info.addr = bssid;
1828 event.disassoc_info.reason_code = reason_code;
046b26a2
JM
1829 if (frame + len > mgmt->u.disassoc.variable) {
1830 event.disassoc_info.ie = mgmt->u.disassoc.variable;
1831 event.disassoc_info.ie_len = frame + len -
1832 mgmt->u.disassoc.variable;
1833 }
0544b242 1834 } else {
e8d70a73
JM
1835 if (drv->ignore_deauth_event) {
1836 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
1837 drv->ignore_deauth_event = 0;
1838 return;
1839 }
3d9975d5 1840 event.deauth_info.locally_generated =
834ee56f 1841 !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
d6a36f39
JM
1842 if (drv->ignore_next_local_deauth) {
1843 drv->ignore_next_local_deauth = 0;
1844 if (event.deauth_info.locally_generated) {
1845 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
1846 return;
1847 }
1848 wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
1849 }
0544b242
JM
1850 event.deauth_info.addr = bssid;
1851 event.deauth_info.reason_code = reason_code;
046b26a2
JM
1852 if (frame + len > mgmt->u.deauth.variable) {
1853 event.deauth_info.ie = mgmt->u.deauth.variable;
1854 event.deauth_info.ie_len = frame + len -
1855 mgmt->u.deauth.variable;
1856 }
0544b242
JM
1857 }
1858
1859 wpa_supplicant_event(drv->ctx, type, &event);
1860}
1861
1862
7d878ca7
JM
1863static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
1864 enum wpa_event_type type,
1865 const u8 *frame, size_t len)
1866{
1867 const struct ieee80211_mgmt *mgmt;
1868 union wpa_event_data event;
1869 u16 reason_code = 0;
1870
7d81932d
JM
1871 if (type == EVENT_UNPROT_DEAUTH)
1872 wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
1873 else
1874 wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
1875
7d878ca7
JM
1876 if (len < 24)
1877 return;
1878
1879 mgmt = (const struct ieee80211_mgmt *) frame;
1880
1881 os_memset(&event, 0, sizeof(event));
1882 /* Note: Same offset for Reason Code in both frame subtypes */
1883 if (len >= 24 + sizeof(mgmt->u.deauth))
1884 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1885
1886 if (type == EVENT_UNPROT_DISASSOC) {
1887 event.unprot_disassoc.sa = mgmt->sa;
1888 event.unprot_disassoc.da = mgmt->da;
1889 event.unprot_disassoc.reason_code = reason_code;
1890 } else {
1891 event.unprot_deauth.sa = mgmt->sa;
1892 event.unprot_deauth.da = mgmt->da;
1893 event.unprot_deauth.reason_code = reason_code;
1894 }
1895
1896 wpa_supplicant_event(drv->ctx, type, &event);
1897}
1898
1899
97279d8d 1900static void mlme_event(struct i802_bss *bss,
da1fb17c 1901 enum nl80211_commands cmd, struct nlattr *frame,
58f6fbe0
JM
1902 struct nlattr *addr, struct nlattr *timed_out,
1903 struct nlattr *freq, struct nlattr *ack,
da873dbb 1904 struct nlattr *cookie, struct nlattr *sig)
c2a04078 1905{
97279d8d
JM
1906 struct wpa_driver_nl80211_data *drv = bss->drv;
1907 const u8 *data;
1908 size_t len;
1909
da1fb17c
JM
1910 if (timed_out && addr) {
1911 mlme_timeout_event(drv, cmd, addr);
1912 return;
1913 }
1914
c2a04078 1915 if (frame == NULL) {
2090a0b4
DS
1916 wpa_printf(MSG_DEBUG,
1917 "nl80211: MLME event %d (%s) without frame data",
1918 cmd, nl80211_command_to_string(cmd));
c2a04078
JM
1919 return;
1920 }
1921
97279d8d
JM
1922 data = nla_data(frame);
1923 len = nla_len(frame);
455299fb 1924 if (len < 4 + 2 * ETH_ALEN) {
2090a0b4
DS
1925 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
1926 MACSTR ") - too short",
1927 cmd, nl80211_command_to_string(cmd), bss->ifname,
1928 MAC2STR(bss->addr));
97279d8d
JM
1929 return;
1930 }
2090a0b4
DS
1931 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
1932 ") A1=" MACSTR " A2=" MACSTR, cmd,
1933 nl80211_command_to_string(cmd), bss->ifname,
1934 MAC2STR(bss->addr), MAC2STR(data + 4),
1935 MAC2STR(data + 4 + ETH_ALEN));
97279d8d 1936 if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
455299fb
JM
1937 os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
1938 os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
97279d8d
JM
1939 wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
1940 "for foreign address", bss->ifname);
1941 return;
1942 }
c2a04078
JM
1943 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
1944 nla_data(frame), nla_len(frame));
1945
1946 switch (cmd) {
1947 case NL80211_CMD_AUTHENTICATE:
1948 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
1949 break;
1950 case NL80211_CMD_ASSOCIATE:
1951 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
1952 break;
1953 case NL80211_CMD_DEAUTHENTICATE:
0544b242
JM
1954 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
1955 nla_data(frame), nla_len(frame));
c2a04078
JM
1956 break;
1957 case NL80211_CMD_DISASSOCIATE:
0544b242
JM
1958 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
1959 nla_data(frame), nla_len(frame));
c2a04078 1960 break;
bd94971e 1961 case NL80211_CMD_FRAME:
1d91f504 1962 mlme_event_mgmt(bss, freq, sig, nla_data(frame),
da873dbb 1963 nla_len(frame));
58f6fbe0 1964 break;
bd94971e 1965 case NL80211_CMD_FRAME_TX_STATUS:
a11241fa
JB
1966 mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
1967 nla_len(frame), ack);
58f6fbe0 1968 break;
7d878ca7
JM
1969 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
1970 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
1971 nla_data(frame), nla_len(frame));
1972 break;
1973 case NL80211_CMD_UNPROT_DISASSOCIATE:
1974 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
1975 nla_data(frame), nla_len(frame));
1976 break;
c2a04078
JM
1977 default:
1978 break;
1979 }
1980}
1981
1982
a5e1eb20 1983static void mlme_event_michael_mic_failure(struct i802_bss *bss,
35583f3f
JM
1984 struct nlattr *tb[])
1985{
1986 union wpa_event_data data;
1987
1988 wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
1989 os_memset(&data, 0, sizeof(data));
1990 if (tb[NL80211_ATTR_MAC]) {
1991 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
1992 nla_data(tb[NL80211_ATTR_MAC]),
1993 nla_len(tb[NL80211_ATTR_MAC]));
ad1e68e6 1994 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
35583f3f
JM
1995 }
1996 if (tb[NL80211_ATTR_KEY_SEQ]) {
1997 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
1998 nla_data(tb[NL80211_ATTR_KEY_SEQ]),
1999 nla_len(tb[NL80211_ATTR_KEY_SEQ]));
2000 }
2001 if (tb[NL80211_ATTR_KEY_TYPE]) {
2002 enum nl80211_key_type key_type =
2003 nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
2004 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
2005 if (key_type == NL80211_KEYTYPE_PAIRWISE)
2006 data.michael_mic_failure.unicast = 1;
2007 } else
2008 data.michael_mic_failure.unicast = 1;
2009
2010 if (tb[NL80211_ATTR_KEY_IDX]) {
2011 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
2012 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
2013 }
2014
a5e1eb20 2015 wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
35583f3f
JM
2016}
2017
2018
5cc4d64b
JM
2019static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
2020 struct nlattr *tb[])
2021{
2022 if (tb[NL80211_ATTR_MAC] == NULL) {
2023 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
2024 "event");
2025 return;
2026 }
2027 os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
b21990b4 2028
5cc4d64b
JM
2029 drv->associated = 1;
2030 wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
2031 MAC2STR(drv->bssid));
2032
2033 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
2034}
2035
2036
55777702
JM
2037static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
2038 int cancel_event, struct nlattr *tb[])
2039{
2040 unsigned int freq, chan_type, duration;
2041 union wpa_event_data data;
2042 u64 cookie;
2043
2044 if (tb[NL80211_ATTR_WIPHY_FREQ])
2045 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2046 else
2047 freq = 0;
2048
2049 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
2050 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
2051 else
2052 chan_type = 0;
2053
2054 if (tb[NL80211_ATTR_DURATION])
2055 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
2056 else
2057 duration = 0;
2058
2059 if (tb[NL80211_ATTR_COOKIE])
2060 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
2061 else
2062 cookie = 0;
2063
2064 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
2065 "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
2066 cancel_event, freq, chan_type, duration,
2067 (long long unsigned int) cookie,
2068 cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
2069
2070 if (cookie != drv->remain_on_chan_cookie)
2071 return; /* not for us */
2072
531f0331
JB
2073 if (cancel_event)
2074 drv->pending_remain_on_chan = 0;
55777702
JM
2075
2076 os_memset(&data, 0, sizeof(data));
2077 data.remain_on_channel.freq = freq;
2078 data.remain_on_channel.duration = duration;
2079 wpa_supplicant_event(drv->ctx, cancel_event ?
2080 EVENT_CANCEL_REMAIN_ON_CHANNEL :
2081 EVENT_REMAIN_ON_CHANNEL, &data);
2082}
2083
2084
6a1ce395
DG
2085static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
2086 struct nlattr *tb[])
2087{
2088 union wpa_event_data data;
2089
2090 os_memset(&data, 0, sizeof(data));
2091
2092 if (tb[NL80211_ATTR_IE]) {
2093 data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
2094 data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
2095 }
2096
2097 if (tb[NL80211_ATTR_IE_RIC]) {
2098 data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
2099 data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
2100 }
2101
2102 if (tb[NL80211_ATTR_MAC])
2103 os_memcpy(data.ft_ies.target_ap,
2104 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2105
2106 wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
2107 MAC2STR(data.ft_ies.target_ap));
2108
2109 wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
2110}
2111
2112
8d923a4a
JM
2113static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
2114 struct nlattr *tb[])
2115{
2116 union wpa_event_data event;
2117 struct nlattr *nl;
2118 int rem;
2119 struct scan_info *info;
2120#define MAX_REPORT_FREQS 50
2121 int freqs[MAX_REPORT_FREQS];
2122 int num_freqs = 0;
2123
536fd62d
JM
2124 if (drv->scan_for_auth) {
2125 drv->scan_for_auth = 0;
2126 wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
2127 "cfg80211 BSS entry");
2128 wpa_driver_nl80211_authenticate_retry(drv);
2129 return;
2130 }
2131
8d923a4a
JM
2132 os_memset(&event, 0, sizeof(event));
2133 info = &event.scan_info;
2134 info->aborted = aborted;
2135
2136 if (tb[NL80211_ATTR_SCAN_SSIDS]) {
2137 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
2138 struct wpa_driver_scan_ssid *s =
2139 &info->ssids[info->num_ssids];
2140 s->ssid = nla_data(nl);
2141 s->ssid_len = nla_len(nl);
3ae3ec27
JM
2142 wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
2143 wpa_ssid_txt(s->ssid, s->ssid_len));
8d923a4a
JM
2144 info->num_ssids++;
2145 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
2146 break;
2147 }
2148 }
2149 if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
3ae3ec27
JM
2150 char msg[200], *pos, *end;
2151 int res;
2152
2153 pos = msg;
2154 end = pos + sizeof(msg);
2155 *pos = '\0';
2156
8d923a4a
JM
2157 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
2158 {
2159 freqs[num_freqs] = nla_get_u32(nl);
3ae3ec27
JM
2160 res = os_snprintf(pos, end - pos, " %d",
2161 freqs[num_freqs]);
2162 if (res > 0 && end - pos > res)
2163 pos += res;
8d923a4a
JM
2164 num_freqs++;
2165 if (num_freqs == MAX_REPORT_FREQS - 1)
2166 break;
2167 }
2168 info->freqs = freqs;
2169 info->num_freqs = num_freqs;
3ae3ec27
JM
2170 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
2171 msg);
8d923a4a
JM
2172 }
2173 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
2174}
2175
2176
60a972a6
JM
2177static int get_link_signal(struct nl_msg *msg, void *arg)
2178{
2179 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2180 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2181 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
2182 static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
2183 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
95783298 2184 [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
60a972a6 2185 };
7ee35bf3
PS
2186 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
2187 static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
2188 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
2189 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
2190 [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
2191 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
2192 };
1c5c7273 2193 struct wpa_signal_info *sig_change = arg;
60a972a6
JM
2194
2195 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2196 genlmsg_attrlen(gnlh, 0), NULL);
2197 if (!tb[NL80211_ATTR_STA_INFO] ||
2198 nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
2199 tb[NL80211_ATTR_STA_INFO], policy))
2200 return NL_SKIP;
2201 if (!sinfo[NL80211_STA_INFO_SIGNAL])
2202 return NL_SKIP;
2203
7ee35bf3
PS
2204 sig_change->current_signal =
2205 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
2206
95783298
AO
2207 if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
2208 sig_change->avg_signal =
2209 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
2210 else
2211 sig_change->avg_signal = 0;
2212
7ee35bf3
PS
2213 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
2214 if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
2215 sinfo[NL80211_STA_INFO_TX_BITRATE],
2216 rate_policy)) {
2217 sig_change->current_txrate = 0;
2218 } else {
2219 if (rinfo[NL80211_RATE_INFO_BITRATE]) {
2220 sig_change->current_txrate =
2221 nla_get_u16(rinfo[
2222 NL80211_RATE_INFO_BITRATE]) * 100;
2223 }
2224 }
2225 }
2226
60a972a6
JM
2227 return NL_SKIP;
2228}
2229
2230
2231static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
1c5c7273 2232 struct wpa_signal_info *sig)
60a972a6
JM
2233{
2234 struct nl_msg *msg;
2235
7ee35bf3
PS
2236 sig->current_signal = -9999;
2237 sig->current_txrate = 0;
60a972a6
JM
2238
2239 msg = nlmsg_alloc();
2240 if (!msg)
2241 return -ENOMEM;
2242
9fb04070 2243 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
60a972a6
JM
2244
2245 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2246 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
2247
2248 return send_and_recv_msgs(drv, msg, get_link_signal, sig);
2249 nla_put_failure:
5883168a 2250 nlmsg_free(msg);
60a972a6
JM
2251 return -ENOBUFS;
2252}
2253
2254
7ee35bf3
PS
2255static int get_link_noise(struct nl_msg *msg, void *arg)
2256{
2257 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2258 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2259 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
2260 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
2261 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
2262 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
2263 };
1c5c7273 2264 struct wpa_signal_info *sig_change = arg;
7ee35bf3
PS
2265
2266 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2267 genlmsg_attrlen(gnlh, 0), NULL);
2268
2269 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
2270 wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
2271 return NL_SKIP;
2272 }
2273
2274 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
2275 tb[NL80211_ATTR_SURVEY_INFO],
2276 survey_policy)) {
2277 wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
2278 "attributes!");
2279 return NL_SKIP;
2280 }
2281
2282 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
2283 return NL_SKIP;
2284
2285 if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
2286 sig_change->frequency)
2287 return NL_SKIP;
2288
2289 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
2290 return NL_SKIP;
2291
2292 sig_change->current_noise =
2293 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
2294
2295 return NL_SKIP;
2296}
2297
2298
2299static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
1c5c7273 2300 struct wpa_signal_info *sig_change)
7ee35bf3
PS
2301{
2302 struct nl_msg *msg;
2303
2304 sig_change->current_noise = 9999;
2305 sig_change->frequency = drv->assoc_freq;
2306
2307 msg = nlmsg_alloc();
2308 if (!msg)
2309 return -ENOMEM;
2310
9fb04070 2311 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
7ee35bf3
PS
2312
2313 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2314
2315 return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
2316 nla_put_failure:
5883168a 2317 nlmsg_free(msg);
7ee35bf3
PS
2318 return -ENOBUFS;
2319}
2320
2321
577db0ae
GM
2322static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
2323{
2324 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2325 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2326 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
2327 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
2328 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
2329 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
2330 };
2331 struct wpa_scan_results *scan_results = arg;
2332 struct wpa_scan_res *scan_res;
2333 size_t i;
2334
2335 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2336 genlmsg_attrlen(gnlh, 0), NULL);
2337
2338 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
2339 wpa_printf(MSG_DEBUG, "nl80211: Survey data missing");
2340 return NL_SKIP;
2341 }
2342
2343 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
2344 tb[NL80211_ATTR_SURVEY_INFO],
2345 survey_policy)) {
2346 wpa_printf(MSG_DEBUG, "nl80211: Failed to parse nested "
2347 "attributes");
2348 return NL_SKIP;
2349 }
2350
2351 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
2352 return NL_SKIP;
2353
2354 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
2355 return NL_SKIP;
2356
2357 for (i = 0; i < scan_results->num; ++i) {
2358 scan_res = scan_results->res[i];
2359 if (!scan_res)
2360 continue;
2361 if ((int) nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
2362 scan_res->freq)
2363 continue;
2364 if (!(scan_res->flags & WPA_SCAN_NOISE_INVALID))
2365 continue;
2366 scan_res->noise = (s8)
2367 nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
2368 scan_res->flags &= ~WPA_SCAN_NOISE_INVALID;
2369 }
2370
2371 return NL_SKIP;
2372}
2373
2374
2375static int nl80211_get_noise_for_scan_results(
2376 struct wpa_driver_nl80211_data *drv,
2377 struct wpa_scan_results *scan_res)
2378{
2379 struct nl_msg *msg;
2380
2381 msg = nlmsg_alloc();
2382 if (!msg)
2383 return -ENOMEM;
2384
2385 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
2386
2387 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2388
2389 return send_and_recv_msgs(drv, msg, get_noise_for_scan_results,
2390 scan_res);
2391 nla_put_failure:
9e088e74 2392 nlmsg_free(msg);
577db0ae
GM
2393 return -ENOBUFS;
2394}
2395
2396
93910401
JM
2397static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
2398 struct nlattr *tb[])
2399{
2400 static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
2401 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
2402 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
2403 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
0d7e5a3a 2404 [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
93910401
JM
2405 };
2406 struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
2407 enum nl80211_cqm_rssi_threshold_event event;
b625473c 2408 union wpa_event_data ed;
1c5c7273 2409 struct wpa_signal_info sig;
7ee35bf3 2410 int res;
93910401
JM
2411
2412 if (tb[NL80211_ATTR_CQM] == NULL ||
2413 nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
2414 cqm_policy)) {
2415 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
2416 return;
2417 }
2418
0d7e5a3a
JB
2419 os_memset(&ed, 0, sizeof(ed));
2420
2421 if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
2422 if (!tb[NL80211_ATTR_MAC])
2423 return;
2424 os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
2425 ETH_ALEN);
2426 wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
2427 return;
2428 }
2429
93910401
JM
2430 if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
2431 return;
2432 event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
b625473c 2433
93910401
JM
2434 if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
2435 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2436 "event: RSSI high");
b625473c 2437 ed.signal_change.above_threshold = 1;
93910401
JM
2438 } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
2439 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2440 "event: RSSI low");
b625473c
JM
2441 ed.signal_change.above_threshold = 0;
2442 } else
2443 return;
2444
60a972a6
JM
2445 res = nl80211_get_link_signal(drv, &sig);
2446 if (res == 0) {
7ee35bf3
PS
2447 ed.signal_change.current_signal = sig.current_signal;
2448 ed.signal_change.current_txrate = sig.current_txrate;
2449 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm txrate: %d",
2450 sig.current_signal, sig.current_txrate);
2451 }
2452
2453 res = nl80211_get_link_noise(drv, &sig);
2454 if (res == 0) {
2455 ed.signal_change.current_noise = sig.current_noise;
2456 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
2457 sig.current_noise);
60a972a6
JM
2458 }
2459
b625473c 2460 wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
93910401
JM
2461}
2462
2463
18d2ba08
JM
2464static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
2465 struct nlattr **tb)
2466{
2467 u8 *addr;
2468 union wpa_event_data data;
2469
2470 if (tb[NL80211_ATTR_MAC] == NULL)
2471 return;
2472 addr = nla_data(tb[NL80211_ATTR_MAC]);
2473 wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
5f310a9e 2474
61cbe2ff 2475 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
5f310a9e
JM
2476 u8 *ies = NULL;
2477 size_t ies_len = 0;
2478 if (tb[NL80211_ATTR_IE]) {
2479 ies = nla_data(tb[NL80211_ATTR_IE]);
2480 ies_len = nla_len(tb[NL80211_ATTR_IE]);
2481 }
2482 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
2483 drv_event_assoc(drv->ctx, addr, ies, ies_len, 0);
2484 return;
2485 }
2486
18d2ba08
JM
2487 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2488 return;
2489
2490 os_memset(&data, 0, sizeof(data));
2491 os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
2492 wpa_supplicant_event(drv->ctx, EVENT_IBSS_RSN_START, &data);
2493}
2494
2495
ef985058
JM
2496static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
2497 struct nlattr **tb)
2498{
2499 u8 *addr;
2500 union wpa_event_data data;
2501
2502 if (tb[NL80211_ATTR_MAC] == NULL)
2503 return;
2504 addr = nla_data(tb[NL80211_ATTR_MAC]);
2505 wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
2506 MAC2STR(addr));
5f310a9e 2507
61cbe2ff 2508 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
5f310a9e
JM
2509 drv_event_disassoc(drv->ctx, addr);
2510 return;
2511 }
2512
ef985058
JM
2513 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2514 return;
2515
2516 os_memset(&data, 0, sizeof(data));
2517 os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
2518 wpa_supplicant_event(drv->ctx, EVENT_IBSS_PEER_LOST, &data);
2519}
2520
2521
b14a210c
JB
2522static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
2523 struct nlattr **tb)
2524{
2525 struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
2526 static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
2527 [NL80211_REKEY_DATA_KEK] = {
2528 .minlen = NL80211_KEK_LEN,
2529 .maxlen = NL80211_KEK_LEN,
2530 },
2531 [NL80211_REKEY_DATA_KCK] = {
2532 .minlen = NL80211_KCK_LEN,
2533 .maxlen = NL80211_KCK_LEN,
2534 },
2535 [NL80211_REKEY_DATA_REPLAY_CTR] = {
2536 .minlen = NL80211_REPLAY_CTR_LEN,
2537 .maxlen = NL80211_REPLAY_CTR_LEN,
2538 },
2539 };
2540 union wpa_event_data data;
2541
2542 if (!tb[NL80211_ATTR_MAC])
2543 return;
2544 if (!tb[NL80211_ATTR_REKEY_DATA])
2545 return;
2546 if (nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
2547 tb[NL80211_ATTR_REKEY_DATA], rekey_policy))
2548 return;
2549 if (!rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
2550 return;
2551
2552 os_memset(&data, 0, sizeof(data));
2553 data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
2554 wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
2555 MAC2STR(data.driver_gtk_rekey.bssid));
2556 data.driver_gtk_rekey.replay_ctr =
2557 nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
2558 wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
2559 data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
2560 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
2561}
2562
2563
c36d5242
JM
2564static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
2565 struct nlattr **tb)
2566{
2567 struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
2568 static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
2569 [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
2570 [NL80211_PMKSA_CANDIDATE_BSSID] = {
2571 .minlen = ETH_ALEN,
2572 .maxlen = ETH_ALEN,
2573 },
2574 [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
2575 };
2576 union wpa_event_data data;
2577
7d81932d
JM
2578 wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
2579
c36d5242
JM
2580 if (!tb[NL80211_ATTR_PMKSA_CANDIDATE])
2581 return;
2582 if (nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
2583 tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy))
2584 return;
2585 if (!cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
2586 !cand[NL80211_PMKSA_CANDIDATE_BSSID])
2587 return;
2588
2589 os_memset(&data, 0, sizeof(data));
2590 os_memcpy(data.pmkid_candidate.bssid,
2591 nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
2592 data.pmkid_candidate.index =
2593 nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
2594 data.pmkid_candidate.preauth =
2595 cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
2596 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
2597}
2598
2599
39718852
JB
2600static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
2601 struct nlattr **tb)
2602{
2603 union wpa_event_data data;
2604
7d81932d
JM
2605 wpa_printf(MSG_DEBUG, "nl80211: Probe client event");
2606
39718852
JB
2607 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
2608 return;
2609
2610 os_memset(&data, 0, sizeof(data));
2611 os_memcpy(data.client_poll.addr,
2612 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2613
2614 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
2615}
2616
2617
6201b052
JM
2618static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
2619 struct nlattr **tb)
2620{
2621 union wpa_event_data data;
2622
2623 wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
2624
2625 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
2626 return;
2627
2628 os_memset(&data, 0, sizeof(data));
2629 os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2630 switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
2631 case NL80211_TDLS_SETUP:
2632 wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
2633 MACSTR, MAC2STR(data.tdls.peer));
2634 data.tdls.oper = TDLS_REQUEST_SETUP;
2635 break;
2636 case NL80211_TDLS_TEARDOWN:
2637 wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
2638 MACSTR, MAC2STR(data.tdls.peer));
2639 data.tdls.oper = TDLS_REQUEST_TEARDOWN;
2640 break;
2641 default:
2642 wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
2643 "event");
2644 return;
2645 }
2646 if (tb[NL80211_ATTR_REASON_CODE]) {
2647 data.tdls.reason_code =
2648 nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
2649 }
2650
2651 wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
2652}
2653
2654
7239ea7f
ST
2655static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
2656 struct nlattr **tb)
2657{
2658 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
2659}
2660
2661
3140803b
RM
2662static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
2663 struct nlattr **tb)
2664{
2665 union wpa_event_data data;
2666 u32 reason;
2667
2668 wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
2669
2670 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
2671 return;
2672
2673 os_memset(&data, 0, sizeof(data));
2674 os_memcpy(data.connect_failed_reason.addr,
2675 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2676
2677 reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
2678 switch (reason) {
2679 case NL80211_CONN_FAIL_MAX_CLIENTS:
2680 wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
2681 data.connect_failed_reason.code = MAX_CLIENT_REACHED;
2682 break;
2683 case NL80211_CONN_FAIL_BLOCKED_CLIENT:
2684 wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
2685 " tried to connect",
2686 MAC2STR(data.connect_failed_reason.addr));
2687 data.connect_failed_reason.code = BLOCKED_CLIENT;
2688 break;
2689 default:
2690 wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
2691 "%u", reason);
2692 return;
2693 }
2694
2695 wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
2696}
2697
2698
04be54fa
SW
2699static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
2700 struct nlattr **tb)
2701{
2702 union wpa_event_data data;
2703 enum nl80211_radar_event event_type;
2704
2705 if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
2706 return;
2707
2708 os_memset(&data, 0, sizeof(data));
cd3b0700
MK
2709 data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2710 event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
04be54fa 2711
846de15d
JD
2712 /* Check HT params */
2713 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2714 data.dfs_event.ht_enabled = 1;
2715 data.dfs_event.chan_offset = 0;
2716
2717 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
2718 case NL80211_CHAN_NO_HT:
2719 data.dfs_event.ht_enabled = 0;
2720 break;
2721 case NL80211_CHAN_HT20:
2722 break;
2723 case NL80211_CHAN_HT40PLUS:
2724 data.dfs_event.chan_offset = 1;
2725 break;
2726 case NL80211_CHAN_HT40MINUS:
2727 data.dfs_event.chan_offset = -1;
2728 break;
2729 }
2730 }
2731
2732 /* Get VHT params */
884f1a3c
JM
2733 if (tb[NL80211_ATTR_CHANNEL_WIDTH])
2734 data.dfs_event.chan_width =
2735 convert2width(nla_get_u32(
2736 tb[NL80211_ATTR_CHANNEL_WIDTH]));
2737 if (tb[NL80211_ATTR_CENTER_FREQ1])
2738 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
846de15d
JD
2739 if (tb[NL80211_ATTR_CENTER_FREQ2])
2740 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
2741
2742 wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
2743 data.dfs_event.freq, data.dfs_event.ht_enabled,
2744 data.dfs_event.chan_offset, data.dfs_event.chan_width,
2745 data.dfs_event.cf1, data.dfs_event.cf2);
04be54fa
SW
2746
2747 switch (event_type) {
2748 case NL80211_RADAR_DETECTED:
2749 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
2750 break;
2751 case NL80211_RADAR_CAC_FINISHED:
2752 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
2753 break;
2754 case NL80211_RADAR_CAC_ABORTED:
2755 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
2756 break;
2757 case NL80211_RADAR_NOP_FINISHED:
2758 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
2759 break;
2760 default:
2761 wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
2762 "received", event_type);
2763 break;
2764 }
2765}
2766
2767
3088e4e5
JB
2768static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
2769 int wds)
02bb32c3
JB
2770{
2771 struct wpa_driver_nl80211_data *drv = bss->drv;
2772 union wpa_event_data event;
02bb32c3
JB
2773
2774 if (!tb[NL80211_ATTR_MAC])
2775 return;
2776
02bb32c3 2777 os_memset(&event, 0, sizeof(event));
341eebee 2778 event.rx_from_unknown.bssid = bss->addr;
02bb32c3 2779 event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
3088e4e5 2780 event.rx_from_unknown.wds = wds;
02bb32c3
JB
2781
2782 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
2783}
2784
2785
253f2e37
AH
2786static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
2787 const u8 *data, size_t len)
2788{
2789 u32 i, count;
2790 union wpa_event_data event;
2791 struct wpa_freq_range *range = NULL;
2792 const struct qca_avoid_freq_list *freq_range;
2793
2794 freq_range = (const struct qca_avoid_freq_list *) data;
2795 if (len < sizeof(freq_range->count))
2796 return;
2797
2798 count = freq_range->count;
2799 if (len < sizeof(freq_range->count) +
2800 count * sizeof(struct qca_avoid_freq_range)) {
2801 wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
2802 (unsigned int) len);
2803 return;
2804 }
2805
2806 if (count > 0) {
2807 range = os_calloc(count, sizeof(struct wpa_freq_range));
2808 if (range == NULL)
2809 return;
2810 }
2811
2812 os_memset(&event, 0, sizeof(event));
2813 for (i = 0; i < count; i++) {
2814 unsigned int idx = event.freq_range.num;
2815 range[idx].min = freq_range->range[i].start_freq;
2816 range[idx].max = freq_range->range[i].end_freq;
2817 wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
2818 range[idx].min, range[idx].max);
2819 if (range[idx].min > range[idx].max) {
2820 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
2821 continue;
2822 }
2823 event.freq_range.num++;
2824 }
2825 event.freq_range.range = range;
2826
2827 wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
2828
2829 os_free(range);
2830}
2831
2832
1682c623
JM
2833static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
2834 u32 subcmd, u8 *data, size_t len)
2835{
2836 switch (subcmd) {
253f2e37
AH
2837 case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
2838 qca_nl80211_avoid_freq(drv, data, len);
2839 break;
1682c623
JM
2840 default:
2841 wpa_printf(MSG_DEBUG,
2842 "nl80211: Ignore unsupported QCA vendor event %u",
2843 subcmd);
2844 break;
2845 }
2846}
2847
2848
17b79e65
JM
2849static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
2850 struct nlattr **tb)
2851{
2852 u32 vendor_id, subcmd, wiphy = 0;
2853 int wiphy_idx;
2854 u8 *data = NULL;
2855 size_t len = 0;
2856
2857 if (!tb[NL80211_ATTR_VENDOR_ID] ||
2858 !tb[NL80211_ATTR_VENDOR_SUBCMD])
2859 return;
2860
2861 vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
2862 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
2863
2864 if (tb[NL80211_ATTR_WIPHY])
2865 wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2866
2867 wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
2868 wiphy, vendor_id, subcmd);
2869
2870 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2871 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
2872 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
2873 wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
2874 }
2875
2876 wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
2877 if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
2878 wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
2879 wiphy, wiphy_idx);
2880 return;
2881 }
2882
2883 switch (vendor_id) {
1682c623
JM
2884 case OUI_QCA:
2885 nl80211_vendor_event_qca(drv, subcmd, data, len);
2886 break;
17b79e65
JM
2887 default:
2888 wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
2889 break;
2890 }
2891}
2892
2893
142817b2
JM
2894static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
2895 struct nlattr *tb[])
2896{
2897 union wpa_event_data data;
2898 enum nl80211_reg_initiator init;
2899
2900 wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
2901
2902 if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
2903 return;
2904
2905 os_memset(&data, 0, sizeof(data));
2906 init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
2907 wpa_printf(MSG_DEBUG, " * initiator=%d", init);
2908 switch (init) {
2909 case NL80211_REGDOM_SET_BY_CORE:
2910 data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
2911 break;
2912 case NL80211_REGDOM_SET_BY_USER:
2913 data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
2914 break;
2915 case NL80211_REGDOM_SET_BY_DRIVER:
2916 data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
2917 break;
2918 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
2919 data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
2920 break;
2921 }
2922
2923 if (tb[NL80211_ATTR_REG_TYPE]) {
2924 enum nl80211_reg_type type;
2925 type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
2926 wpa_printf(MSG_DEBUG, " * type=%d", type);
2927 switch (type) {
2928 case NL80211_REGDOM_TYPE_COUNTRY:
2929 data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
2930 break;
2931 case NL80211_REGDOM_TYPE_WORLD:
2932 data.channel_list_changed.type = REGDOM_TYPE_WORLD;
2933 break;
2934 case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
2935 data.channel_list_changed.type =
2936 REGDOM_TYPE_CUSTOM_WORLD;
2937 break;
2938 case NL80211_REGDOM_TYPE_INTERSECTION:
2939 data.channel_list_changed.type =
2940 REGDOM_TYPE_INTERSECTION;
2941 break;
2942 }
2943 }
2944
2945 if (tb[NL80211_ATTR_REG_ALPHA2]) {
2946 os_strlcpy(data.channel_list_changed.alpha2,
2947 nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
2948 sizeof(data.channel_list_changed.alpha2));
2949 wpa_printf(MSG_DEBUG, " * alpha2=%s",
2950 data.channel_list_changed.alpha2);
2951 }
2952
2953 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
2954}
2955
2956
a5e1eb20
SE
2957static void do_process_drv_event(struct i802_bss *bss, int cmd,
2958 struct nlattr **tb)
97865538 2959{
a5e1eb20 2960 struct wpa_driver_nl80211_data *drv = bss->drv;
795baf77 2961 union wpa_event_data data;
a5e1eb20 2962
2090a0b4
DS
2963 wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
2964 cmd, nl80211_command_to_string(cmd), bss->ifname);
2965
b1f625e0 2966 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
d6c9aab8
JB
2967 (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
2968 cmd == NL80211_CMD_SCAN_ABORTED)) {
834ee56f 2969 wpa_driver_nl80211_set_mode(drv->first_bss,
b1f625e0
EP
2970 drv->ap_scan_as_station);
2971 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
ad1e68e6
JM
2972 }
2973
d6c9aab8 2974 switch (cmd) {
d942a79e 2975 case NL80211_CMD_TRIGGER_SCAN:
565110cd 2976 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
a771c07d 2977 drv->scan_state = SCAN_STARTED;
1b5df9e5
JM
2978 if (drv->scan_for_auth) {
2979 /*
2980 * Cannot indicate EVENT_SCAN_STARTED here since we skip
2981 * EVENT_SCAN_RESULTS in scan_for_auth case and the
2982 * upper layer implementation could get confused about
2983 * scanning state.
2984 */
2985 wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
2986 break;
2987 }
a5f40eff 2988 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
d942a79e 2989 break;
d21c63b9 2990 case NL80211_CMD_START_SCHED_SCAN:
565110cd 2991 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
a771c07d 2992 drv->scan_state = SCHED_SCAN_STARTED;
d21c63b9
LC
2993 break;
2994 case NL80211_CMD_SCHED_SCAN_STOPPED:
565110cd 2995 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
a771c07d 2996 drv->scan_state = SCHED_SCAN_STOPPED;
d21c63b9
LC
2997 wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
2998 break;
97865538 2999 case NL80211_CMD_NEW_SCAN_RESULTS:
565110cd
JM
3000 wpa_dbg(drv->ctx, MSG_DEBUG,
3001 "nl80211: New scan results available");
a771c07d 3002 drv->scan_state = SCAN_COMPLETED;
97865538
JM
3003 drv->scan_complete_events = 1;
3004 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
3005 drv->ctx);
8d923a4a 3006 send_scan_event(drv, 0, tb);
97865538 3007 break;
d21c63b9 3008 case NL80211_CMD_SCHED_SCAN_RESULTS:
565110cd
JM
3009 wpa_dbg(drv->ctx, MSG_DEBUG,
3010 "nl80211: New sched scan results available");
a771c07d 3011 drv->scan_state = SCHED_SCAN_RESULTS;
d21c63b9
LC
3012 send_scan_event(drv, 0, tb);
3013 break;
97865538 3014 case NL80211_CMD_SCAN_ABORTED:
565110cd 3015 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
a771c07d 3016 drv->scan_state = SCAN_ABORTED;
97865538
JM
3017 /*
3018 * Need to indicate that scan results are available in order
3019 * not to make wpa_supplicant stop its scanning.
3020 */
3021 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
3022 drv->ctx);
8d923a4a 3023 send_scan_event(drv, 1, tb);
97865538 3024 break;
c2a04078
JM
3025 case NL80211_CMD_AUTHENTICATE:
3026 case NL80211_CMD_ASSOCIATE:
3027 case NL80211_CMD_DEAUTHENTICATE:
3028 case NL80211_CMD_DISASSOCIATE:
bd94971e 3029 case NL80211_CMD_FRAME_TX_STATUS:
7d878ca7
JM
3030 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
3031 case NL80211_CMD_UNPROT_DISASSOCIATE:
97279d8d 3032 mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
58f6fbe0
JM
3033 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3034 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
da873dbb
JB
3035 tb[NL80211_ATTR_COOKIE],
3036 tb[NL80211_ATTR_RX_SIGNAL_DBM]);
c2a04078 3037 break;
da72a1c1
ZY
3038 case NL80211_CMD_CONNECT:
3039 case NL80211_CMD_ROAM:
d6c9aab8 3040 mlme_event_connect(drv, cmd,
da72a1c1
ZY
3041 tb[NL80211_ATTR_STATUS_CODE],
3042 tb[NL80211_ATTR_MAC],
3043 tb[NL80211_ATTR_REQ_IE],
3044 tb[NL80211_ATTR_RESP_IE]);
3045 break;
1b487b8b 3046 case NL80211_CMD_CH_SWITCH_NOTIFY:
8d1fdde7
JD
3047 mlme_event_ch_switch(drv,
3048 tb[NL80211_ATTR_IFINDEX],
3049 tb[NL80211_ATTR_WIPHY_FREQ],
3050 tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3051 tb[NL80211_ATTR_CHANNEL_WIDTH],
3052 tb[NL80211_ATTR_CENTER_FREQ1],
3053 tb[NL80211_ATTR_CENTER_FREQ2]);
1b487b8b 3054 break;
da72a1c1 3055 case NL80211_CMD_DISCONNECT:
20f5a4c2 3056 mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
3d9975d5
JM
3057 tb[NL80211_ATTR_MAC],
3058 tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
da72a1c1 3059 break;
35583f3f 3060 case NL80211_CMD_MICHAEL_MIC_FAILURE:
a5e1eb20 3061 mlme_event_michael_mic_failure(bss, tb);
35583f3f 3062 break;
5cc4d64b
JM
3063 case NL80211_CMD_JOIN_IBSS:
3064 mlme_event_join_ibss(drv, tb);
3065 break;
55777702
JM
3066 case NL80211_CMD_REMAIN_ON_CHANNEL:
3067 mlme_event_remain_on_channel(drv, 0, tb);
3068 break;
3069 case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
3070 mlme_event_remain_on_channel(drv, 1, tb);
3071 break;
93910401
JM
3072 case NL80211_CMD_NOTIFY_CQM:
3073 nl80211_cqm_event(drv, tb);
3074 break;
33c5deb8 3075 case NL80211_CMD_REG_CHANGE:
142817b2 3076 nl80211_reg_change_event(drv, tb);
33c5deb8
JM
3077 break;
3078 case NL80211_CMD_REG_BEACON_HINT:
3079 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
8597ebdb
JM
3080 os_memset(&data, 0, sizeof(data));
3081 data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
33c5deb8 3082 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
8597ebdb 3083 &data);
33c5deb8 3084 break;
18d2ba08
JM
3085 case NL80211_CMD_NEW_STATION:
3086 nl80211_new_station_event(drv, tb);
3087 break;
ef985058
JM
3088 case NL80211_CMD_DEL_STATION:
3089 nl80211_del_station_event(drv, tb);
3090 break;
b14a210c
JB
3091 case NL80211_CMD_SET_REKEY_OFFLOAD:
3092 nl80211_rekey_offload_event(drv, tb);
3093 break;
c36d5242
JM
3094 case NL80211_CMD_PMKSA_CANDIDATE:
3095 nl80211_pmksa_candidate_event(drv, tb);
3096 break;
39718852
JB
3097 case NL80211_CMD_PROBE_CLIENT:
3098 nl80211_client_probe_event(drv, tb);
3099 break;
6201b052
JM
3100 case NL80211_CMD_TDLS_OPER:
3101 nl80211_tdls_oper_event(drv, tb);
3102 break;
3140803b
RM
3103 case NL80211_CMD_CONN_FAILED:
3104 nl80211_connect_failed_event(drv, tb);
3105 break;
6a1ce395
DG
3106 case NL80211_CMD_FT_EVENT:
3107 mlme_event_ft_event(drv, tb);
3108 break;
04be54fa
SW
3109 case NL80211_CMD_RADAR_DETECT:
3110 nl80211_radar_event(drv, tb);
3111 break;
7239ea7f
ST
3112 case NL80211_CMD_STOP_AP:
3113 nl80211_stop_ap(drv, tb);
3114 break;
17b79e65
JM
3115 case NL80211_CMD_VENDOR:
3116 nl80211_vendor_event(drv, tb);
3117 break;
97865538 3118 default:
565110cd
JM
3119 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
3120 "(cmd=%d)", cmd);
97865538
JM
3121 break;
3122 }
d6c9aab8
JB
3123}
3124
3125
3126static int process_drv_event(struct nl_msg *msg, void *arg)
3127{
3128 struct wpa_driver_nl80211_data *drv = arg;
3129 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3130 struct nlattr *tb[NL80211_ATTR_MAX + 1];
a5e1eb20
SE
3131 struct i802_bss *bss;
3132 int ifidx = -1;
d6c9aab8
JB
3133
3134 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3135 genlmsg_attrlen(gnlh, 0), NULL);
3136
d3aaef80 3137 if (tb[NL80211_ATTR_IFINDEX]) {
a5e1eb20
SE
3138 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
3139
834ee56f 3140 for (bss = drv->first_bss; bss; bss = bss->next)
d3aaef80
DS
3141 if (ifidx == -1 || ifidx == bss->ifindex) {
3142 do_process_drv_event(bss, gnlh->cmd, tb);
3143 return NL_SKIP;
3144 }
3145 wpa_printf(MSG_DEBUG,
3146 "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d)",
3147 gnlh->cmd, ifidx);
3148 } else if (tb[NL80211_ATTR_WDEV]) {
3149 u64 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
3150 wpa_printf(MSG_DEBUG, "nl80211: Process event on P2P device");
834ee56f 3151 for (bss = drv->first_bss; bss; bss = bss->next) {
d3aaef80
DS
3152 if (bss->wdev_id_set && wdev_id == bss->wdev_id) {
3153 do_process_drv_event(bss, gnlh->cmd, tb);
3154 return NL_SKIP;
3155 }
d6c9aab8 3156 }
d3aaef80
DS
3157 wpa_printf(MSG_DEBUG,
3158 "nl80211: Ignored event (cmd=%d) for foreign interface (wdev 0x%llx)",
3159 gnlh->cmd, (long long unsigned int) wdev_id);
d6c9aab8
JB
3160 }
3161
d6c9aab8
JB
3162 return NL_SKIP;
3163}
3164
3165
3166static int process_global_event(struct nl_msg *msg, void *arg)
3167{
3168 struct nl80211_global *global = arg;
3169 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3170 struct nlattr *tb[NL80211_ATTR_MAX + 1];
24b5bd8b 3171 struct wpa_driver_nl80211_data *drv, *tmp;
d6c9aab8 3172 int ifidx = -1;
a5e1eb20 3173 struct i802_bss *bss;
54d4ba42 3174 u64 wdev_id = 0;
d3aaef80 3175 int wdev_id_set = 0;
d6c9aab8
JB
3176
3177 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3178 genlmsg_attrlen(gnlh, 0), NULL);
3179
3180 if (tb[NL80211_ATTR_IFINDEX])
3181 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
d3aaef80
DS
3182 else if (tb[NL80211_ATTR_WDEV]) {
3183 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
3184 wdev_id_set = 1;
3185 }
d6c9aab8 3186
24b5bd8b
JB
3187 dl_list_for_each_safe(drv, tmp, &global->interfaces,
3188 struct wpa_driver_nl80211_data, list) {
834ee56f 3189 for (bss = drv->first_bss; bss; bss = bss->next) {
d3aaef80
DS
3190 if ((ifidx == -1 && !wdev_id_set) ||
3191 ifidx == bss->ifindex ||
3192 (wdev_id_set && bss->wdev_id_set &&
3193 wdev_id == bss->wdev_id)) {
a5e1eb20
SE
3194 do_process_drv_event(bss, gnlh->cmd, tb);
3195 return NL_SKIP;
3196 }
3197 }
d6c9aab8 3198 }
97865538
JM
3199
3200 return NL_SKIP;
3201}
3202
3203
cc7a48d1
JB
3204static int process_bss_event(struct nl_msg *msg, void *arg)
3205{
a11241fa 3206 struct i802_bss *bss = arg;
cc7a48d1
JB
3207 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3208 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3209
3210 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3211 genlmsg_attrlen(gnlh, 0), NULL);
3212
2090a0b4
DS
3213 wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
3214 gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
3215 bss->ifname);
3216
cc7a48d1 3217 switch (gnlh->cmd) {
a11241fa
JB
3218 case NL80211_CMD_FRAME:
3219 case NL80211_CMD_FRAME_TX_STATUS:
97279d8d 3220 mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
a11241fa
JB
3221 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3222 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
da873dbb
JB
3223 tb[NL80211_ATTR_COOKIE],
3224 tb[NL80211_ATTR_RX_SIGNAL_DBM]);
a11241fa 3225 break;
02bb32c3 3226 case NL80211_CMD_UNEXPECTED_FRAME:
3088e4e5
JB
3227 nl80211_spurious_frame(bss, tb, 0);
3228 break;
3229 case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
3230 nl80211_spurious_frame(bss, tb, 1);
02bb32c3 3231 break;
cc7a48d1
JB
3232 default:
3233 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
3234 "(cmd=%d)", gnlh->cmd);
3235 break;
3236 }
3237
3238 return NL_SKIP;
3239}
3240
3241
97865538 3242static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
5582a5d1 3243 void *handle)
97865538 3244{
a4ae123c 3245 struct nl_cb *cb = eloop_ctx;
34068ac3 3246 int res;
97865538 3247
cc2ada86 3248 wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
97865538 3249
34068ac3
JM
3250 res = nl_recvmsgs(handle, cb);
3251 if (res) {
3252 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
3253 __func__, res);
3254 }
97865538
JM
3255}
3256
3257
6d158490
LR
3258/**
3259 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
3260 * @priv: driver_nl80211 private data
3261 * @alpha2_arg: country to which to switch to
3262 * Returns: 0 on success, -1 on failure
3263 *
3264 * This asks nl80211 to set the regulatory domain for given
3265 * country ISO / IEC alpha2.
3266 */
3267static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
3268{
a2e40bb6
FF
3269 struct i802_bss *bss = priv;
3270 struct wpa_driver_nl80211_data *drv = bss->drv;
6d158490
LR
3271 char alpha2[3];
3272 struct nl_msg *msg;
3273
3274 msg = nlmsg_alloc();
3275 if (!msg)
e785c2ba 3276 return -ENOMEM;
6d158490
LR
3277
3278 alpha2[0] = alpha2_arg[0];
3279 alpha2[1] = alpha2_arg[1];
3280 alpha2[2] = '\0';
3281
9fb04070 3282 nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG);
6d158490
LR
3283
3284 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
3285 if (send_and_recv_msgs(drv, msg, NULL, NULL))
3286 return -EINVAL;
3287 return 0;
3288nla_put_failure:
5883168a 3289 nlmsg_free(msg);
6d158490
LR
3290 return -EINVAL;
3291}
3292
3293
f0793bf1
JM
3294static int nl80211_get_country(struct nl_msg *msg, void *arg)
3295{
3296 char *alpha2 = arg;
3297 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3298 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3299
3300 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3301 genlmsg_attrlen(gnlh, 0), NULL);
3302 if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
3303 wpa_printf(MSG_DEBUG, "nl80211: No country information available");
3304 return NL_SKIP;
3305 }
3306 os_strlcpy(alpha2, nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]), 3);
3307 return NL_SKIP;
3308}
3309
3310
3311static int wpa_driver_nl80211_get_country(void *priv, char *alpha2)
3312{
3313 struct i802_bss *bss = priv;
3314 struct wpa_driver_nl80211_data *drv = bss->drv;
3315 struct nl_msg *msg;
3316 int ret;
3317
3318 msg = nlmsg_alloc();
3319 if (!msg)
3320 return -ENOMEM;
3321
3322 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
3323 alpha2[0] = '\0';
3324 ret = send_and_recv_msgs(drv, msg, nl80211_get_country, alpha2);
3325 if (!alpha2[0])
3326 ret = -1;
3327
3328 return ret;
3329}
3330
3331
43245552
DJ
3332static int protocol_feature_handler(struct nl_msg *msg, void *arg)
3333{
3334 u32 *feat = arg;
3335 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3336 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3337
3338 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3339 genlmsg_attrlen(gnlh, 0), NULL);
3340
3341 if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES])
3342 *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]);
3343
3344 return NL_SKIP;
3345}
3346
3347
3348static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
3349{
3350 u32 feat = 0;
3351 struct nl_msg *msg;
3352
3353 msg = nlmsg_alloc();
3354 if (!msg)
3355 goto nla_put_failure;
3356
3357 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES);
3358 if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat) == 0)
3359 return feat;
3360
3361 msg = NULL;
3362nla_put_failure:
3363 nlmsg_free(msg);
3364 return 0;
3365}
3366
3367
80bc75f1 3368struct wiphy_info_data {
8cd6b7bc 3369 struct wpa_driver_nl80211_data *drv;
e8b5e24e
JB
3370 struct wpa_driver_capa *capa;
3371
4752147d
IP
3372 unsigned int num_multichan_concurrent;
3373
e8b5e24e 3374 unsigned int error:1;
61cbe2ff 3375 unsigned int device_ap_sme:1;
39718852 3376 unsigned int poll_command_supported:1;
32ab4855 3377 unsigned int data_tx_status:1;
536062f2 3378 unsigned int monitor_supported:1;
43245552
DJ
3379 unsigned int auth_supported:1;
3380 unsigned int connect_supported:1;
3381 unsigned int p2p_go_supported:1;
3382 unsigned int p2p_client_supported:1;
3383 unsigned int p2p_concurrent:1;
1c4ffa87 3384 unsigned int channel_switch_supported:1;
429dd9af 3385 unsigned int set_qos_map_supported:1;
80bc75f1
JM
3386};
3387
3388
562c9d97
AN
3389static unsigned int probe_resp_offload_support(int supp_protocols)
3390{
3391 unsigned int prot = 0;
3392
3393 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
3394 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
3395 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
3396 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
3397 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
3398 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
3399 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
3400 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
3401
3402 return prot;
3403}
3404
3405
5f439107
JM
3406static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
3407 struct nlattr *tb)
80bc75f1 3408{
5f439107
JM
3409 struct nlattr *nl_mode;
3410 int i;
3411
3412 if (tb == NULL)
3413 return;
3414
3415 nla_for_each_nested(nl_mode, tb, i) {
3416 switch (nla_type(nl_mode)) {
3417 case NL80211_IFTYPE_AP:
3418 info->capa->flags |= WPA_DRIVER_FLAGS_AP;
3419 break;
65d52fc1
BR
3420 case NL80211_IFTYPE_ADHOC:
3421 info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
3422 break;
7aad838c
NS
3423 case NL80211_IFTYPE_P2P_DEVICE:
3424 info->capa->flags |=
3425 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
3426 break;
5f439107
JM
3427 case NL80211_IFTYPE_P2P_GO:
3428 info->p2p_go_supported = 1;
3429 break;
3430 case NL80211_IFTYPE_P2P_CLIENT:
3431 info->p2p_client_supported = 1;
3432 break;
3433 case NL80211_IFTYPE_MONITOR:
3434 info->monitor_supported = 1;
3435 break;
3436 }
3437 }
3438}
3439
3440
3441static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
3442 struct nlattr *nl_combi)
3443{
3444 struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
3445 struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
3446 struct nlattr *nl_limit, *nl_mode;
3447 int err, rem_limit, rem_mode;
3448 int combination_has_p2p = 0, combination_has_mgd = 0;
7626850d
JB
3449 static struct nla_policy
3450 iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
3451 [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
3452 [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
3453 [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
3454 [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
f295d0c8 3455 [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
7626850d
JB
3456 },
3457 iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
3458 [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
3459 [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
3460 };
80bc75f1 3461
5f439107
JM
3462 err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
3463 nl_combi, iface_combination_policy);
3464 if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
3465 !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
3466 !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
3467 return 0; /* broken combination */
3468
f295d0c8
SW
3469 if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
3470 info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
3471
5f439107
JM
3472 nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
3473 rem_limit) {
3474 err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
3475 nl_limit, iface_limit_policy);
3476 if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
3477 return 0; /* broken combination */
3478
3479 nla_for_each_nested(nl_mode,
3480 tb_limit[NL80211_IFACE_LIMIT_TYPES],
3481 rem_mode) {
3482 int ift = nla_type(nl_mode);
3483 if (ift == NL80211_IFTYPE_P2P_GO ||
3484 ift == NL80211_IFTYPE_P2P_CLIENT)
3485 combination_has_p2p = 1;
3486 if (ift == NL80211_IFTYPE_STATION)
3487 combination_has_mgd = 1;
3488 }
3489 if (combination_has_p2p && combination_has_mgd)
3490 break;
3491 }
3492
3493 if (combination_has_p2p && combination_has_mgd) {
83c4cb52 3494 unsigned int num_channels =
4752147d 3495 nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
83c4cb52
FF
3496
3497 info->p2p_concurrent = 1;
3498 if (info->num_multichan_concurrent < num_channels)
3499 info->num_multichan_concurrent = num_channels;
5f439107
JM
3500 }
3501
3502 return 0;
3503}
3504
3505
3506static void wiphy_info_iface_comb(struct wiphy_info_data *info,
3507 struct nlattr *tb)
3508{
3509 struct nlattr *nl_combi;
3510 int rem_combi;
3511
3512 if (tb == NULL)
3513 return;
3514
3515 nla_for_each_nested(nl_combi, tb, rem_combi) {
3516 if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
3517 break;
3518 }
3519}
3520
3521
3522static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
3523 struct nlattr *tb)
3524{
3525 struct nlattr *nl_cmd;
3526 int i;
3527
3528 if (tb == NULL)
3529 return;
3530
3531 nla_for_each_nested(nl_cmd, tb, i) {
3532 switch (nla_get_u32(nl_cmd)) {
3533 case NL80211_CMD_AUTHENTICATE:
3534 info->auth_supported = 1;
3535 break;
3536 case NL80211_CMD_CONNECT:
3537 info->connect_supported = 1;
3538 break;
3539 case NL80211_CMD_START_SCHED_SCAN:
3540 info->capa->sched_scan_supported = 1;
3541 break;
3542 case NL80211_CMD_PROBE_CLIENT:
3543 info->poll_command_supported = 1;
3544 break;
1c4ffa87
AO
3545 case NL80211_CMD_CHANNEL_SWITCH:
3546 info->channel_switch_supported = 1;
3547 break;
429dd9af
JM
3548 case NL80211_CMD_SET_QOS_MAP:
3549 info->set_qos_map_supported = 1;
3550 break;
5f439107
JM
3551 }
3552 }
3553}
3554
3555
bee25cc9
JM
3556static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
3557 struct nlattr *tb)
3558{
3559 int i, num;
3560 u32 *ciphers;
3561
3562 if (tb == NULL)
3563 return;
3564
3565 num = nla_len(tb) / sizeof(u32);
3566 ciphers = nla_data(tb);
3567 for (i = 0; i < num; i++) {
3568 u32 c = ciphers[i];
3569
3570 wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
3571 c >> 24, (c >> 16) & 0xff,
3572 (c >> 8) & 0xff, c & 0xff);
3573 switch (c) {
3574 case WLAN_CIPHER_SUITE_CCMP_256:
3575 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
3576 break;
3577 case WLAN_CIPHER_SUITE_GCMP_256:
3578 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
3579 break;
3580 case WLAN_CIPHER_SUITE_CCMP:
3581 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
3582 break;
3583 case WLAN_CIPHER_SUITE_GCMP:
3584 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
3585 break;
3586 case WLAN_CIPHER_SUITE_TKIP:
3587 info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
3588 break;
3589 case WLAN_CIPHER_SUITE_WEP104:
3590 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
3591 break;
3592 case WLAN_CIPHER_SUITE_WEP40:
3593 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
3594 break;
3595 case WLAN_CIPHER_SUITE_AES_CMAC:
3596 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
3597 break;
3598 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
3599 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
3600 break;
3601 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
3602 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
3603 break;
3604 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
3605 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
3606 break;
ae6f9272
JM
3607 case WLAN_CIPHER_SUITE_NO_GROUP_ADDR:
3608 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GTK_NOT_USED;
3609 break;
bee25cc9
JM
3610 }
3611 }
3612}
3613
3614
5f439107
JM
3615static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
3616 struct nlattr *tb)
3617{
5f439107
JM
3618 if (tb)
3619 capa->max_remain_on_chan = nla_get_u32(tb);
3620}
3621
3622
3623static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
3624 struct nlattr *ext_setup)
3625{
3626 if (tdls == NULL)
3627 return;
3628
3629 wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
3630 capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
3631
3632 if (ext_setup) {
3633 wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
3634 capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
3635 }
3636}
3637
3638
3639static void wiphy_info_feature_flags(struct wiphy_info_data *info,
3640 struct nlattr *tb)
3641{
3642 u32 flags;
3643 struct wpa_driver_capa *capa = info->capa;
3644
3645 if (tb == NULL)
3646 return;
3647
3648 flags = nla_get_u32(tb);
3649
3650 if (flags & NL80211_FEATURE_SK_TX_STATUS)
3651 info->data_tx_status = 1;
3652
3653 if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
3654 capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
3655
3656 if (flags & NL80211_FEATURE_SAE)
3657 capa->flags |= WPA_DRIVER_FLAGS_SAE;
3658
3659 if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
3660 capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
e87ef751
PX
3661
3662 if (flags & NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)
3663 capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
5f439107
JM
3664}
3665
3666
3667static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
3668 struct nlattr *tb)
3669{
3670 u32 protocols;
3671
3672 if (tb == NULL)
3673 return;
3674
3675 protocols = nla_get_u32(tb);
3676 wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
3677 "mode");
3678 capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
3679 capa->probe_resp_offloads = probe_resp_offload_support(protocols);
3680}
3681
3682
3683static int wiphy_info_handler(struct nl_msg *msg, void *arg)
3684{
3685 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3686 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3687 struct wiphy_info_data *info = arg;
3688 struct wpa_driver_capa *capa = info->capa;
8cd6b7bc 3689 struct wpa_driver_nl80211_data *drv = info->drv;
5f439107 3690
80bc75f1
JM
3691 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3692 genlmsg_attrlen(gnlh, 0), NULL);
3693
5fbcb45d 3694 if (tb[NL80211_ATTR_WIPHY_NAME])
24f051eb 3695 os_strlcpy(drv->phyname,
5fbcb45d
AS
3696 nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
3697 sizeof(drv->phyname));
80bc75f1 3698 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
e8b5e24e 3699 capa->max_scan_ssids =
80bc75f1
JM
3700 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
3701
d21c63b9 3702 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
e8b5e24e 3703 capa->max_sched_scan_ssids =
d21c63b9
LC
3704 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
3705
bd525934 3706 if (tb[NL80211_ATTR_MAX_MATCH_SETS])
e8b5e24e 3707 capa->max_match_sets =
bd525934
LC
3708 nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
3709
3c4ca363
VN
3710 if (tb[NL80211_ATTR_MAC_ACL_MAX])
3711 capa->max_acl_mac_addrs =
3712 nla_get_u8(tb[NL80211_ATTR_MAC_ACL_MAX]);
3713
5f439107
JM
3714 wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
3715 wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
3716 wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
bee25cc9 3717 wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
93d11400 3718
e8b5e24e
JB
3719 if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
3720 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
3721 "off-channel TX");
3722 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
3723 }
3724
3725 if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
3726 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
3727 capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
3728 }
5dfca53f 3729
5f439107
JM
3730 wiphy_info_max_roc(capa,
3731 tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
004ba773 3732
70619a5d
EP
3733 if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
3734 capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
3735
5f439107
JM
3736 wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
3737 tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
03ea1786 3738
61cbe2ff
JB
3739 if (tb[NL80211_ATTR_DEVICE_AP_SME])
3740 info->device_ap_sme = 1;
3741
5f439107
JM
3742 wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
3743 wiphy_info_probe_resp_offload(capa,
3744 tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
562c9d97 3745
8cd6b7bc
JB
3746 if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
3747 drv->extended_capa == NULL) {
3748 drv->extended_capa =
3749 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3750 if (drv->extended_capa) {
3751 os_memcpy(drv->extended_capa,
3752 nla_data(tb[NL80211_ATTR_EXT_CAPA]),
3753 nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3754 drv->extended_capa_len =
3755 nla_len(tb[NL80211_ATTR_EXT_CAPA]);
3756 }
3757 drv->extended_capa_mask =
3758 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3759 if (drv->extended_capa_mask) {
3760 os_memcpy(drv->extended_capa_mask,
3761 nla_data(tb[NL80211_ATTR_EXT_CAPA]),
3762 nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3763 } else {
3764 os_free(drv->extended_capa);
3765 drv->extended_capa = NULL;
3766 drv->extended_capa_len = 0;
3767 }
3768 }
3769
17b79e65
JM
3770 if (tb[NL80211_ATTR_VENDOR_DATA]) {
3771 struct nlattr *nl;
3772 int rem;
3773
3774 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
3775 struct nl80211_vendor_cmd_info *vinfo;
080cc445 3776 if (nla_len(nl) != sizeof(*vinfo)) {
17b79e65
JM
3777 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
3778 continue;
3779 }
3780 vinfo = nla_data(nl);
65d645ce
AS
3781 if (vinfo->subcmd ==
3782 QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY)
3783 drv->dfs_vendor_cmd_avail = 1;
3784
17b79e65
JM
3785 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
3786 vinfo->vendor_id, vinfo->subcmd);
3787 }
3788 }
3789
3790 if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
3791 struct nlattr *nl;
3792 int rem;
3793
3794 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
3795 struct nl80211_vendor_cmd_info *vinfo;
080cc445 3796 if (nla_len(nl) != sizeof(*vinfo)) {
17b79e65
JM
3797 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
3798 continue;
3799 }
3800 vinfo = nla_data(nl);
3801 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
3802 vinfo->vendor_id, vinfo->subcmd);
3803 }
3804 }
3805
80bc75f1
JM
3806 return NL_SKIP;
3807}
3808
3809
3810static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
3811 struct wiphy_info_data *info)
3812{
43245552 3813 u32 feat;
80bc75f1
JM
3814 struct nl_msg *msg;
3815
3816 os_memset(info, 0, sizeof(*info));
e8b5e24e 3817 info->capa = &drv->capa;
8cd6b7bc 3818 info->drv = drv;
89e07afb 3819
80bc75f1
JM
3820 msg = nlmsg_alloc();
3821 if (!msg)
3822 return -1;
3823
43245552
DJ
3824 feat = get_nl80211_protocol_features(drv);
3825 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
3826 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_WIPHY);
3827 else
3828 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
80bc75f1 3829
43245552 3830 NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
834ee56f 3831 if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
f632e483 3832 goto nla_put_failure;
80bc75f1 3833
43245552
DJ
3834 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info))
3835 return -1;
3836
3837 if (info->auth_supported)
3838 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
3839 else if (!info->connect_supported) {
3840 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
3841 "authentication/association or connect commands");
3842 info->error = 1;
3843 }
3844
3845 if (info->p2p_go_supported && info->p2p_client_supported)
3846 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
3847 if (info->p2p_concurrent) {
3848 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
3849 "interface (driver advertised support)");
3850 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
3851 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
3852 }
4752147d 3853 if (info->num_multichan_concurrent > 1) {
43245552
DJ
3854 wpa_printf(MSG_DEBUG, "nl80211: Enable multi-channel "
3855 "concurrent (driver advertised support)");
4752147d
IP
3856 drv->capa.num_multichan_concurrent =
3857 info->num_multichan_concurrent;
43245552 3858 }
b691dcb1
IP
3859
3860 /* default to 5000 since early versions of mac80211 don't set it */
3861 if (!drv->capa.max_remain_on_chan)
3862 drv->capa.max_remain_on_chan = 5000;
3863
991aa9c7
AO
3864 if (info->channel_switch_supported)
3865 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
3866
43245552 3867 return 0;
80bc75f1
JM
3868nla_put_failure:
3869 nlmsg_free(msg);
3870 return -1;
3871}
3872
3873
93d11400 3874static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
80bc75f1
JM
3875{
3876 struct wiphy_info_data info;
3877 if (wpa_driver_nl80211_get_info(drv, &info))
93d11400 3878 return -1;
e8b5e24e
JB
3879
3880 if (info.error)
3881 return -1;
3882
80bc75f1 3883 drv->has_capability = 1;
1b2a72e8
JM
3884 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
3885 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
3886 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
3887 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
291b6068
JM
3888 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
3889 WPA_DRIVER_AUTH_SHARED |
3890 WPA_DRIVER_AUTH_LEAP;
1b2a72e8 3891
871f4dd0 3892 drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
0194fedb 3893 drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
2fee890a 3894 drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
e1bd4e19 3895
354c903f
MB
3896 /*
3897 * As all cfg80211 drivers must support cases where the AP interface is
3898 * removed without the knowledge of wpa_supplicant/hostapd, e.g., in
3899 * case that the user space daemon has crashed, they must be able to
3900 * cleanup all stations and key entries in the AP tear down flow. Thus,
3901 * this flag can/should always be set for cfg80211 drivers.
3902 */
3903 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
3904
e5091674 3905 if (!info.device_ap_sme) {
e1bd4e19 3906 drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
0194fedb 3907
e5091674
JM
3908 /*
3909 * No AP SME is currently assumed to also indicate no AP MLME
3910 * in the driver/firmware.
3911 */
3912 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_MLME;
3913 }
3914
61cbe2ff 3915 drv->device_ap_sme = info.device_ap_sme;
39718852 3916 drv->poll_command_supported = info.poll_command_supported;
32ab4855 3917 drv->data_tx_status = info.data_tx_status;
429dd9af
JM
3918 if (info.set_qos_map_supported)
3919 drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
61cbe2ff 3920
a11241fa 3921 /*
73a3c6ff
FF
3922 * If poll command and tx status are supported, mac80211 is new enough
3923 * to have everything we need to not need monitor interfaces.
a11241fa 3924 */
73a3c6ff 3925 drv->use_monitor = !info.poll_command_supported || !info.data_tx_status;
a11241fa 3926
536062f2
JM
3927 if (drv->device_ap_sme && drv->use_monitor) {
3928 /*
3929 * Non-mac80211 drivers may not support monitor interface.
3930 * Make sure we do not get stuck with incorrect capability here
3931 * by explicitly testing this.
3932 */
3933 if (!info.monitor_supported) {
3934 wpa_printf(MSG_DEBUG, "nl80211: Disable use_monitor "
3935 "with device_ap_sme since no monitor mode "
3936 "support detected");
3937 drv->use_monitor = 0;
3938 }
3939 }
3940
a11241fa
JB
3941 /*
3942 * If we aren't going to use monitor interfaces, but the
3943 * driver doesn't support data TX status, we won't get TX
3944 * status for EAPOL frames.
3945 */
3946 if (!drv->use_monitor && !info.data_tx_status)
3947 drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
3948
93d11400 3949 return 0;
80bc75f1
JM
3950}
3951
3952
b088cf82
JM
3953#ifdef ANDROID
3954static int android_genl_ctrl_resolve(struct nl_handle *handle,
3955 const char *name)
3956{
3957 /*
3958 * Android ICS has very minimal genl_ctrl_resolve() implementation, so
3959 * need to work around that.
3960 */
3961 struct nl_cache *cache = NULL;
3962 struct genl_family *nl80211 = NULL;
3963 int id = -1;
3964
3965 if (genl_ctrl_alloc_cache(handle, &cache) < 0) {
3966 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
3967 "netlink cache");
3968 goto fail;
3969 }
3970
3971 nl80211 = genl_ctrl_search_by_name(cache, name);
3972 if (nl80211 == NULL)
3973 goto fail;
3974
3975 id = genl_family_get_id(nl80211);
3976
3977fail:
3978 if (nl80211)
3979 genl_family_put(nl80211);
3980 if (cache)
3981 nl_cache_free(cache);
3982
3983 return id;
3984}
3985#define genl_ctrl_resolve android_genl_ctrl_resolve
3986#endif /* ANDROID */
3987
3988
2a7b66f5
BG
3989static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
3990{
d6c9aab8
JB
3991 int ret;
3992
2a7b66f5
BG
3993 global->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
3994 if (global->nl_cb == NULL) {
3995 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
3996 "callbacks");
3997 return -1;
3998 }
3999
481234cf
JM
4000 global->nl = nl_create_handle(global->nl_cb, "nl");
4001 if (global->nl == NULL)
d6c9aab8 4002 goto err;
276e2d67 4003
481234cf 4004 global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211");
335d42b1 4005 if (global->nl80211_id < 0) {
276e2d67
BG
4006 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
4007 "found");
d6c9aab8 4008 goto err;
276e2d67
BG
4009 }
4010
481234cf
JM
4011 global->nl_event = nl_create_handle(global->nl_cb, "event");
4012 if (global->nl_event == NULL)
d6c9aab8 4013 goto err;
9fff9fdc 4014
d6c9aab8 4015 ret = nl_get_multicast_id(global, "nl80211", "scan");
97865538 4016 if (ret >= 0)
481234cf 4017 ret = nl_socket_add_membership(global->nl_event, ret);
97865538
JM
4018 if (ret < 0) {
4019 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
4020 "membership for scan events: %d (%s)",
4021 ret, strerror(-ret));
d6c9aab8 4022 goto err;
97865538 4023 }
c2a04078 4024
d6c9aab8 4025 ret = nl_get_multicast_id(global, "nl80211", "mlme");
c2a04078 4026 if (ret >= 0)
481234cf 4027 ret = nl_socket_add_membership(global->nl_event, ret);
c2a04078
JM
4028 if (ret < 0) {
4029 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
4030 "membership for mlme events: %d (%s)",
4031 ret, strerror(-ret));
d6c9aab8 4032 goto err;
c2a04078 4033 }
c2a04078 4034
d6c9aab8 4035 ret = nl_get_multicast_id(global, "nl80211", "regulatory");
33c5deb8 4036 if (ret >= 0)
481234cf 4037 ret = nl_socket_add_membership(global->nl_event, ret);
33c5deb8
JM
4038 if (ret < 0) {
4039 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
4040 "membership for regulatory events: %d (%s)",
4041 ret, strerror(-ret));
4042 /* Continue without regulatory events */
4043 }
4044
17b79e65
JM
4045 ret = nl_get_multicast_id(global, "nl80211", "vendor");
4046 if (ret >= 0)
4047 ret = nl_socket_add_membership(global->nl_event, ret);
4048 if (ret < 0) {
4049 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
4050 "membership for vendor events: %d (%s)",
4051 ret, strerror(-ret));
4052 /* Continue without vendor events */
4053 }
4054
d6c9aab8
JB
4055 nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
4056 no_seq_check, NULL);
4057 nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
4058 process_global_event, global);
4059
5f65e9f7
JB
4060 nl80211_register_eloop_read(&global->nl_event,
4061 wpa_driver_nl80211_event_receive,
4062 global->nl_cb);
d6c9aab8
JB
4063
4064 return 0;
4065
4066err:
4067 nl_destroy_handles(&global->nl_event);
4068 nl_destroy_handles(&global->nl);
4069 nl_cb_put(global->nl_cb);
671a5039 4070 global->nl_cb = NULL;
d6c9aab8
JB
4071 return -1;
4072}
4073
4074
4075static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv)
4076{
1afc986d
JB
4077 drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
4078 if (!drv->nl_cb) {
4079 wpa_printf(MSG_ERROR, "nl80211: Failed to alloc cb struct");
d6c9aab8 4080 return -1;
1afc986d
JB
4081 }
4082
4083 nl_cb_set(drv->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
4084 no_seq_check, NULL);
f06aedd9
JB
4085 nl_cb_set(drv->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
4086 process_drv_event, drv);
1afc986d 4087
9fff9fdc 4088 return 0;
9fff9fdc
JM
4089}
4090
4091
8401a6b0
JM
4092static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
4093{
8401a6b0 4094 wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
a63063b4
JM
4095 /*
4096 * This may be for any interface; use ifdown event to disable
4097 * interface.
4098 */
8401a6b0
JM
4099}
4100
4101
4102static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
4103{
4104 struct wpa_driver_nl80211_data *drv = ctx;
4105 wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
834ee56f 4106 if (i802_set_iface_flags(drv->first_bss, 1)) {
8401a6b0
JM
4107 wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
4108 "after rfkill unblock");
4109 return;
4110 }
a63063b4 4111 /* rtnetlink ifup handler will report interface as enabled */
8401a6b0
JM
4112}
4113
4114
32ab4855
JB
4115static void wpa_driver_nl80211_handle_eapol_tx_status(int sock,
4116 void *eloop_ctx,
4117 void *handle)
4118{
4119 struct wpa_driver_nl80211_data *drv = eloop_ctx;
4120 u8 data[2048];
4121 struct msghdr msg;
4122 struct iovec entry;
cad0f50e 4123 u8 control[512];
32ab4855
JB
4124 struct cmsghdr *cmsg;
4125 int res, found_ee = 0, found_wifi = 0, acked = 0;
4126 union wpa_event_data event;
4127
4128 memset(&msg, 0, sizeof(msg));
4129 msg.msg_iov = &entry;
4130 msg.msg_iovlen = 1;
4131 entry.iov_base = data;
4132 entry.iov_len = sizeof(data);
4133 msg.msg_control = &control;
4134 msg.msg_controllen = sizeof(control);
4135
4136 res = recvmsg(sock, &msg, MSG_ERRQUEUE);
4137 /* if error or not fitting 802.3 header, return */
4138 if (res < 14)
4139 return;
4140
4141 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
4142 {
4143 if (cmsg->cmsg_level == SOL_SOCKET &&
4144 cmsg->cmsg_type == SCM_WIFI_STATUS) {
4145 int *ack;
4146
4147 found_wifi = 1;
4148 ack = (void *)CMSG_DATA(cmsg);
4149 acked = *ack;
4150 }
4151
4152 if (cmsg->cmsg_level == SOL_PACKET &&
4153 cmsg->cmsg_type == PACKET_TX_TIMESTAMP) {
4154 struct sock_extended_err *err =
4155 (struct sock_extended_err *)CMSG_DATA(cmsg);
4156
4157 if (err->ee_origin == SO_EE_ORIGIN_TXSTATUS)
4158 found_ee = 1;
4159 }
4160 }
4161
4162 if (!found_ee || !found_wifi)
4163 return;
4164
4165 memset(&event, 0, sizeof(event));
4166 event.eapol_tx_status.dst = data;
4167 event.eapol_tx_status.data = data + 14;
4168 event.eapol_tx_status.data_len = res - 14;
4169 event.eapol_tx_status.ack = acked;
4170 wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
4171}
4172
4173
cc7a48d1
JB
4174static int nl80211_init_bss(struct i802_bss *bss)
4175{
4176 bss->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
4177 if (!bss->nl_cb)
4178 return -1;
4179
4180 nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
4181 no_seq_check, NULL);
4182 nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
4183 process_bss_event, bss);
4184
4185 return 0;
4186}
4187
4188
4189static void nl80211_destroy_bss(struct i802_bss *bss)
4190{
4191 nl_cb_put(bss->nl_cb);
4192 bss->nl_cb = NULL;
4193}
4194
4195
0d547d5f
JM
4196static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
4197 void *global_priv, int hostapd,
4198 const u8 *set_addr)
9fff9fdc 4199{
9fff9fdc 4200 struct wpa_driver_nl80211_data *drv;
8401a6b0 4201 struct rfkill_config *rcfg;
a2e40bb6 4202 struct i802_bss *bss;
9fff9fdc 4203
a5c696ad
JM
4204 if (global_priv == NULL)
4205 return NULL;
9fff9fdc
JM
4206 drv = os_zalloc(sizeof(*drv));
4207 if (drv == NULL)
4208 return NULL;
f2ed8023 4209 drv->global = global_priv;
9fff9fdc 4210 drv->ctx = ctx;
0d547d5f
JM
4211 drv->hostapd = !!hostapd;
4212 drv->eapol_sock = -1;
4213 drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
4214 drv->if_indices = drv->default_if_indices;
834ee56f
KP
4215
4216 drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
4217 if (!drv->first_bss) {
4218 os_free(drv);
4219 return NULL;
4220 }
4221 bss = drv->first_bss;
a2e40bb6 4222 bss->drv = drv;
a5e1eb20
SE
4223 bss->ctx = ctx;
4224
a2e40bb6 4225 os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
9fff9fdc
JM
4226 drv->monitor_ifidx = -1;
4227 drv->monitor_sock = -1;
d12dab4c 4228 drv->eapol_tx_sock = -1;
b1f625e0 4229 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
9fff9fdc 4230
ba2d0d7d 4231 if (wpa_driver_nl80211_init_nl(drv)) {
bbaf0837
JM
4232 os_free(drv);
4233 return NULL;
4234 }
9fff9fdc 4235
cc7a48d1
JB
4236 if (nl80211_init_bss(bss))
4237 goto failed;
4238
8401a6b0
JM
4239 rcfg = os_zalloc(sizeof(*rcfg));
4240 if (rcfg == NULL)
4241 goto failed;
4242 rcfg->ctx = drv;
4243 os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
4244 rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
4245 rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
4246 drv->rfkill = rfkill_init(rcfg);
52169389 4247 if (drv->rfkill == NULL) {
8401a6b0 4248 wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
52169389
JM
4249 os_free(rcfg);
4250 }
8401a6b0 4251
146fa9b3
JM
4252 if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0)
4253 drv->start_iface_up = 1;
4254
49b4b205 4255 if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1))
bbaf0837 4256 goto failed;
7524cfb1 4257
d12dab4c 4258 drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
32ab4855
JB
4259 if (drv->eapol_tx_sock < 0)
4260 goto failed;
4261
4262 if (drv->data_tx_status) {
4263 int enabled = 1;
4264
4265 if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
4266 &enabled, sizeof(enabled)) < 0) {
4267 wpa_printf(MSG_DEBUG,
4268 "nl80211: wifi status sockopt failed\n");
4269 drv->data_tx_status = 0;
a11241fa
JB
4270 if (!drv->use_monitor)
4271 drv->capa.flags &=
4272 ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
32ab4855
JB
4273 } else {
4274 eloop_register_read_sock(drv->eapol_tx_sock,
4275 wpa_driver_nl80211_handle_eapol_tx_status,
4276 drv, NULL);
4277 }
4278 }
f10bfc9a 4279
dac12351 4280 if (drv->global) {
c4bb8817 4281 dl_list_add(&drv->global->interfaces, &drv->list);
dac12351
BG
4282 drv->in_interface_list = 1;
4283 }
c4bb8817 4284
a2e40bb6 4285 return bss;
7524cfb1 4286
bbaf0837 4287failed:
dac12351 4288 wpa_driver_nl80211_deinit(bss);
7524cfb1
JM
4289 return NULL;
4290}
4291
4292
0d547d5f
JM
4293/**
4294 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
4295 * @ctx: context to be used when calling wpa_supplicant functions,
4296 * e.g., wpa_supplicant_event()
4297 * @ifname: interface name, e.g., wlan0
4298 * @global_priv: private driver global data from global_init()
4299 * Returns: Pointer to private data, %NULL on failure
4300 */
4301static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
4302 void *global_priv)
4303{
4304 return wpa_driver_nl80211_drv_init(ctx, ifname, global_priv, 0, NULL);
4305}
4306
4307
a11241fa 4308static int nl80211_register_frame(struct i802_bss *bss,
5582a5d1 4309 struct nl_handle *nl_handle,
bd94971e 4310 u16 type, const u8 *match, size_t match_len)
58f6fbe0 4311{
a11241fa 4312 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0
JM
4313 struct nl_msg *msg;
4314 int ret = -1;
880de885 4315 char buf[30];
58f6fbe0
JM
4316
4317 msg = nlmsg_alloc();
4318 if (!msg)
4319 return -1;
4320
880de885
JM
4321 buf[0] = '\0';
4322 wpa_snprintf_hex(buf, sizeof(buf), match, match_len);
4323 wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x nl_handle=%p match=%s",
4324 type, nl_handle, buf);
36488c05 4325
9fb04070 4326 nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION);
58f6fbe0 4327
f632e483 4328 if (nl80211_set_iface_id(msg, bss) < 0)
d3aaef80
DS
4329 goto nla_put_failure;
4330
bd94971e 4331 NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type);
58f6fbe0
JM
4332 NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
4333
d6c9aab8 4334 ret = send_and_recv(drv->global, nl_handle, msg, NULL, NULL);
58f6fbe0
JM
4335 msg = NULL;
4336 if (ret) {
5582a5d1
JB
4337 wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
4338 "failed (type=%u): ret=%d (%s)",
4339 type, ret, strerror(-ret));
4340 wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
58f6fbe0
JM
4341 match, match_len);
4342 goto nla_put_failure;
4343 }
4344 ret = 0;
4345nla_put_failure:
4346 nlmsg_free(msg);
4347 return ret;
4348}
4349
4350
a11241fa
JB
4351static int nl80211_alloc_mgmt_handle(struct i802_bss *bss)
4352{
4353 struct wpa_driver_nl80211_data *drv = bss->drv;
4354
481234cf 4355 if (bss->nl_mgmt) {
a11241fa 4356 wpa_printf(MSG_DEBUG, "nl80211: Mgmt reporting "
36488c05 4357 "already on! (nl_mgmt=%p)", bss->nl_mgmt);
a11241fa
JB
4358 return -1;
4359 }
4360
481234cf
JM
4361 bss->nl_mgmt = nl_create_handle(drv->nl_cb, "mgmt");
4362 if (bss->nl_mgmt == NULL)
a11241fa
JB
4363 return -1;
4364
a11241fa
JB
4365 return 0;
4366}
4367
4368
5f65e9f7
JB
4369static void nl80211_mgmt_handle_register_eloop(struct i802_bss *bss)
4370{
4371 nl80211_register_eloop_read(&bss->nl_mgmt,
4372 wpa_driver_nl80211_event_receive,
4373 bss->nl_cb);
4374}
4375
4376
a11241fa 4377static int nl80211_register_action_frame(struct i802_bss *bss,
bd94971e
JB
4378 const u8 *match, size_t match_len)
4379{
4380 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
481234cf 4381 return nl80211_register_frame(bss, bss->nl_mgmt,
5582a5d1 4382 type, match, match_len);
bd94971e
JB
4383}
4384
4385
a11241fa 4386static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
58f6fbe0 4387{
a11241fa 4388 struct wpa_driver_nl80211_data *drv = bss->drv;
6f06766e 4389 int ret = 0;
a11241fa
JB
4390
4391 if (nl80211_alloc_mgmt_handle(bss))
4392 return -1;
36488c05
JM
4393 wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
4394 "handle %p", bss->nl_mgmt);
a11241fa 4395
e8d1168b
JB
4396 if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
4397 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
4398
4399 /* register for any AUTH message */
4400 nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0);
4401 }
4402
56f5af48
JM
4403#ifdef CONFIG_INTERWORKING
4404 /* QoS Map Configure */
4405 if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
6f06766e 4406 ret = -1;
56f5af48 4407#endif /* CONFIG_INTERWORKING */
4fe9fa0d 4408#if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
046b26a2 4409 /* GAS Initial Request */
a11241fa 4410 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
6f06766e 4411 ret = -1;
046b26a2 4412 /* GAS Initial Response */
a11241fa 4413 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
6f06766e 4414 ret = -1;
18708aad 4415 /* GAS Comeback Request */
a11241fa 4416 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
6f06766e 4417 ret = -1;
18708aad 4418 /* GAS Comeback Response */
a11241fa 4419 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
6f06766e 4420 ret = -1;
c5a64e2d
JM
4421 /* Protected GAS Initial Request */
4422 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
4423 ret = -1;
4424 /* Protected GAS Initial Response */
4425 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
4426 ret = -1;
4427 /* Protected GAS Comeback Request */
4428 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
4429 ret = -1;
4430 /* Protected GAS Comeback Response */
4431 if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
4432 ret = -1;
4fe9fa0d
JM
4433#endif /* CONFIG_P2P || CONFIG_INTERWORKING */
4434#ifdef CONFIG_P2P
046b26a2 4435 /* P2P Public Action */
a11241fa 4436 if (nl80211_register_action_frame(bss,
046b26a2
JM
4437 (u8 *) "\x04\x09\x50\x6f\x9a\x09",
4438 6) < 0)
6f06766e 4439 ret = -1;
046b26a2 4440 /* P2P Action */
a11241fa 4441 if (nl80211_register_action_frame(bss,
046b26a2
JM
4442 (u8 *) "\x7f\x50\x6f\x9a\x09",
4443 5) < 0)
6f06766e 4444 ret = -1;
046b26a2 4445#endif /* CONFIG_P2P */
7d878ca7
JM
4446#ifdef CONFIG_IEEE80211W
4447 /* SA Query Response */
a11241fa 4448 if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
6f06766e 4449 ret = -1;
7d878ca7 4450#endif /* CONFIG_IEEE80211W */
35287637
AN
4451#ifdef CONFIG_TDLS
4452 if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
4453 /* TDLS Discovery Response */
aa543c0c 4454 if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
35287637 4455 0)
6f06766e 4456 ret = -1;
35287637
AN
4457 }
4458#endif /* CONFIG_TDLS */
046b26a2 4459
7b90c16a 4460 /* FT Action frames */
a11241fa 4461 if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
6f06766e 4462 ret = -1;
7b90c16a
JM
4463 else
4464 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
4465 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
4466
71269b37 4467 /* WNM - BSS Transition Management Request */
a11241fa 4468 if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
6f06766e 4469 ret = -1;
bd896433
JM
4470 /* WNM-Sleep Mode Response */
4471 if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
6f06766e 4472 ret = -1;
a11241fa 4473
95a3ea94
JM
4474#ifdef CONFIG_HS20
4475 /* WNM-Notification */
4476 if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x1a", 2) < 0)
4477 return -1;
4478#endif /* CONFIG_HS20 */
4479
5f65e9f7
JB
4480 nl80211_mgmt_handle_register_eloop(bss);
4481
6f06766e 4482 return ret;
a11241fa
JB
4483}
4484
4485
02bb32c3
JB
4486static int nl80211_register_spurious_class3(struct i802_bss *bss)
4487{
4488 struct wpa_driver_nl80211_data *drv = bss->drv;
4489 struct nl_msg *msg;
4490 int ret = -1;
4491
4492 msg = nlmsg_alloc();
4493 if (!msg)
4494 return -1;
4495
4496 nl80211_cmd(drv, msg, 0, NL80211_CMD_UNEXPECTED_FRAME);
4497
4498 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
4499
481234cf 4500 ret = send_and_recv(drv->global, bss->nl_mgmt, msg, NULL, NULL);
02bb32c3
JB
4501 msg = NULL;
4502 if (ret) {
4503 wpa_printf(MSG_DEBUG, "nl80211: Register spurious class3 "
4504 "failed: ret=%d (%s)",
4505 ret, strerror(-ret));
4506 goto nla_put_failure;
4507 }
4508 ret = 0;
4509nla_put_failure:
4510 nlmsg_free(msg);
4511 return ret;
4512}
4513
4514
a11241fa
JB
4515static int nl80211_mgmt_subscribe_ap(struct i802_bss *bss)
4516{
4517 static const int stypes[] = {
4518 WLAN_FC_STYPE_AUTH,
4519 WLAN_FC_STYPE_ASSOC_REQ,
4520 WLAN_FC_STYPE_REASSOC_REQ,
4521 WLAN_FC_STYPE_DISASSOC,
4522 WLAN_FC_STYPE_DEAUTH,
4523 WLAN_FC_STYPE_ACTION,
4524 WLAN_FC_STYPE_PROBE_REQ,
4525/* Beacon doesn't work as mac80211 doesn't currently allow
4526 * it, but it wouldn't really be the right thing anyway as
4527 * it isn't per interface ... maybe just dump the scan
4528 * results periodically for OLBC?
4529 */
0e80ea2c 4530 /* WLAN_FC_STYPE_BEACON, */
a11241fa
JB
4531 };
4532 unsigned int i;
4533
4534 if (nl80211_alloc_mgmt_handle(bss))
71269b37 4535 return -1;
36488c05
JM
4536 wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
4537 "handle %p", bss->nl_mgmt);
71269b37 4538
e7ecab4a 4539 for (i = 0; i < ARRAY_SIZE(stypes); i++) {
481234cf 4540 if (nl80211_register_frame(bss, bss->nl_mgmt,
a11241fa
JB
4541 (WLAN_FC_TYPE_MGMT << 2) |
4542 (stypes[i] << 4),
4543 NULL, 0) < 0) {
4544 goto out_err;
4545 }
4546 }
4547
02bb32c3
JB
4548 if (nl80211_register_spurious_class3(bss))
4549 goto out_err;
4550
e32ad281
JB
4551 if (nl80211_get_wiphy_data_ap(bss) == NULL)
4552 goto out_err;
4553
5f65e9f7 4554 nl80211_mgmt_handle_register_eloop(bss);
58f6fbe0 4555 return 0;
a11241fa
JB
4556
4557out_err:
a11241fa
JB
4558 nl_destroy_handles(&bss->nl_mgmt);
4559 return -1;
4560}
4561
4562
a6cc0602
JM
4563static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
4564{
4565 if (nl80211_alloc_mgmt_handle(bss))
4566 return -1;
4567 wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
4568 "handle %p (device SME)", bss->nl_mgmt);
4569
4570 if (nl80211_register_frame(bss, bss->nl_mgmt,
4571 (WLAN_FC_TYPE_MGMT << 2) |
4572 (WLAN_FC_STYPE_ACTION << 4),
4573 NULL, 0) < 0)
4574 goto out_err;
4575
5f65e9f7 4576 nl80211_mgmt_handle_register_eloop(bss);
a6cc0602
JM
4577 return 0;
4578
4579out_err:
a6cc0602
JM
4580 nl_destroy_handles(&bss->nl_mgmt);
4581 return -1;
4582}
4583
4584
36488c05 4585static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
a11241fa 4586{
481234cf 4587 if (bss->nl_mgmt == NULL)
a11241fa 4588 return;
36488c05
JM
4589 wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
4590 "(%s)", bss->nl_mgmt, reason);
5f65e9f7 4591 nl80211_destroy_eloop_handle(&bss->nl_mgmt);
e32ad281
JB
4592
4593 nl80211_put_wiphy_data_ap(bss);
58f6fbe0
JM
4594}
4595
4596
8401a6b0
JM
4597static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
4598{
4599 wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
4600}
4601
4602
eb4582f2
AS
4603static void nl80211_del_p2pdev(struct i802_bss *bss)
4604{
4605 struct wpa_driver_nl80211_data *drv = bss->drv;
4606 struct nl_msg *msg;
4607 int ret;
4608
4609 msg = nlmsg_alloc();
4610 if (!msg)
4611 return;
4612
4613 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
4614 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
4615
4616 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4617 msg = NULL;
4618
4619 wpa_printf(MSG_DEBUG, "nl80211: Delete P2P Device %s (0x%llx): %s",
4620 bss->ifname, (long long unsigned int) bss->wdev_id,
6cb4f11d 4621 strerror(-ret));
eb4582f2
AS
4622
4623nla_put_failure:
4624 nlmsg_free(msg);
4625}
4626
4627
eb4582f2 4628static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
f632e483
AS
4629{
4630 struct wpa_driver_nl80211_data *drv = bss->drv;
4631 struct nl_msg *msg;
4632 int ret = -1;
4633
f632e483
AS
4634 msg = nlmsg_alloc();
4635 if (!msg)
4636 return -1;
4637
eb4582f2
AS
4638 if (start)
4639 nl80211_cmd(drv, msg, 0, NL80211_CMD_START_P2P_DEVICE);
4640 else
4641 nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_P2P_DEVICE);
4642
f632e483
AS
4643 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
4644
4645 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4646 msg = NULL;
4647
eb4582f2
AS
4648 wpa_printf(MSG_DEBUG, "nl80211: %s P2P Device %s (0x%llx): %s",
4649 start ? "Start" : "Stop",
4650 bss->ifname, (long long unsigned int) bss->wdev_id,
6cb4f11d 4651 strerror(-ret));
eb4582f2 4652
f632e483
AS
4653nla_put_failure:
4654 nlmsg_free(msg);
4655 return ret;
4656}
f632e483
AS
4657
4658
91724d6f
AS
4659static int i802_set_iface_flags(struct i802_bss *bss, int up)
4660{
4661 enum nl80211_iftype nlmode;
4662
4663 nlmode = nl80211_get_ifmode(bss);
4664 if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
4665 return linux_set_iface_flags(bss->drv->global->ioctl_sock,
4666 bss->ifname, up);
4667 }
4668
4669 /* P2P Device has start/stop which is equivalent */
4670 return nl80211_set_p2pdev(bss, up);
4671}
4672
4673
362f781e 4674static int
0d547d5f 4675wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
49b4b205 4676 const u8 *set_addr, int first)
7524cfb1 4677{
834ee56f 4678 struct i802_bss *bss = drv->first_bss;
8401a6b0 4679 int send_rfkill_event = 0;
0d547d5f 4680 enum nl80211_iftype nlmode;
a2e40bb6
FF
4681
4682 drv->ifindex = if_nametoindex(bss->ifname);
f632e483
AS
4683 bss->ifindex = drv->ifindex;
4684 bss->wdev_id = drv->global->if_add_wdevid;
4685 bss->wdev_id_set = drv->global->if_add_wdevid_set;
4686
60b13c20
IP
4687 bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
4688 bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
f632e483
AS
4689 drv->global->if_add_wdevid_set = 0;
4690
4691 if (wpa_driver_nl80211_capa(drv))
4692 return -1;
a87c9d96 4693
5fbcb45d
AS
4694 wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
4695 bss->ifname, drv->phyname);
4696
0d547d5f
JM
4697 if (set_addr &&
4698 (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) ||
4699 linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
4700 set_addr)))
4701 return -1;
4702
49b4b205
JM
4703 if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
4704 drv->start_mode_ap = 1;
4705
0d547d5f
JM
4706 if (drv->hostapd)
4707 nlmode = NL80211_IFTYPE_AP;
4708 else if (bss->if_dynamic)
8e12685c 4709 nlmode = nl80211_get_ifmode(bss);
0d547d5f
JM
4710 else
4711 nlmode = NL80211_IFTYPE_STATION;
f632e483 4712
8e12685c 4713 if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
0d547d5f 4714 wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
8e12685c 4715 return -1;
a87c9d96
JM
4716 }
4717
8c06db70 4718 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
597b94f5 4719 nl80211_get_macaddr(bss);
f632e483 4720
8c06db70
MB
4721 if (!rfkill_is_blocked(drv->rfkill)) {
4722 int ret = i802_set_iface_flags(bss, 1);
4723 if (ret) {
8401a6b0
JM
4724 wpa_printf(MSG_ERROR, "nl80211: Could not set "
4725 "interface '%s' UP", bss->ifname);
8c06db70 4726 return ret;
8401a6b0 4727 }
8c06db70
MB
4728 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
4729 return ret;
4730 } else {
4731 wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
4732 "interface '%s' due to rfkill", bss->ifname);
4733 if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
4734 return 0;
4735 drv->if_disabled = 1;
4736 send_rfkill_event = 1;
362f781e 4737 }
3f5285e8 4738
0d547d5f
JM
4739 if (!drv->hostapd)
4740 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
4741 1, IF_OPER_DORMANT);
362f781e 4742
c81eff1a 4743 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
341eebee 4744 bss->addr))
2136f480 4745 return -1;
f2ed8023 4746
8401a6b0
JM
4747 if (send_rfkill_event) {
4748 eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
4749 drv, drv->ctx);
4750 }
4751
362f781e 4752 return 0;
3f5285e8
JM
4753}
4754
4755
8a27af5c
JM
4756static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
4757{
4758 struct nl_msg *msg;
4759
4760 msg = nlmsg_alloc();
4761 if (!msg)
4762 return -ENOMEM;
4763
08e55ebb
JM
4764 wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
4765 drv->ifindex);
9fb04070 4766 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_BEACON);
8a27af5c
JM
4767 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4768
4769 return send_and_recv_msgs(drv, msg, NULL, NULL);
4770 nla_put_failure:
5883168a 4771 nlmsg_free(msg);
8a27af5c
JM
4772 return -ENOBUFS;
4773}
8a27af5c
JM
4774
4775
3f5285e8 4776/**
7e5ba1b9 4777 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
9ebce9c5 4778 * @bss: Pointer to private nl80211 data from wpa_driver_nl80211_init()
3f5285e8
JM
4779 *
4780 * Shut down driver interface and processing of driver events. Free
4781 * private data buffer if one was allocated in wpa_driver_nl80211_init().
4782 */
9ebce9c5 4783static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
3f5285e8 4784{
a2e40bb6 4785 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 4786
873d0fcf 4787 bss->in_deinit = 1;
32ab4855
JB
4788 if (drv->data_tx_status)
4789 eloop_unregister_read_sock(drv->eapol_tx_sock);
d12dab4c
JB
4790 if (drv->eapol_tx_sock >= 0)
4791 close(drv->eapol_tx_sock);
f10bfc9a 4792
481234cf 4793 if (bss->nl_preq)
5582a5d1 4794 wpa_driver_nl80211_probe_req_report(bss, 0);
e17a2477 4795 if (bss->added_if_into_bridge) {
c81eff1a
BG
4796 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
4797 bss->ifname) < 0)
94627f6c
JM
4798 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
4799 "interface %s from bridge %s: %s",
e17a2477 4800 bss->ifname, bss->brname, strerror(errno));
94627f6c 4801 }
e17a2477 4802 if (bss->added_bridge) {
c81eff1a 4803 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
94627f6c
JM
4804 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
4805 "bridge %s: %s",
e17a2477 4806 bss->brname, strerror(errno));
94627f6c
JM
4807 }
4808
460456f8 4809 nl80211_remove_monitor_interface(drv);
8a27af5c 4810
b1f625e0 4811 if (is_ap_interface(drv->nlmode))
8a27af5c 4812 wpa_driver_nl80211_del_beacon(drv);
0915d02c 4813
bbaf0837
JM
4814 if (drv->eapol_sock >= 0) {
4815 eloop_unregister_read_sock(drv->eapol_sock);
4816 close(drv->eapol_sock);
4817 }
4818
4819 if (drv->if_indices != drv->default_if_indices)
4820 os_free(drv->if_indices);
3f5285e8 4821
b3af99d2 4822 if (drv->disabled_11b_rates)
4e5cb1a3
JM
4823 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
4824
36d84860
BG
4825 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
4826 IF_OPER_UP);
8401a6b0 4827 rfkill_deinit(drv->rfkill);
3f5285e8 4828
bbaf0837
JM
4829 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
4830
146fa9b3
JM
4831 if (!drv->start_iface_up)
4832 (void) i802_set_iface_flags(bss, 0);
8e12685c 4833 if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
49b4b205
JM
4834 if (!drv->hostapd || !drv->start_mode_ap)
4835 wpa_driver_nl80211_set_mode(bss,
4836 NL80211_IFTYPE_STATION);
b378c41f 4837 nl80211_mgmt_unsubscribe(bss, "deinit");
8e12685c
AS
4838 } else {
4839 nl80211_mgmt_unsubscribe(bss, "deinit");
eb4582f2 4840 nl80211_del_p2pdev(bss);
8e12685c 4841 }
1afc986d 4842 nl_cb_put(drv->nl_cb);
3f5285e8 4843
834ee56f 4844 nl80211_destroy_bss(drv->first_bss);
cc7a48d1 4845
3812464c
JM
4846 os_free(drv->filter_ssids);
4847
536fd62d
JM
4848 os_free(drv->auth_ie);
4849
dac12351 4850 if (drv->in_interface_list)
f2ed8023
JM
4851 dl_list_del(&drv->list);
4852
8cd6b7bc
JB
4853 os_free(drv->extended_capa);
4854 os_free(drv->extended_capa_mask);
834ee56f 4855 os_free(drv->first_bss);
3f5285e8
JM
4856 os_free(drv);
4857}
4858
4859
4860/**
4861 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
ad1e68e6 4862 * @eloop_ctx: Driver private data
3f5285e8
JM
4863 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
4864 *
4865 * This function can be used as registered timeout when starting a scan to
4866 * generate a scan completed event if the driver does not report this.
4867 */
4868static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
4869{
ad1e68e6 4870 struct wpa_driver_nl80211_data *drv = eloop_ctx;
b1f625e0 4871 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
834ee56f 4872 wpa_driver_nl80211_set_mode(drv->first_bss,
b1f625e0
EP
4873 drv->ap_scan_as_station);
4874 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
ad1e68e6 4875 }
3f5285e8
JM
4876 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
4877 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
4878}
4879
4880
95ac3bf4
JM
4881static struct nl_msg *
4882nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
d3aaef80 4883 struct wpa_driver_scan_params *params, u64 *wdev_id)
3f5285e8 4884{
95ac3bf4 4885 struct nl_msg *msg;
6a1063e0 4886 size_t i;
3f5285e8 4887
0e75527f 4888 msg = nlmsg_alloc();
f0494d0f 4889 if (!msg)
95ac3bf4 4890 return NULL;
3812464c 4891
95ac3bf4 4892 nl80211_cmd(drv, msg, 0, cmd);
0e75527f 4893
d3aaef80
DS
4894 if (!wdev_id)
4895 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4896 else
4897 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, *wdev_id);
3f5285e8 4898
f0494d0f 4899 if (params->num_ssids) {
8970bae8
JB
4900 struct nlattr *ssids;
4901
4902 ssids = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
f0494d0f 4903 if (ssids == NULL)
95ac3bf4 4904 goto fail;
f0494d0f
JM
4905 for (i = 0; i < params->num_ssids; i++) {
4906 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
4907 params->ssids[i].ssid,
4908 params->ssids[i].ssid_len);
8970bae8
JB
4909 if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
4910 params->ssids[i].ssid) < 0)
95ac3bf4 4911 goto fail;
f0494d0f 4912 }
8970bae8 4913 nla_nest_end(msg, ssids);
3f5285e8
JM
4914 }
4915
d173df52 4916 if (params->extra_ies) {
3b1c7bfd
JM
4917 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
4918 params->extra_ies, params->extra_ies_len);
95ac3bf4
JM
4919 if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
4920 params->extra_ies) < 0)
4921 goto fail;
d173df52
JM
4922 }
4923
d3a98225 4924 if (params->freqs) {
8970bae8
JB
4925 struct nlattr *freqs;
4926 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
f0494d0f 4927 if (freqs == NULL)
95ac3bf4 4928 goto fail;
9fad706c
JM
4929 for (i = 0; params->freqs[i]; i++) {
4930 wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
4931 "MHz", params->freqs[i]);
8970bae8 4932 if (nla_put_u32(msg, i + 1, params->freqs[i]) < 0)
95ac3bf4 4933 goto fail;
9fad706c 4934 }
8970bae8 4935 nla_nest_end(msg, freqs);
d3a98225
JM
4936 }
4937
95ac3bf4
JM
4938 os_free(drv->filter_ssids);
4939 drv->filter_ssids = params->filter_ssids;
4940 params->filter_ssids = NULL;
4941 drv->num_filter_ssids = params->num_filter_ssids;
4942
949938aa
JM
4943 if (params->only_new_results) {
4944 wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
4945 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS,
4946 NL80211_SCAN_FLAG_FLUSH);
4947 }
4948
95ac3bf4
JM
4949 return msg;
4950
4951fail:
d3aaef80 4952nla_put_failure:
95ac3bf4
JM
4953 nlmsg_free(msg);
4954 return NULL;
4955}
4956
4957
4958/**
4959 * wpa_driver_nl80211_scan - Request the driver to initiate scan
9ebce9c5 4960 * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
95ac3bf4
JM
4961 * @params: Scan parameters
4962 * Returns: 0 on success, -1 on failure
4963 */
9ebce9c5 4964static int wpa_driver_nl80211_scan(struct i802_bss *bss,
95ac3bf4
JM
4965 struct wpa_driver_scan_params *params)
4966{
95ac3bf4
JM
4967 struct wpa_driver_nl80211_data *drv = bss->drv;
4968 int ret = -1, timeout;
8970bae8 4969 struct nl_msg *msg = NULL;
95ac3bf4 4970
565110cd 4971 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
95ac3bf4
JM
4972 drv->scan_for_auth = 0;
4973
d3aaef80
DS
4974 msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params,
4975 bss->wdev_id_set ? &bss->wdev_id : NULL);
95ac3bf4
JM
4976 if (!msg)
4977 return -1;
4978
47185fc7 4979 if (params->p2p_probe) {
8970bae8
JB
4980 struct nlattr *rates;
4981
8a6a1e1b
JM
4982 wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
4983
8970bae8 4984 rates = nla_nest_start(msg, NL80211_ATTR_SCAN_SUPP_RATES);
f0494d0f
JM
4985 if (rates == NULL)
4986 goto nla_put_failure;
4987
47185fc7
RM
4988 /*
4989 * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
4990 * by masking out everything else apart from the OFDM rates 6,
4991 * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
4992 * rates are left enabled.
4993 */
8970bae8 4994 NLA_PUT(msg, NL80211_BAND_2GHZ, 8,
47185fc7 4995 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
8970bae8 4996 nla_nest_end(msg, rates);
970fa12e
RM
4997
4998 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
47185fc7
RM
4999 }
5000
0e75527f
JM
5001 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5002 msg = NULL;
5003 if (ret) {
5004 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
5005 "(%s)", ret, strerror(-ret));
04eff7d5 5006 if (drv->hostapd && is_ap_interface(drv->nlmode)) {
72e7fb3f
YP
5007 enum nl80211_iftype old_mode = drv->nlmode;
5008
ad1e68e6
JM
5009 /*
5010 * mac80211 does not allow scan requests in AP mode, so
5011 * try to do this in station mode.
5012 */
b1f625e0
EP
5013 if (wpa_driver_nl80211_set_mode(
5014 bss, NL80211_IFTYPE_STATION))
ad1e68e6
JM
5015 goto nla_put_failure;
5016
085b29f1 5017 if (wpa_driver_nl80211_scan(bss, params)) {
b1f625e0 5018 wpa_driver_nl80211_set_mode(bss, drv->nlmode);
ad1e68e6
JM
5019 goto nla_put_failure;
5020 }
5021
5022 /* Restore AP mode when processing scan results */
72e7fb3f 5023 drv->ap_scan_as_station = old_mode;
ad1e68e6
JM
5024 ret = 0;
5025 } else
5026 goto nla_put_failure;
3f5285e8
JM
5027 }
5028
a771c07d 5029 drv->scan_state = SCAN_REQUESTED;
3f5285e8
JM
5030 /* Not all drivers generate "scan completed" wireless event, so try to
5031 * read results after a timeout. */
0e75527f 5032 timeout = 10;
3f5285e8
JM
5033 if (drv->scan_complete_events) {
5034 /*
d173df52
JM
5035 * The driver seems to deliver events to notify when scan is
5036 * complete, so use longer timeout to avoid race conditions
5037 * with scanning and following association request.
3f5285e8
JM
5038 */
5039 timeout = 30;
5040 }
5041 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
5042 "seconds", ret, timeout);
5043 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
0e75527f
JM
5044 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
5045 drv, drv->ctx);
3f5285e8 5046
0e75527f 5047nla_put_failure:
0e75527f 5048 nlmsg_free(msg);
3f5285e8
JM
5049 return ret;
5050}
5051
5052
d21c63b9
LC
5053/**
5054 * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
5055 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
5056 * @params: Scan parameters
5057 * @interval: Interval between scan cycles in milliseconds
5058 * Returns: 0 on success, -1 on failure or if not supported
5059 */
5060static int wpa_driver_nl80211_sched_scan(void *priv,
5061 struct wpa_driver_scan_params *params,
5062 u32 interval)
5063{
5064 struct i802_bss *bss = priv;
5065 struct wpa_driver_nl80211_data *drv = bss->drv;
6afbc3d6 5066 int ret = -1;
95ac3bf4 5067 struct nl_msg *msg;
d21c63b9
LC
5068 size_t i;
5069
565110cd
JM
5070 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request");
5071
216eede8
DS
5072#ifdef ANDROID
5073 if (!drv->capa.sched_scan_supported)
5074 return android_pno_start(bss, params);
5075#endif /* ANDROID */
5076
d3aaef80
DS
5077 msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params,
5078 bss->wdev_id_set ? &bss->wdev_id : NULL);
6afbc3d6
JM
5079 if (!msg)
5080 goto nla_put_failure;
d21c63b9 5081
d21c63b9
LC
5082 NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
5083
bf8d6d24
TP
5084 if ((drv->num_filter_ssids &&
5085 (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
5086 params->filter_rssi) {
8970bae8
JB
5087 struct nlattr *match_sets;
5088 match_sets = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
6afbc3d6
JM
5089 if (match_sets == NULL)
5090 goto nla_put_failure;
bd525934
LC
5091
5092 for (i = 0; i < drv->num_filter_ssids; i++) {
8970bae8 5093 struct nlattr *match_set_ssid;
bd525934
LC
5094 wpa_hexdump_ascii(MSG_MSGDUMP,
5095 "nl80211: Sched scan filter SSID",
5096 drv->filter_ssids[i].ssid,
5097 drv->filter_ssids[i].ssid_len);
5098
8970bae8 5099 match_set_ssid = nla_nest_start(msg, i + 1);
6afbc3d6
JM
5100 if (match_set_ssid == NULL)
5101 goto nla_put_failure;
8970bae8 5102 NLA_PUT(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
bd525934
LC
5103 drv->filter_ssids[i].ssid_len,
5104 drv->filter_ssids[i].ssid);
ff5e1d14
JB
5105 if (params->filter_rssi)
5106 NLA_PUT_U32(msg,
5107 NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
5108 params->filter_rssi);
bd525934 5109
adc96dc2 5110 nla_nest_end(msg, match_set_ssid);
bd525934
LC
5111 }
5112
ff5e1d14
JB
5113 /*
5114 * Due to backward compatibility code, newer kernels treat this
5115 * matchset (with only an RSSI filter) as the default for all
5116 * other matchsets, unless it's the only one, in which case the
5117 * matchset will actually allow all SSIDs above the RSSI.
5118 */
bf8d6d24 5119 if (params->filter_rssi) {
8970bae8
JB
5120 struct nlattr *match_set_rssi;
5121 match_set_rssi = nla_nest_start(msg, 0);
6afbc3d6
JM
5122 if (match_set_rssi == NULL)
5123 goto nla_put_failure;
8970bae8 5124 NLA_PUT_U32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
bf8d6d24
TP
5125 params->filter_rssi);
5126 wpa_printf(MSG_MSGDUMP,
5127 "nl80211: Sched scan RSSI filter %d dBm",
5128 params->filter_rssi);
8970bae8 5129 nla_nest_end(msg, match_set_rssi);
bf8d6d24
TP
5130 }
5131
8970bae8 5132 nla_nest_end(msg, match_sets);
bd525934
LC
5133 }
5134
d21c63b9
LC
5135 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5136
5137 /* TODO: if we get an error here, we should fall back to normal scan */
5138
5139 msg = NULL;
5140 if (ret) {
5141 wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
5142 "ret=%d (%s)", ret, strerror(-ret));
5143 goto nla_put_failure;
5144 }
5145
5146 wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
5147 "scan interval %d msec", ret, interval);
5148
5149nla_put_failure:
d21c63b9 5150 nlmsg_free(msg);
d21c63b9
LC
5151 return ret;
5152}
5153
5154
5155/**
5156 * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
5157 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
5158 * Returns: 0 on success, -1 on failure or if not supported
5159 */
5160static int wpa_driver_nl80211_stop_sched_scan(void *priv)
5161{
5162 struct i802_bss *bss = priv;
5163 struct wpa_driver_nl80211_data *drv = bss->drv;
5164 int ret = 0;
5165 struct nl_msg *msg;
5166
216eede8
DS
5167#ifdef ANDROID
5168 if (!drv->capa.sched_scan_supported)
5169 return android_pno_stop(bss);
5170#endif /* ANDROID */
5171
d21c63b9
LC
5172 msg = nlmsg_alloc();
5173 if (!msg)
5174 return -1;
5175
9fb04070 5176 nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_SCHED_SCAN);
d21c63b9
LC
5177
5178 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5179
5180 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5181 msg = NULL;
5182 if (ret) {
5183 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop failed: "
5184 "ret=%d (%s)", ret, strerror(-ret));
5185 goto nla_put_failure;
5186 }
5187
5188 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop sent (ret=%d)", ret);
5189
5190nla_put_failure:
5191 nlmsg_free(msg);
5192 return ret;
5193}
5194
5195
3812464c
JM
5196static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
5197{
5198 const u8 *end, *pos;
5199
5200 if (ies == NULL)
5201 return NULL;
5202
5203 pos = ies;
5204 end = ies + ies_len;
5205
5206 while (pos + 1 < end) {
5207 if (pos + 2 + pos[1] > end)
5208 break;
5209 if (pos[0] == ie)
5210 return pos;
5211 pos += 2 + pos[1];
5212 }
5213
5214 return NULL;
5215}
5216
5217
5218static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
5219 const u8 *ie, size_t ie_len)
5220{
5221 const u8 *ssid;
5222 size_t i;
5223
5224 if (drv->filter_ssids == NULL)
5225 return 0;
5226
5227 ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
5228 if (ssid == NULL)
5229 return 1;
5230
5231 for (i = 0; i < drv->num_filter_ssids; i++) {
5232 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
5233 os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
5234 0)
5235 return 0;
5236 }
5237
5238 return 1;
5239}
5240
5241
b3db1e1c 5242static int bss_info_handler(struct nl_msg *msg, void *arg)
3f5285e8 5243{
b3db1e1c
JM
5244 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5245 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5246 struct nlattr *bss[NL80211_BSS_MAX + 1];
5247 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
5248 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
5249 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
5250 [NL80211_BSS_TSF] = { .type = NLA_U64 },
5251 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
5252 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
5253 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
5254 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
5255 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
e6b8efeb 5256 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
b3ad11bb 5257 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
8c090654 5258 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
b3db1e1c 5259 };
3812464c
JM
5260 struct nl80211_bss_info_arg *_arg = arg;
5261 struct wpa_scan_results *res = _arg->res;
3f5285e8
JM
5262 struct wpa_scan_res **tmp;
5263 struct wpa_scan_res *r;
8c090654
JM
5264 const u8 *ie, *beacon_ie;
5265 size_t ie_len, beacon_ie_len;
5266 u8 *pos;
46957a9b 5267 size_t i;
3f5285e8 5268
b3db1e1c
JM
5269 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5270 genlmsg_attrlen(gnlh, 0), NULL);
5271 if (!tb[NL80211_ATTR_BSS])
5272 return NL_SKIP;
5273 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
5274 bss_policy))
5275 return NL_SKIP;
f5a8d422
JM
5276 if (bss[NL80211_BSS_STATUS]) {
5277 enum nl80211_bss_status status;
5278 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
5279 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
5280 bss[NL80211_BSS_FREQUENCY]) {
5281 _arg->assoc_freq =
5282 nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
5283 wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
5284 _arg->assoc_freq);
5285 }
20f5a4c2
JM
5286 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
5287 bss[NL80211_BSS_BSSID]) {
5288 os_memcpy(_arg->assoc_bssid,
5289 nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN);
5290 wpa_printf(MSG_DEBUG, "nl80211: Associated with "
5291 MACSTR, MAC2STR(_arg->assoc_bssid));
5292 }
f5a8d422
JM
5293 }
5294 if (!res)
5295 return NL_SKIP;
b3db1e1c
JM
5296 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
5297 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
5298 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
5299 } else {
5300 ie = NULL;
5301 ie_len = 0;
5302 }
8c090654
JM
5303 if (bss[NL80211_BSS_BEACON_IES]) {
5304 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
5305 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
5306 } else {
5307 beacon_ie = NULL;
5308 beacon_ie_len = 0;
5309 }
3f5285e8 5310
3812464c
JM
5311 if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
5312 ie ? ie_len : beacon_ie_len))
5313 return NL_SKIP;
5314
8c090654 5315 r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
3f5285e8 5316 if (r == NULL)
b3db1e1c
JM
5317 return NL_SKIP;
5318 if (bss[NL80211_BSS_BSSID])
5319 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
5320 ETH_ALEN);
5321 if (bss[NL80211_BSS_FREQUENCY])
5322 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
5323 if (bss[NL80211_BSS_BEACON_INTERVAL])
5324 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
5325 if (bss[NL80211_BSS_CAPABILITY])
5326 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
7c2849d2
JM
5327 r->flags |= WPA_SCAN_NOISE_INVALID;
5328 if (bss[NL80211_BSS_SIGNAL_MBM]) {
b3db1e1c 5329 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
7c2849d2
JM
5330 r->level /= 100; /* mBm to dBm */
5331 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
5332 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
5333 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
98ac6763 5334 r->flags |= WPA_SCAN_QUAL_INVALID;
7c2849d2
JM
5335 } else
5336 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
b3db1e1c
JM
5337 if (bss[NL80211_BSS_TSF])
5338 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
b3ad11bb
JM
5339 if (bss[NL80211_BSS_SEEN_MS_AGO])
5340 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
b3db1e1c 5341 r->ie_len = ie_len;
8c090654
JM
5342 pos = (u8 *) (r + 1);
5343 if (ie) {
5344 os_memcpy(pos, ie, ie_len);
5345 pos += ie_len;
5346 }
5347 r->beacon_ie_len = beacon_ie_len;
5348 if (beacon_ie)
5349 os_memcpy(pos, beacon_ie, beacon_ie_len);
3f5285e8 5350
e6b8efeb
JM
5351 if (bss[NL80211_BSS_STATUS]) {
5352 enum nl80211_bss_status status;
5353 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
5354 switch (status) {
5355 case NL80211_BSS_STATUS_AUTHENTICATED:
5356 r->flags |= WPA_SCAN_AUTHENTICATED;
5357 break;
5358 case NL80211_BSS_STATUS_ASSOCIATED:
5359 r->flags |= WPA_SCAN_ASSOCIATED;
5360 break;
5361 default:
5362 break;
5363 }
5364 }
5365
46957a9b
JM
5366 /*
5367 * cfg80211 maintains separate BSS table entries for APs if the same
5368 * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
5369 * not use frequency as a separate key in the BSS table, so filter out
5370 * duplicated entries. Prefer associated BSS entry in such a case in
4ea6a471
JM
5371 * order to get the correct frequency into the BSS table. Similarly,
5372 * prefer newer entries over older.
46957a9b
JM
5373 */
5374 for (i = 0; i < res->num; i++) {
5375 const u8 *s1, *s2;
5376 if (os_memcmp(res->res[i]->bssid, r->bssid, ETH_ALEN) != 0)
5377 continue;
5378
5379 s1 = nl80211_get_ie((u8 *) (res->res[i] + 1),
5380 res->res[i]->ie_len, WLAN_EID_SSID);
5381 s2 = nl80211_get_ie((u8 *) (r + 1), r->ie_len, WLAN_EID_SSID);
5382 if (s1 == NULL || s2 == NULL || s1[1] != s2[1] ||
5383 os_memcmp(s1, s2, 2 + s1[1]) != 0)
5384 continue;
5385
5386 /* Same BSSID,SSID was already included in scan results */
5387 wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
5388 "for " MACSTR, MAC2STR(r->bssid));
5389
4ea6a471
JM
5390 if (((r->flags & WPA_SCAN_ASSOCIATED) &&
5391 !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) ||
5392 r->age < res->res[i]->age) {
46957a9b
JM
5393 os_free(res->res[i]);
5394 res->res[i] = r;
5395 } else
5396 os_free(r);
5397 return NL_SKIP;
5398 }
5399
067ffa26
JM
5400 tmp = os_realloc_array(res->res, res->num + 1,
5401 sizeof(struct wpa_scan_res *));
3f5285e8
JM
5402 if (tmp == NULL) {
5403 os_free(r);
b3db1e1c 5404 return NL_SKIP;
3f5285e8
JM
5405 }
5406 tmp[res->num++] = r;
5407 res->res = tmp;
b3db1e1c
JM
5408
5409 return NL_SKIP;
3f5285e8 5410}
b3db1e1c 5411
3f5285e8 5412
d72aad94
JM
5413static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
5414 const u8 *addr)
5415{
5416 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
5417 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
582507be 5418 "mismatch (" MACSTR ")", MAC2STR(addr));
d72aad94
JM
5419 wpa_driver_nl80211_mlme(drv, addr,
5420 NL80211_CMD_DEAUTHENTICATE,
77339912 5421 WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
d72aad94
JM
5422 }
5423}
5424
5425
e6b8efeb
JM
5426static void wpa_driver_nl80211_check_bss_status(
5427 struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
5428{
5429 size_t i;
5430
5431 for (i = 0; i < res->num; i++) {
5432 struct wpa_scan_res *r = res->res[i];
5433 if (r->flags & WPA_SCAN_AUTHENTICATED) {
5434 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
5435 "indicates BSS status with " MACSTR
5436 " as authenticated",
5437 MAC2STR(r->bssid));
b1f625e0 5438 if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
5439 os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
5440 os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
5441 0) {
5442 wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
5443 " in local state (auth=" MACSTR
5444 " assoc=" MACSTR ")",
5445 MAC2STR(drv->auth_bssid),
5446 MAC2STR(drv->bssid));
582507be 5447 clear_state_mismatch(drv, r->bssid);
e6b8efeb
JM
5448 }
5449 }
5450
5451 if (r->flags & WPA_SCAN_ASSOCIATED) {
5452 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
5453 "indicate BSS status with " MACSTR
5454 " as associated",
5455 MAC2STR(r->bssid));
b1f625e0 5456 if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
5457 !drv->associated) {
5458 wpa_printf(MSG_DEBUG, "nl80211: Local state "
5459 "(not associated) does not match "
5460 "with BSS state");
d72aad94 5461 clear_state_mismatch(drv, r->bssid);
b1f625e0 5462 } else if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
5463 os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
5464 0) {
5465 wpa_printf(MSG_DEBUG, "nl80211: Local state "
5466 "(associated with " MACSTR ") does "
5467 "not match with BSS state",
d72aad94
JM
5468 MAC2STR(drv->bssid));
5469 clear_state_mismatch(drv, r->bssid);
5470 clear_state_mismatch(drv, drv->bssid);
e6b8efeb
JM
5471 }
5472 }
5473 }
5474}
5475
5476
7e5ba1b9 5477static struct wpa_scan_results *
8856462d 5478nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
3f5285e8 5479{
b3db1e1c 5480 struct nl_msg *msg;
3f5285e8 5481 struct wpa_scan_results *res;
b3db1e1c 5482 int ret;
3812464c 5483 struct nl80211_bss_info_arg arg;
3f5285e8
JM
5484
5485 res = os_zalloc(sizeof(*res));
b3db1e1c 5486 if (res == NULL)
8e2c104f 5487 return NULL;
b3db1e1c
JM
5488 msg = nlmsg_alloc();
5489 if (!msg)
5490 goto nla_put_failure;
3f5285e8 5491
9fb04070 5492 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
834ee56f 5493 if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
fdc554b8 5494 goto nla_put_failure;
3f5285e8 5495
3812464c
JM
5496 arg.drv = drv;
5497 arg.res = res;
5498 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
b3db1e1c
JM
5499 msg = NULL;
5500 if (ret == 0) {
577db0ae
GM
5501 wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu "
5502 "BSSes)", (unsigned long) res->num);
5503 nl80211_get_noise_for_scan_results(drv, res);
b3db1e1c 5504 return res;
3f5285e8 5505 }
b3db1e1c
JM
5506 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
5507 "(%s)", ret, strerror(-ret));
5508nla_put_failure:
5509 nlmsg_free(msg);
5510 wpa_scan_results_free(res);
5511 return NULL;
3f5285e8
JM
5512}
5513
5514
8856462d
JM
5515/**
5516 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
5517 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
5518 * Returns: Scan results on success, -1 on failure
5519 */
5520static struct wpa_scan_results *
5521wpa_driver_nl80211_get_scan_results(void *priv)
5522{
a2e40bb6
FF
5523 struct i802_bss *bss = priv;
5524 struct wpa_driver_nl80211_data *drv = bss->drv;
8856462d
JM
5525 struct wpa_scan_results *res;
5526
5527 res = nl80211_get_scan_results(drv);
5528 if (res)
5529 wpa_driver_nl80211_check_bss_status(drv, res);
5530 return res;
5531}
5532
5533
5534static void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
5535{
5536 struct wpa_scan_results *res;
5537 size_t i;
5538
5539 res = nl80211_get_scan_results(drv);
5540 if (res == NULL) {
5541 wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
5542 return;
5543 }
5544
5545 wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
5546 for (i = 0; i < res->num; i++) {
5547 struct wpa_scan_res *r = res->res[i];
5548 wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s%s",
5549 (int) i, (int) res->num, MAC2STR(r->bssid),
5550 r->flags & WPA_SCAN_AUTHENTICATED ? " [auth]" : "",
5551 r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
5552 }
5553
5554 wpa_scan_results_free(res);
5555}
5556
5557
de4ed4a8
JM
5558static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
5559{
5560 switch (alg) {
5561 case WPA_ALG_WEP:
5562 if (key_len == 5)
5563 return WLAN_CIPHER_SUITE_WEP40;
5564 return WLAN_CIPHER_SUITE_WEP104;
5565 case WPA_ALG_TKIP:
5566 return WLAN_CIPHER_SUITE_TKIP;
5567 case WPA_ALG_CCMP:
5568 return WLAN_CIPHER_SUITE_CCMP;
5569 case WPA_ALG_GCMP:
5570 return WLAN_CIPHER_SUITE_GCMP;
5571 case WPA_ALG_CCMP_256:
5572 return WLAN_CIPHER_SUITE_CCMP_256;
5573 case WPA_ALG_GCMP_256:
5574 return WLAN_CIPHER_SUITE_GCMP_256;
5575 case WPA_ALG_IGTK:
5576 return WLAN_CIPHER_SUITE_AES_CMAC;
5577 case WPA_ALG_BIP_GMAC_128:
5578 return WLAN_CIPHER_SUITE_BIP_GMAC_128;
5579 case WPA_ALG_BIP_GMAC_256:
5580 return WLAN_CIPHER_SUITE_BIP_GMAC_256;
5581 case WPA_ALG_BIP_CMAC_256:
5582 return WLAN_CIPHER_SUITE_BIP_CMAC_256;
5583 case WPA_ALG_SMS4:
5584 return WLAN_CIPHER_SUITE_SMS4;
5585 case WPA_ALG_KRK:
5586 return WLAN_CIPHER_SUITE_KRK;
5587 case WPA_ALG_NONE:
5588 case WPA_ALG_PMK:
5589 wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
5590 alg);
5591 return 0;
5592 }
5593
5594 wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
5595 alg);
5596 return 0;
5597}
5598
5599
5600static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
5601{
5602 switch (cipher) {
5603 case WPA_CIPHER_CCMP_256:
5604 return WLAN_CIPHER_SUITE_CCMP_256;
5605 case WPA_CIPHER_GCMP_256:
5606 return WLAN_CIPHER_SUITE_GCMP_256;
5607 case WPA_CIPHER_CCMP:
5608 return WLAN_CIPHER_SUITE_CCMP;
5609 case WPA_CIPHER_GCMP:
5610 return WLAN_CIPHER_SUITE_GCMP;
5611 case WPA_CIPHER_TKIP:
5612 return WLAN_CIPHER_SUITE_TKIP;
5613 case WPA_CIPHER_WEP104:
5614 return WLAN_CIPHER_SUITE_WEP104;
5615 case WPA_CIPHER_WEP40:
5616 return WLAN_CIPHER_SUITE_WEP40;
ae6f9272
JM
5617 case WPA_CIPHER_GTK_NOT_USED:
5618 return WLAN_CIPHER_SUITE_NO_GROUP_ADDR;
de4ed4a8
JM
5619 }
5620
5621 return 0;
5622}
5623
5624
5625static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
5626 int max_suites)
5627{
5628 int num_suites = 0;
5629
5630 if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
5631 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP_256;
5632 if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
5633 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP_256;
5634 if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
5635 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
5636 if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
5637 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
5638 if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
5639 suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
5640 if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
5641 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
5642 if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
5643 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
5644
5645 return num_suites;
5646}
5647
5648
9ebce9c5 5649static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
71934751
JM
5650 enum wpa_alg alg, const u8 *addr,
5651 int key_idx, int set_tx,
642187d6
JM
5652 const u8 *seq, size_t seq_len,
5653 const u8 *key, size_t key_len)
3f5285e8 5654{
a2e40bb6 5655 struct wpa_driver_nl80211_data *drv = bss->drv;
e472e1b4 5656 int ifindex;
3f5285e8 5657 struct nl_msg *msg;
1ad1cdc2 5658 int ret;
dc01de8a 5659 int tdls = 0;
3f5285e8 5660
e472e1b4
AS
5661 /* Ignore for P2P Device */
5662 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
5663 return 0;
5664
5665 ifindex = if_nametoindex(ifname);
8393e1a0 5666 wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
1ad1cdc2 5667 "set_tx=%d seq_len=%lu key_len=%lu",
8393e1a0 5668 __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
3f5285e8 5669 (unsigned long) seq_len, (unsigned long) key_len);
8c66e185 5670#ifdef CONFIG_TDLS
dc01de8a 5671 if (key_idx == -1) {
8c66e185 5672 key_idx = 0;
dc01de8a
JM
5673 tdls = 1;
5674 }
8c66e185 5675#endif /* CONFIG_TDLS */
3f5285e8
JM
5676
5677 msg = nlmsg_alloc();
1ad1cdc2
JM
5678 if (!msg)
5679 return -ENOMEM;
3f5285e8
JM
5680
5681 if (alg == WPA_ALG_NONE) {
9fb04070 5682 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_KEY);
3f5285e8 5683 } else {
9fb04070 5684 nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_KEY);
3f5285e8 5685 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
e6ef73f1 5686 wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
de4ed4a8
JM
5687 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
5688 wpa_alg_to_cipher_suite(alg, key_len));
3f5285e8
JM
5689 }
5690
e6ef73f1 5691 if (seq && seq_len) {
1ad1cdc2 5692 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
e6ef73f1
JM
5693 wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
5694 }
1ad1cdc2 5695
0382097e 5696 if (addr && !is_broadcast_ether_addr(addr)) {
3f5285e8
JM
5697 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
5698 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
89c38e32
JM
5699
5700 if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
5701 wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK");
5702 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE,
5703 NL80211_KEYTYPE_GROUP);
5704 }
60ea8187 5705 } else if (addr && is_broadcast_ether_addr(addr)) {
8970bae8
JB
5706 struct nlattr *types;
5707
60ea8187 5708 wpa_printf(MSG_DEBUG, " broadcast key");
8970bae8
JB
5709
5710 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
60ea8187
JM
5711 if (!types)
5712 goto nla_put_failure;
8970bae8
JB
5713 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
5714 nla_nest_end(msg, types);
3f5285e8
JM
5715 }
5716 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1ad1cdc2 5717 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
3f5285e8 5718
1ad1cdc2 5719 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
15664ad0 5720 if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
1ad1cdc2
JM
5721 ret = 0;
5722 if (ret)
5723 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
5724 ret, strerror(-ret));
3f5285e8 5725
1ad1cdc2
JM
5726 /*
5727 * If we failed or don't need to set the default TX key (below),
5728 * we're done here.
5729 */
dc01de8a 5730 if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
1ad1cdc2 5731 return ret;
b1f625e0 5732 if (is_ap_interface(drv->nlmode) && addr &&
0382097e 5733 !is_broadcast_ether_addr(addr))
de12717a 5734 return ret;
3f5285e8 5735
1ad1cdc2
JM
5736 msg = nlmsg_alloc();
5737 if (!msg)
5738 return -ENOMEM;
3f5285e8 5739
9fb04070 5740 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_KEY);
1ad1cdc2
JM
5741 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
5742 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5743 if (alg == WPA_ALG_IGTK)
5744 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
5745 else
5746 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
60ea8187 5747 if (addr && is_broadcast_ether_addr(addr)) {
8970bae8
JB
5748 struct nlattr *types;
5749
5750 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
60ea8187
JM
5751 if (!types)
5752 goto nla_put_failure;
8970bae8
JB
5753 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
5754 nla_nest_end(msg, types);
60ea8187 5755 } else if (addr) {
8970bae8
JB
5756 struct nlattr *types;
5757
5758 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
60ea8187
JM
5759 if (!types)
5760 goto nla_put_failure;
8970bae8
JB
5761 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST);
5762 nla_nest_end(msg, types);
60ea8187 5763 }
3f5285e8 5764
1ad1cdc2
JM
5765 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5766 if (ret == -ENOENT)
5767 ret = 0;
5768 if (ret)
5769 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
5770 "err=%d %s)", ret, strerror(-ret));
5771 return ret;
3f5285e8
JM
5772
5773nla_put_failure:
5883168a 5774 nlmsg_free(msg);
6241fcb1 5775 return -ENOBUFS;
3f5285e8
JM
5776}
5777
5778
71934751 5779static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
0194fedb
JB
5780 int key_idx, int defkey,
5781 const u8 *seq, size_t seq_len,
5782 const u8 *key, size_t key_len)
5783{
5784 struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
5785 if (!key_attr)
5786 return -1;
5787
5788 if (defkey && alg == WPA_ALG_IGTK)
5789 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
5790 else if (defkey)
5791 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
5792
5793 NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
5794
de4ed4a8
JM
5795 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5796 wpa_alg_to_cipher_suite(alg, key_len));
0194fedb
JB
5797
5798 if (seq && seq_len)
5799 NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
5800
5801 NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
5802
5803 nla_nest_end(msg, key_attr);
5804
5805 return 0;
5806 nla_put_failure:
5807 return -1;
5808}
5809
c811d5bc 5810
cfaab580
ZY
5811static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
5812 struct nl_msg *msg)
5813{
5814 int i, privacy = 0;
5815 struct nlattr *nl_keys, *nl_key;
5816
5817 for (i = 0; i < 4; i++) {
5818 if (!params->wep_key[i])
5819 continue;
5820 privacy = 1;
5821 break;
5822 }
ce04af5a
JM
5823 if (params->wps == WPS_MODE_PRIVACY)
5824 privacy = 1;
5825 if (params->pairwise_suite &&
5826 params->pairwise_suite != WPA_CIPHER_NONE)
5827 privacy = 1;
5828
cfaab580
ZY
5829 if (!privacy)
5830 return 0;
5831
5832 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
5833
5834 nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
5835 if (!nl_keys)
5836 goto nla_put_failure;
5837
5838 for (i = 0; i < 4; i++) {
5839 if (!params->wep_key[i])
5840 continue;
5841
5842 nl_key = nla_nest_start(msg, i);
5843 if (!nl_key)
5844 goto nla_put_failure;
5845
5846 NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
5847 params->wep_key[i]);
5848 if (params->wep_key_len[i] == 5)
5849 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5850 WLAN_CIPHER_SUITE_WEP40);
5851 else
5852 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5853 WLAN_CIPHER_SUITE_WEP104);
5854
5855 NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
5856
5857 if (i == params->wep_tx_keyidx)
5858 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
5859
5860 nla_nest_end(msg, nl_key);
5861 }
5862 nla_nest_end(msg, nl_keys);
5863
5864 return 0;
5865
5866nla_put_failure:
5867 return -ENOBUFS;
5868}
5869
5870
c2a04078 5871static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
77339912
JM
5872 const u8 *addr, int cmd, u16 reason_code,
5873 int local_state_change)
c2a04078
JM
5874{
5875 int ret = -1;
5876 struct nl_msg *msg;
5877
5878 msg = nlmsg_alloc();
5879 if (!msg)
5880 return -1;
5881
9fb04070 5882 nl80211_cmd(drv, msg, 0, cmd);
c2a04078
JM
5883
5884 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5885 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
817762d9
MI
5886 if (addr)
5887 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
77339912
JM
5888 if (local_state_change)
5889 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
c2a04078
JM
5890
5891 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5892 msg = NULL;
5893 if (ret) {
3b7ea880
BG
5894 wpa_dbg(drv->ctx, MSG_DEBUG,
5895 "nl80211: MLME command failed: reason=%u ret=%d (%s)",
5896 reason_code, ret, strerror(-ret));
c2a04078
JM
5897 goto nla_put_failure;
5898 }
5899 ret = 0;
5900
5901nla_put_failure:
5902 nlmsg_free(msg);
5903 return ret;
5904}
3f5285e8
JM
5905
5906
cfaab580 5907static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
817762d9 5908 int reason_code)
cfaab580 5909{
3f53c006
JJ
5910 int ret;
5911
817762d9 5912 wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
add9b7a4 5913 nl80211_mark_disconnected(drv);
817762d9 5914 /* Disconnect command doesn't need BSSID - it uses cached value */
3f53c006
JJ
5915 ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
5916 reason_code, 0);
5917 /*
5918 * For locally generated disconnect, supplicant already generates a
5919 * DEAUTH event, so ignore the event from NL80211.
5920 */
5921 drv->ignore_next_local_disconnect = ret == 0;
5922
5923 return ret;
cfaab580
ZY
5924}
5925
5926
9ebce9c5
JM
5927static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
5928 const u8 *addr, int reason_code)
3f5285e8 5929{
a2e40bb6 5930 struct wpa_driver_nl80211_data *drv = bss->drv;
d6a36f39 5931 int ret;
9392c9be
AS
5932
5933 if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
5934 nl80211_mark_disconnected(drv);
5935 return nl80211_leave_ibss(drv);
5936 }
cfaab580 5937 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
817762d9 5938 return wpa_driver_nl80211_disconnect(drv, reason_code);
2e75a2b3
JM
5939 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
5940 __func__, MAC2STR(addr), reason_code);
add9b7a4 5941 nl80211_mark_disconnected(drv);
d6a36f39
JM
5942 ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
5943 reason_code, 0);
5944 /*
5945 * For locally generated deauthenticate, supplicant already generates a
5946 * DEAUTH event, so ignore the event from NL80211.
5947 */
5948 drv->ignore_next_local_deauth = ret == 0;
5949 return ret;
3f5285e8
JM
5950}
5951
5952
536fd62d
JM
5953static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
5954 struct wpa_driver_auth_params *params)
5955{
5956 int i;
5957
5958 drv->auth_freq = params->freq;
5959 drv->auth_alg = params->auth_alg;
5960 drv->auth_wep_tx_keyidx = params->wep_tx_keyidx;
5961 drv->auth_local_state_change = params->local_state_change;
5962 drv->auth_p2p = params->p2p;
5963
5964 if (params->bssid)
5965 os_memcpy(drv->auth_bssid_, params->bssid, ETH_ALEN);
5966 else
5967 os_memset(drv->auth_bssid_, 0, ETH_ALEN);
5968
5969 if (params->ssid) {
5970 os_memcpy(drv->auth_ssid, params->ssid, params->ssid_len);
5971 drv->auth_ssid_len = params->ssid_len;
5972 } else
5973 drv->auth_ssid_len = 0;
5974
5975
5976 os_free(drv->auth_ie);
5977 drv->auth_ie = NULL;
5978 drv->auth_ie_len = 0;
5979 if (params->ie) {
5980 drv->auth_ie = os_malloc(params->ie_len);
5981 if (drv->auth_ie) {
5982 os_memcpy(drv->auth_ie, params->ie, params->ie_len);
5983 drv->auth_ie_len = params->ie_len;
5984 }
5985 }
5986
5987 for (i = 0; i < 4; i++) {
5988 if (params->wep_key[i] && params->wep_key_len[i] &&
5989 params->wep_key_len[i] <= 16) {
5990 os_memcpy(drv->auth_wep_key[i], params->wep_key[i],
5991 params->wep_key_len[i]);
5992 drv->auth_wep_key_len[i] = params->wep_key_len[i];
5993 } else
5994 drv->auth_wep_key_len[i] = 0;
5995 }
5996}
5997
5998
c2a04078 5999static int wpa_driver_nl80211_authenticate(
9ebce9c5 6000 struct i802_bss *bss, struct wpa_driver_auth_params *params)
c2a04078 6001{
a2e40bb6 6002 struct wpa_driver_nl80211_data *drv = bss->drv;
a0b2f99b 6003 int ret = -1, i;
c2a04078
JM
6004 struct nl_msg *msg;
6005 enum nl80211_auth_type type;
2f4f73b1 6006 enum nl80211_iftype nlmode;
6d6f4bb8 6007 int count = 0;
536fd62d
JM
6008 int is_retry;
6009
6010 is_retry = drv->retry_auth;
6011 drv->retry_auth = 0;
e8d70a73 6012 drv->ignore_deauth_event = 0;
c2a04078 6013
add9b7a4 6014 nl80211_mark_disconnected(drv);
e6b8efeb 6015 os_memset(drv->auth_bssid, 0, ETH_ALEN);
add9b7a4
JM
6016 if (params->bssid)
6017 os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
6018 else
6019 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
af473088 6020 /* FIX: IBSS mode */
2f4f73b1
EP
6021 nlmode = params->p2p ?
6022 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
6023 if (drv->nlmode != nlmode &&
9ebce9c5 6024 wpa_driver_nl80211_set_mode(bss, nlmode) < 0)
4a867032
JM
6025 return -1;
6026
6d6f4bb8 6027retry:
c2a04078
JM
6028 msg = nlmsg_alloc();
6029 if (!msg)
6030 return -1;
6031
6032 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
6033 drv->ifindex);
a0b2f99b 6034
9fb04070 6035 nl80211_cmd(drv, msg, 0, NL80211_CMD_AUTHENTICATE);
0194fedb 6036
a0b2f99b
JM
6037 for (i = 0; i < 4; i++) {
6038 if (!params->wep_key[i])
6039 continue;
9ebce9c5 6040 wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
2ea2fcc7 6041 NULL, i,
a0b2f99b
JM
6042 i == params->wep_tx_keyidx, NULL, 0,
6043 params->wep_key[i],
6044 params->wep_key_len[i]);
0194fedb
JB
6045 if (params->wep_tx_keyidx != i)
6046 continue;
6047 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
6048 params->wep_key[i], params->wep_key_len[i])) {
6049 nlmsg_free(msg);
6050 return -1;
6051 }
a0b2f99b
JM
6052 }
6053
c2a04078
JM
6054 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
6055 if (params->bssid) {
6056 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
6057 MAC2STR(params->bssid));
6058 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
6059 }
6060 if (params->freq) {
6061 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
6062 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
6063 }
6064 if (params->ssid) {
6065 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
6066 params->ssid, params->ssid_len);
6067 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
6068 params->ssid);
6069 }
6070 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
6071 if (params->ie)
6072 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
569fed90
JM
6073 if (params->sae_data) {
6074 wpa_hexdump(MSG_DEBUG, " * SAE data", params->sae_data,
6075 params->sae_data_len);
6076 NLA_PUT(msg, NL80211_ATTR_SAE_DATA, params->sae_data_len,
6077 params->sae_data);
6078 }
abd9fafa 6079 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
c2a04078 6080 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
abd9fafa 6081 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
c2a04078 6082 type = NL80211_AUTHTYPE_SHARED_KEY;
abd9fafa 6083 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
c2a04078 6084 type = NL80211_AUTHTYPE_NETWORK_EAP;
abd9fafa 6085 else if (params->auth_alg & WPA_AUTH_ALG_FT)
c2a04078 6086 type = NL80211_AUTHTYPE_FT;
569fed90
JM
6087 else if (params->auth_alg & WPA_AUTH_ALG_SAE)
6088 type = NL80211_AUTHTYPE_SAE;
c2a04078
JM
6089 else
6090 goto nla_put_failure;
6091 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
6092 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
77339912
JM
6093 if (params->local_state_change) {
6094 wpa_printf(MSG_DEBUG, " * Local state change only");
6095 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
6096 }
c2a04078
JM
6097
6098 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6099 msg = NULL;
6100 if (ret) {
3b7ea880
BG
6101 wpa_dbg(drv->ctx, MSG_DEBUG,
6102 "nl80211: MLME command failed (auth): ret=%d (%s)",
6103 ret, strerror(-ret));
6d6f4bb8 6104 count++;
77339912
JM
6105 if (ret == -EALREADY && count == 1 && params->bssid &&
6106 !params->local_state_change) {
6d6f4bb8
JM
6107 /*
6108 * mac80211 does not currently accept new
6109 * authentication if we are already authenticated. As a
6110 * workaround, force deauthentication and try again.
6111 */
6112 wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
6113 "after forced deauthentication");
e8d70a73 6114 drv->ignore_deauth_event = 1;
6d6f4bb8 6115 wpa_driver_nl80211_deauthenticate(
5205c4f9 6116 bss, params->bssid,
6d6f4bb8
JM
6117 WLAN_REASON_PREV_AUTH_NOT_VALID);
6118 nlmsg_free(msg);
6119 goto retry;
6120 }
536fd62d
JM
6121
6122 if (ret == -ENOENT && params->freq && !is_retry) {
6123 /*
6124 * cfg80211 has likely expired the BSS entry even
6125 * though it was previously available in our internal
6126 * BSS table. To recover quickly, start a single
6127 * channel scan on the specified channel.
6128 */
6129 struct wpa_driver_scan_params scan;
6130 int freqs[2];
6131
6132 os_memset(&scan, 0, sizeof(scan));
6133 scan.num_ssids = 1;
6134 if (params->ssid) {
6135 scan.ssids[0].ssid = params->ssid;
6136 scan.ssids[0].ssid_len = params->ssid_len;
6137 }
6138 freqs[0] = params->freq;
6139 freqs[1] = 0;
6140 scan.freqs = freqs;
6141 wpa_printf(MSG_DEBUG, "nl80211: Trigger single "
6142 "channel scan to refresh cfg80211 BSS "
6143 "entry");
6144 ret = wpa_driver_nl80211_scan(bss, &scan);
6145 if (ret == 0) {
6146 nl80211_copy_auth_params(drv, params);
6147 drv->scan_for_auth = 1;
6148 }
8c3ba078
JM
6149 } else if (is_retry) {
6150 /*
6151 * Need to indicate this with an event since the return
6152 * value from the retry is not delivered to core code.
6153 */
6154 union wpa_event_data event;
6155 wpa_printf(MSG_DEBUG, "nl80211: Authentication retry "
6156 "failed");
6157 os_memset(&event, 0, sizeof(event));
6158 os_memcpy(event.timeout_event.addr, drv->auth_bssid_,
6159 ETH_ALEN);
6160 wpa_supplicant_event(drv->ctx, EVENT_AUTH_TIMED_OUT,
6161 &event);
536fd62d
JM
6162 }
6163
c2a04078
JM
6164 goto nla_put_failure;
6165 }
6166 ret = 0;
6167 wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
6168 "successfully");
6169
6170nla_put_failure:
6171 nlmsg_free(msg);
6172 return ret;
6173}
6174
6175
536fd62d
JM
6176static int wpa_driver_nl80211_authenticate_retry(
6177 struct wpa_driver_nl80211_data *drv)
6178{
6179 struct wpa_driver_auth_params params;
834ee56f 6180 struct i802_bss *bss = drv->first_bss;
536fd62d
JM
6181 int i;
6182
6183 wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
6184
6185 os_memset(&params, 0, sizeof(params));
6186 params.freq = drv->auth_freq;
6187 params.auth_alg = drv->auth_alg;
6188 params.wep_tx_keyidx = drv->auth_wep_tx_keyidx;
6189 params.local_state_change = drv->auth_local_state_change;
6190 params.p2p = drv->auth_p2p;
6191
6192 if (!is_zero_ether_addr(drv->auth_bssid_))
6193 params.bssid = drv->auth_bssid_;
6194
6195 if (drv->auth_ssid_len) {
6196 params.ssid = drv->auth_ssid;
6197 params.ssid_len = drv->auth_ssid_len;
6198 }
6199
6200 params.ie = drv->auth_ie;
6201 params.ie_len = drv->auth_ie_len;
6202
6203 for (i = 0; i < 4; i++) {
6204 if (drv->auth_wep_key_len[i]) {
6205 params.wep_key[i] = drv->auth_wep_key[i];
6206 params.wep_key_len[i] = drv->auth_wep_key_len[i];
6207 }
6208 }
6209
6210 drv->retry_auth = 1;
6211 return wpa_driver_nl80211_authenticate(bss, &params);
6212}
6213
6214
282d5590
JM
6215struct phy_info_arg {
6216 u16 *num_modes;
6217 struct hostapd_hw_modes *modes;
43245552 6218 int last_mode, last_chan_idx;
282d5590
JM
6219};
6220
e62a1d43
JM
6221static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
6222 struct nlattr *ampdu_factor,
6223 struct nlattr *ampdu_density,
6224 struct nlattr *mcs_set)
6225{
6226 if (capa)
6227 mode->ht_capab = nla_get_u16(capa);
6228
6229 if (ampdu_factor)
6230 mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
6231
6232 if (ampdu_density)
6233 mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
6234
6235 if (mcs_set && nla_len(mcs_set) >= 16) {
6236 u8 *mcs;
6237 mcs = nla_data(mcs_set);
6238 os_memcpy(mode->mcs_set, mcs, 16);
6239 }
6240}
6241
6242
6243static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
6244 struct nlattr *capa,
6245 struct nlattr *mcs_set)
6246{
6247 if (capa)
6248 mode->vht_capab = nla_get_u32(capa);
6249
6250 if (mcs_set && nla_len(mcs_set) >= 8) {
6251 u8 *mcs;
6252 mcs = nla_data(mcs_set);
6253 os_memcpy(mode->vht_mcs_set, mcs, 8);
6254 }
6255}
6256
6257
214a77b0
JM
6258static void phy_info_freq(struct hostapd_hw_modes *mode,
6259 struct hostapd_channel_data *chan,
6260 struct nlattr *tb_freq[])
6261{
e864c0ae 6262 u8 channel;
214a77b0
JM
6263 chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
6264 chan->flag = 0;
bbbacbf2 6265 chan->dfs_cac_ms = 0;
e864c0ae
JM
6266 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
6267 chan->chan = channel;
214a77b0
JM
6268
6269 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
6270 chan->flag |= HOSTAPD_CHAN_DISABLED;
9fcd300d
JM
6271 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
6272 chan->flag |= HOSTAPD_CHAN_PASSIVE_SCAN | HOSTAPD_CHAN_NO_IBSS;
214a77b0
JM
6273 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
6274 chan->flag |= HOSTAPD_CHAN_RADAR;
6275
fc96522e
SW
6276 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
6277 enum nl80211_dfs_state state =
6278 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
6279
6280 switch (state) {
6281 case NL80211_DFS_USABLE:
6282 chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
6283 break;
6284 case NL80211_DFS_AVAILABLE:
6285 chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
6286 break;
6287 case NL80211_DFS_UNAVAILABLE:
6288 chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
6289 break;
6290 }
6291 }
bbbacbf2
JD
6292
6293 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
6294 chan->dfs_cac_ms = nla_get_u32(
6295 tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
6296 }
214a77b0
JM
6297}
6298
6299
e62a1d43
JM
6300static int phy_info_freqs(struct phy_info_arg *phy_info,
6301 struct hostapd_hw_modes *mode, struct nlattr *tb)
282d5590 6302{
282d5590
JM
6303 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
6304 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
6305 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
9fcd300d 6306 [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
282d5590
JM
6307 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
6308 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
fc96522e 6309 [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
282d5590 6310 };
e62a1d43
JM
6311 int new_channels = 0;
6312 struct hostapd_channel_data *channel;
6313 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
6314 struct nlattr *nl_freq;
6315 int rem_freq, idx;
6316
6317 if (tb == NULL)
6318 return NL_OK;
6319
6320 nla_for_each_nested(nl_freq, tb, rem_freq) {
6321 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
6322 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
6323 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
6324 continue;
6325 new_channels++;
6326 }
6327
6328 channel = os_realloc_array(mode->channels,
6329 mode->num_channels + new_channels,
6330 sizeof(struct hostapd_channel_data));
6331 if (!channel)
6332 return NL_SKIP;
6333
6334 mode->channels = channel;
6335 mode->num_channels += new_channels;
6336
6337 idx = phy_info->last_chan_idx;
6338
6339 nla_for_each_nested(nl_freq, tb, rem_freq) {
6340 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
6341 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
6342 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
6343 continue;
214a77b0 6344 phy_info_freq(mode, &mode->channels[idx], tb_freq);
e62a1d43
JM
6345 idx++;
6346 }
6347 phy_info->last_chan_idx = idx;
6348
6349 return NL_OK;
6350}
6351
6352
6353static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
6354{
282d5590
JM
6355 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
6356 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
3cfcad1b
JM
6357 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
6358 { .type = NLA_FLAG },
282d5590 6359 };
e62a1d43 6360 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
282d5590 6361 struct nlattr *nl_rate;
e62a1d43
JM
6362 int rem_rate, idx;
6363
6364 if (tb == NULL)
6365 return NL_OK;
6366
6367 nla_for_each_nested(nl_rate, tb, rem_rate) {
6368 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
6369 nla_data(nl_rate), nla_len(nl_rate),
6370 rate_policy);
6371 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
6372 continue;
6373 mode->num_rates++;
6374 }
6375
6376 mode->rates = os_calloc(mode->num_rates, sizeof(int));
6377 if (!mode->rates)
6378 return NL_SKIP;
6379
6380 idx = 0;
6381
6382 nla_for_each_nested(nl_rate, tb, rem_rate) {
6383 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
6384 nla_data(nl_rate), nla_len(nl_rate),
6385 rate_policy);
6386 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
6387 continue;
6388 mode->rates[idx] = nla_get_u32(
6389 tb_rate[NL80211_BITRATE_ATTR_RATE]);
e62a1d43
JM
6390 idx++;
6391 }
6392
6393 return NL_OK;
6394}
6395
6396
6397static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
6398{
6399 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
282d5590 6400 struct hostapd_hw_modes *mode;
e62a1d43 6401 int ret;
282d5590 6402
3cfcad1b
JM
6403 if (phy_info->last_mode != nl_band->nla_type) {
6404 mode = os_realloc_array(phy_info->modes,
6405 *phy_info->num_modes + 1,
6406 sizeof(*mode));
6407 if (!mode)
6408 return NL_SKIP;
6409 phy_info->modes = mode;
6410
6411 mode = &phy_info->modes[*(phy_info->num_modes)];
6412 os_memset(mode, 0, sizeof(*mode));
6413 mode->mode = NUM_HOSTAPD_MODES;
c8ebeda4
MK
6414 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
6415 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
6416
6417 /*
6418 * Unsupported VHT MCS stream is defined as value 3, so the VHT
6419 * MCS RX/TX map must be initialized with 0xffff to mark all 8
6420 * possible streams as unsupported. This will be overridden if
6421 * driver advertises VHT support.
6422 */
6423 mode->vht_mcs_set[0] = 0xff;
6424 mode->vht_mcs_set[1] = 0xff;
6425 mode->vht_mcs_set[4] = 0xff;
6426 mode->vht_mcs_set[5] = 0xff;
6427
3cfcad1b
JM
6428 *(phy_info->num_modes) += 1;
6429 phy_info->last_mode = nl_band->nla_type;
6430 phy_info->last_chan_idx = 0;
6431 } else
6432 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
282d5590 6433
3cfcad1b
JM
6434 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
6435 nla_len(nl_band), NULL);
282d5590 6436
e62a1d43
JM
6437 phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
6438 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
6439 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
6440 tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
6441 phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
6442 tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
6443 ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
6444 if (ret != NL_OK)
6445 return ret;
6446 ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
6447 if (ret != NL_OK)
6448 return ret;
282d5590 6449
3cfcad1b
JM
6450 return NL_OK;
6451}
6452
6453
6454static int phy_info_handler(struct nl_msg *msg, void *arg)
6455{
6456 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
6457 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6458 struct phy_info_arg *phy_info = arg;
6459 struct nlattr *nl_band;
6460 int rem_band;
6461
6462 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6463 genlmsg_attrlen(gnlh, 0), NULL);
6464
6465 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
6466 return NL_SKIP;
6467
6468 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
6469 {
6470 int res = phy_info_band(phy_info, nl_band);
6471 if (res != NL_OK)
6472 return res;
6473 }
6474
282d5590
JM
6475 return NL_SKIP;
6476}
6477
3cfcad1b 6478
282d5590 6479static struct hostapd_hw_modes *
c30a4ab0
JB
6480wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
6481 u16 *num_modes)
282d5590
JM
6482{
6483 u16 m;
6484 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
6485 int i, mode11g_idx = -1;
6486
c30a4ab0
JB
6487 /* heuristic to set up modes */
6488 for (m = 0; m < *num_modes; m++) {
6489 if (!modes[m].num_channels)
6490 continue;
6491 if (modes[m].channels[0].freq < 4000) {
6492 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
6493 for (i = 0; i < modes[m].num_rates; i++) {
6494 if (modes[m].rates[i] > 200) {
6495 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
6496 break;
6497 }
6498 }
6499 } else if (modes[m].channels[0].freq > 50000)
6500 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
6501 else
6502 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
6503 }
6504
282d5590
JM
6505 /* If only 802.11g mode is included, use it to construct matching
6506 * 802.11b mode data. */
6507
6508 for (m = 0; m < *num_modes; m++) {
6509 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
6510 return modes; /* 802.11b already included */
6511 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
6512 mode11g_idx = m;
6513 }
6514
6515 if (mode11g_idx < 0)
6516 return modes; /* 2.4 GHz band not supported at all */
6517
067ffa26 6518 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
282d5590
JM
6519 if (nmodes == NULL)
6520 return modes; /* Could not add 802.11b mode */
6521
6522 mode = &nmodes[*num_modes];
6523 os_memset(mode, 0, sizeof(*mode));
6524 (*num_modes)++;
6525 modes = nmodes;
6526
6527 mode->mode = HOSTAPD_MODE_IEEE80211B;
6528
6529 mode11g = &modes[mode11g_idx];
6530 mode->num_channels = mode11g->num_channels;
6531 mode->channels = os_malloc(mode11g->num_channels *
6532 sizeof(struct hostapd_channel_data));
6533 if (mode->channels == NULL) {
6534 (*num_modes)--;
6535 return modes; /* Could not add 802.11b mode */
6536 }
6537 os_memcpy(mode->channels, mode11g->channels,
6538 mode11g->num_channels * sizeof(struct hostapd_channel_data));
6539
6540 mode->num_rates = 0;
fb7842aa 6541 mode->rates = os_malloc(4 * sizeof(int));
282d5590
JM
6542 if (mode->rates == NULL) {
6543 os_free(mode->channels);
6544 (*num_modes)--;
6545 return modes; /* Could not add 802.11b mode */
6546 }
6547
6548 for (i = 0; i < mode11g->num_rates; i++) {
fb7842aa
JM
6549 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
6550 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
282d5590
JM
6551 continue;
6552 mode->rates[mode->num_rates] = mode11g->rates[i];
6553 mode->num_rates++;
6554 if (mode->num_rates == 4)
6555 break;
6556 }
6557
6558 if (mode->num_rates == 0) {
6559 os_free(mode->channels);
6560 os_free(mode->rates);
6561 (*num_modes)--;
6562 return modes; /* No 802.11b rates */
6563 }
6564
6565 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
6566 "information");
6567
6568 return modes;
6569}
6570
6571
d8e66e80
JM
6572static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
6573 int end)
6574{
6575 int c;
6576
6577 for (c = 0; c < mode->num_channels; c++) {
6578 struct hostapd_channel_data *chan = &mode->channels[c];
6579 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
6580 chan->flag |= HOSTAPD_CHAN_HT40;
6581 }
6582}
6583
6584
6585static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
6586 int end)
6587{
6588 int c;
6589
6590 for (c = 0; c < mode->num_channels; c++) {
6591 struct hostapd_channel_data *chan = &mode->channels[c];
6592 if (!(chan->flag & HOSTAPD_CHAN_HT40))
6593 continue;
6594 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
6595 chan->flag |= HOSTAPD_CHAN_HT40MINUS;
6596 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
6597 chan->flag |= HOSTAPD_CHAN_HT40PLUS;
6598 }
6599}
6600
6601
35f3d3ed 6602static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
6651f1f9
HS
6603 struct phy_info_arg *results)
6604{
6651f1f9
HS
6605 u16 m;
6606
6651f1f9
HS
6607 for (m = 0; m < *results->num_modes; m++) {
6608 int c;
6609 struct hostapd_hw_modes *mode = &results->modes[m];
6610
6611 for (c = 0; c < mode->num_channels; c++) {
6612 struct hostapd_channel_data *chan = &mode->channels[c];
6613 if ((u32) chan->freq - 10 >= start &&
6614 (u32) chan->freq + 10 <= end)
6615 chan->max_tx_power = max_eirp;
6616 }
6617 }
6618}
6619
6620
35f3d3ed 6621static void nl80211_reg_rule_ht40(u32 start, u32 end,
d8e66e80
JM
6622 struct phy_info_arg *results)
6623{
d8e66e80
JM
6624 u16 m;
6625
d8e66e80
JM
6626 for (m = 0; m < *results->num_modes; m++) {
6627 if (!(results->modes[m].ht_capab &
6628 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6629 continue;
6630 nl80211_set_ht40_mode(&results->modes[m], start, end);
6631 }
6632}
6633
6634
6635static void nl80211_reg_rule_sec(struct nlattr *tb[],
6636 struct phy_info_arg *results)
6637{
6638 u32 start, end, max_bw;
6639 u16 m;
6640
6641 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6642 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
6643 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
6644 return;
6645
6646 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6647 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6648 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
6649
6650 if (max_bw < 20)
6651 return;
6652
6653 for (m = 0; m < *results->num_modes; m++) {
6654 if (!(results->modes[m].ht_capab &
6655 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6656 continue;
6657 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
6658 }
6659}
6660
6661
53cfad46
EP
6662static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
6663 int end)
6664{
6665 int c;
6666
6667 for (c = 0; c < mode->num_channels; c++) {
6668 struct hostapd_channel_data *chan = &mode->channels[c];
6669 if (chan->freq - 10 >= start && chan->freq + 70 <= end)
6670 chan->flag |= HOSTAPD_CHAN_VHT_10_70;
6671
6672 if (chan->freq - 30 >= start && chan->freq + 50 <= end)
6673 chan->flag |= HOSTAPD_CHAN_VHT_30_50;
6674
6675 if (chan->freq - 50 >= start && chan->freq + 30 <= end)
6676 chan->flag |= HOSTAPD_CHAN_VHT_50_30;
6677
6678 if (chan->freq - 70 >= start && chan->freq + 10 <= end)
6679 chan->flag |= HOSTAPD_CHAN_VHT_70_10;
6680 }
6681}
6682
6683
6684static void nl80211_reg_rule_vht(struct nlattr *tb[],
6685 struct phy_info_arg *results)
6686{
6687 u32 start, end, max_bw;
6688 u16 m;
6689
6690 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6691 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
6692 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
6693 return;
6694
6695 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6696 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6697 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
6698
6699 if (max_bw < 80)
6700 return;
6701
6702 for (m = 0; m < *results->num_modes; m++) {
6703 if (!(results->modes[m].ht_capab &
6704 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6705 continue;
6706 /* TODO: use a real VHT support indication */
6707 if (!results->modes[m].vht_capab)
6708 continue;
6709
6710 nl80211_set_vht_mode(&results->modes[m], start, end);
6711 }
6712}
6713
6714
1412beee
JD
6715static const char * dfs_domain_name(enum nl80211_dfs_regions region)
6716{
6717 switch (region) {
6718 case NL80211_DFS_UNSET:
6719 return "DFS-UNSET";
6720 case NL80211_DFS_FCC:
6721 return "DFS-FCC";
6722 case NL80211_DFS_ETSI:
6723 return "DFS-ETSI";
6724 case NL80211_DFS_JP:
6725 return "DFS-JP";
6726 default:
6727 return "DFS-invalid";
6728 }
6729}
6730
6731
d8e66e80
JM
6732static int nl80211_get_reg(struct nl_msg *msg, void *arg)
6733{
6734 struct phy_info_arg *results = arg;
6735 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
6736 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6737 struct nlattr *nl_rule;
6738 struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
6739 int rem_rule;
6740 static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
6741 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6742 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6743 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6744 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6745 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6746 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6747 };
6748
6749 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6750 genlmsg_attrlen(gnlh, 0), NULL);
6751 if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
6752 !tb_msg[NL80211_ATTR_REG_RULES]) {
6753 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
6754 "available");
6755 return NL_SKIP;
6756 }
6757
1412beee
JD
6758 if (tb_msg[NL80211_ATTR_DFS_REGION]) {
6759 enum nl80211_dfs_regions dfs_domain;
6760 dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
6761 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
6762 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
6763 dfs_domain_name(dfs_domain));
6764 } else {
6765 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
6766 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
6767 }
d8e66e80
JM
6768
6769 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6770 {
bfb79dde 6771 u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
d8e66e80
JM
6772 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6773 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
35f3d3ed
JM
6774 if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6775 tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
6776 continue;
6777 start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6778 end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6779 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6780 max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
6781 if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6782 max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
bfb79dde
JM
6783 if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
6784 flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
6785
6786 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
6787 start, end, max_bw, max_eirp,
6788 flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
6789 flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
6790 flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
6791 flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
6792 "",
6793 flags & NL80211_RRF_DFS ? " (DFS)" : "",
6794 flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
6795 flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
6796 flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
35f3d3ed
JM
6797 if (max_bw >= 40)
6798 nl80211_reg_rule_ht40(start, end, results);
6799 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6800 nl80211_reg_rule_max_eirp(start, end, max_eirp,
6801 results);
d8e66e80
JM
6802 }
6803
6804 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6805 {
6806 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6807 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
6808 nl80211_reg_rule_sec(tb_rule, results);
6809 }
6810
53cfad46
EP
6811 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6812 {
6813 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6814 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
6815 nl80211_reg_rule_vht(tb_rule, results);
6816 }
6817
d8e66e80
JM
6818 return NL_SKIP;
6819}
6820
6821
53cfad46
EP
6822static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
6823 struct phy_info_arg *results)
d8e66e80
JM
6824{
6825 struct nl_msg *msg;
6826
6827 msg = nlmsg_alloc();
6828 if (!msg)
6829 return -ENOMEM;
6830
9fb04070 6831 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
d8e66e80
JM
6832 return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
6833}
6834
6835
282d5590
JM
6836static struct hostapd_hw_modes *
6837wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
6838{
43245552 6839 u32 feat;
a2e40bb6
FF
6840 struct i802_bss *bss = priv;
6841 struct wpa_driver_nl80211_data *drv = bss->drv;
282d5590
JM
6842 struct nl_msg *msg;
6843 struct phy_info_arg result = {
6844 .num_modes = num_modes,
6845 .modes = NULL,
43245552 6846 .last_mode = -1,
282d5590
JM
6847 };
6848
6849 *num_modes = 0;
6850 *flags = 0;
6851
6852 msg = nlmsg_alloc();
6853 if (!msg)
6854 return NULL;
6855
43245552
DJ
6856 feat = get_nl80211_protocol_features(drv);
6857 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
6858 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_WIPHY);
6859 else
6860 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
282d5590 6861
43245552 6862 NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
be24917d
IP
6863 if (nl80211_set_iface_id(msg, bss) < 0)
6864 goto nla_put_failure;
282d5590 6865
d8e66e80 6866 if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
53cfad46 6867 nl80211_set_regulatory_flags(drv, &result);
c30a4ab0
JB
6868 return wpa_driver_nl80211_postprocess_modes(result.modes,
6869 num_modes);
d8e66e80 6870 }
5883168a 6871 msg = NULL;
282d5590 6872 nla_put_failure:
5883168a 6873 nlmsg_free(msg);
282d5590
JM
6874 return NULL;
6875}
6876
6877
a11241fa
JB
6878static int wpa_driver_nl80211_send_mntr(struct wpa_driver_nl80211_data *drv,
6879 const void *data, size_t len,
6880 int encrypt, int noack)
2c2010ac
JM
6881{
6882 __u8 rtap_hdr[] = {
6883 0x00, 0x00, /* radiotap version */
6884 0x0e, 0x00, /* radiotap length */
6885 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
6886 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
6887 0x00, /* padding */
6888 0x00, 0x00, /* RX and TX flags to indicate that */
6889 0x00, 0x00, /* this is the injected frame directly */
6890 };
6891 struct iovec iov[2] = {
6892 {
6893 .iov_base = &rtap_hdr,
6894 .iov_len = sizeof(rtap_hdr),
6895 },
6896 {
6897 .iov_base = (void *) data,
6898 .iov_len = len,
6899 }
6900 };
6901 struct msghdr msg = {
6902 .msg_name = NULL,
6903 .msg_namelen = 0,
6904 .msg_iov = iov,
6905 .msg_iovlen = 2,
6906 .msg_control = NULL,
6907 .msg_controllen = 0,
6908 .msg_flags = 0,
6909 };
ebbec8b2 6910 int res;
fab25336 6911 u16 txflags = 0;
2c2010ac
JM
6912
6913 if (encrypt)
6914 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
6915
866af8b6
JM
6916 if (drv->monitor_sock < 0) {
6917 wpa_printf(MSG_DEBUG, "nl80211: No monitor socket available "
6918 "for %s", __func__);
6919 return -1;
6920 }
6921
fab25336
HS
6922 if (noack)
6923 txflags |= IEEE80211_RADIOTAP_F_TX_NOACK;
9d7a63dc 6924 WPA_PUT_LE16(&rtap_hdr[12], txflags);
fab25336 6925
ebbec8b2
JM
6926 res = sendmsg(drv->monitor_sock, &msg, 0);
6927 if (res < 0) {
6928 wpa_printf(MSG_INFO, "nl80211: sendmsg: %s", strerror(errno));
6929 return -1;
6930 }
6931 return 0;
2c2010ac
JM
6932}
6933
6934
a11241fa
JB
6935static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
6936 const void *data, size_t len,
55231068
JM
6937 int encrypt, int noack,
6938 unsigned int freq, int no_cck,
6939 int offchanok, unsigned int wait_time)
a11241fa
JB
6940{
6941 struct wpa_driver_nl80211_data *drv = bss->drv;
6942 u64 cookie;
41cc50d1 6943 int res;
a11241fa 6944
af964484
JM
6945 if (freq == 0) {
6946 wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
6947 bss->freq);
55231068 6948 freq = bss->freq;
af964484 6949 }
55231068 6950
739faee2
JM
6951 if (drv->use_monitor) {
6952 wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_mntr",
6953 freq, bss->freq);
a11241fa
JB
6954 return wpa_driver_nl80211_send_mntr(drv, data, len,
6955 encrypt, noack);
739faee2 6956 }
a11241fa 6957
739faee2 6958 wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
41cc50d1
JM
6959 res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
6960 &cookie, no_cck, noack, offchanok);
6961 if (res == 0 && !noack) {
6962 const struct ieee80211_mgmt *mgmt;
6963 u16 fc;
6964
6965 mgmt = (const struct ieee80211_mgmt *) data;
6966 fc = le_to_host16(mgmt->frame_control);
6967 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
6968 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
6969 wpa_printf(MSG_MSGDUMP,
6970 "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
6971 (long long unsigned int)
6972 drv->send_action_cookie,
6973 (long long unsigned int) cookie);
6974 drv->send_action_cookie = cookie;
6975 }
6976 }
6977
6978 return res;
a11241fa
JB
6979}
6980
6981
9ebce9c5
JM
6982static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
6983 size_t data_len, int noack,
6984 unsigned int freq, int no_cck,
6985 int offchanok,
6986 unsigned int wait_time)
2c2010ac 6987{
a2e40bb6 6988 struct wpa_driver_nl80211_data *drv = bss->drv;
2c2010ac 6989 struct ieee80211_mgmt *mgmt;
7a47d567 6990 int encrypt = 1;
2c2010ac
JM
6991 u16 fc;
6992
6993 mgmt = (struct ieee80211_mgmt *) data;
6994 fc = le_to_host16(mgmt->frame_control);
af964484
JM
6995 wpa_printf(MSG_DEBUG, "nl80211: send_mlme - noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x nlmode=%d",
6996 noack, freq, no_cck, offchanok, wait_time, fc, drv->nlmode);
2c2010ac 6997
8e12685c
AS
6998 if ((is_sta_interface(drv->nlmode) ||
6999 drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
5582a5d1
JB
7000 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
7001 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
7002 /*
7003 * The use of last_mgmt_freq is a bit of a hack,
7004 * but it works due to the single-threaded nature
7005 * of wpa_supplicant.
7006 */
af964484
JM
7007 if (freq == 0) {
7008 wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
7009 drv->last_mgmt_freq);
55231068 7010 freq = drv->last_mgmt_freq;
af964484 7011 }
55231068 7012 return nl80211_send_frame_cmd(bss, freq, 0,
88df0ef7
JB
7013 data, data_len, NULL, 1, noack,
7014 1);
5582a5d1
JB
7015 }
7016
61cbe2ff 7017 if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
af964484
JM
7018 if (freq == 0) {
7019 wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
7020 bss->freq);
55231068 7021 freq = bss->freq;
af964484 7022 }
b5671498
JM
7023 return nl80211_send_frame_cmd(bss, freq,
7024 (int) freq == bss->freq ? 0 :
7025 wait_time,
d8d6b32e
DG
7026 data, data_len,
7027 &drv->send_action_cookie,
55231068 7028 no_cck, noack, offchanok);
86957e62
JM
7029 }
7030
2c2010ac
JM
7031 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
7032 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
7033 /*
7034 * Only one of the authentication frame types is encrypted.
7035 * In order for static WEP encryption to work properly (i.e.,
7036 * to not encrypt the frame), we need to tell mac80211 about
7037 * the frames that must not be encrypted.
7038 */
7039 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
7040 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
7a47d567
JB
7041 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
7042 encrypt = 0;
2c2010ac
JM
7043 }
7044
739faee2 7045 wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
a11241fa 7046 return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
55231068
JM
7047 noack, freq, no_cck, offchanok,
7048 wait_time);
7049}
7050
7051
31357268 7052static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
e5693c47
JM
7053 int slot, int ht_opmode, int ap_isolate,
7054 int *basic_rates)
31357268
JM
7055{
7056 struct wpa_driver_nl80211_data *drv = bss->drv;
7057 struct nl_msg *msg;
7058
7059 msg = nlmsg_alloc();
7060 if (!msg)
7061 return -ENOMEM;
7062
9fb04070 7063 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_BSS);
31357268
JM
7064
7065 if (cts >= 0)
7066 NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
7067 if (preamble >= 0)
7068 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
7069 if (slot >= 0)
7070 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
7071 if (ht_opmode >= 0)
7072 NLA_PUT_U16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode);
d03e8d11
JM
7073 if (ap_isolate >= 0)
7074 NLA_PUT_U8(msg, NL80211_ATTR_AP_ISOLATE, ap_isolate);
e5693c47
JM
7075
7076 if (basic_rates) {
7077 u8 rates[NL80211_MAX_SUPP_RATES];
7078 u8 rates_len = 0;
7079 int i;
7080
7081 for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0;
7082 i++)
7083 rates[rates_len++] = basic_rates[i] / 5;
7084
7085 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
7086 }
7087
31357268
JM
7088 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
7089
7090 return send_and_recv_msgs(drv, msg, NULL, NULL);
7091 nla_put_failure:
5883168a 7092 nlmsg_free(msg);
31357268
JM
7093 return -ENOBUFS;
7094}
7095
7096
3c4ca363
VN
7097static int wpa_driver_nl80211_set_acl(void *priv,
7098 struct hostapd_acl_params *params)
7099{
7100 struct i802_bss *bss = priv;
7101 struct wpa_driver_nl80211_data *drv = bss->drv;
7102 struct nl_msg *msg;
7103 struct nlattr *acl;
7104 unsigned int i;
7105 int ret = 0;
7106
7107 if (!(drv->capa.max_acl_mac_addrs))
7108 return -ENOTSUP;
7109
7110 if (params->num_mac_acl > drv->capa.max_acl_mac_addrs)
7111 return -ENOTSUP;
7112
7113 msg = nlmsg_alloc();
7114 if (!msg)
7115 return -ENOMEM;
7116
7117 wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
7118 params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
7119
7120 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_MAC_ACL);
7121
7122 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7123
7124 NLA_PUT_U32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
7125 NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
7126 NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED);
7127
7128 acl = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
7129 if (acl == NULL)
7130 goto nla_put_failure;
7131
7132 for (i = 0; i < params->num_mac_acl; i++)
7133 NLA_PUT(msg, i + 1, ETH_ALEN, params->mac_acl[i].addr);
7134
7135 nla_nest_end(msg, acl);
7136
7137 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7138 msg = NULL;
7139 if (ret) {
7140 wpa_printf(MSG_DEBUG, "nl80211: Failed to set MAC ACL: %d (%s)",
7141 ret, strerror(-ret));
7142 }
7143
7144nla_put_failure:
7145 nlmsg_free(msg);
7146
7147 return ret;
7148}
7149
7150
19c3b566
JM
7151static int wpa_driver_nl80211_set_ap(void *priv,
7152 struct wpa_driver_ap_params *params)
d2440ba0 7153{
a2e40bb6
FF
7154 struct i802_bss *bss = priv;
7155 struct wpa_driver_nl80211_data *drv = bss->drv;
d2440ba0
JM
7156 struct nl_msg *msg;
7157 u8 cmd = NL80211_CMD_NEW_BEACON;
7158 int ret;
b4fd6fab 7159 int beacon_set;
8b897f5a 7160 int ifindex = if_nametoindex(bss->ifname);
b11d1d64 7161 int num_suites;
de4ed4a8 7162 u32 suites[10], suite;
b11d1d64 7163 u32 ver;
b4fd6fab 7164
b4fd6fab 7165 beacon_set = bss->beacon_set;
d2440ba0
JM
7166
7167 msg = nlmsg_alloc();
7168 if (!msg)
7169 return -ENOMEM;
7170
7171 wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
b4fd6fab
JM
7172 beacon_set);
7173 if (beacon_set)
d2440ba0
JM
7174 cmd = NL80211_CMD_SET_BEACON;
7175
9fb04070 7176 nl80211_cmd(drv, msg, 0, cmd);
b92e08fc
JM
7177 wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
7178 params->head, params->head_len);
19c3b566 7179 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, params->head_len, params->head);
b92e08fc
JM
7180 wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
7181 params->tail, params->tail_len);
19c3b566 7182 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len, params->tail);
b92e08fc 7183 wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", ifindex);
b4fd6fab 7184 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
b92e08fc 7185 wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
19c3b566 7186 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
b92e08fc 7187 wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
19c3b566 7188 NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
b92e08fc
JM
7189 wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
7190 params->ssid, params->ssid_len);
ccb941e6
JM
7191 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
7192 params->ssid);
b92e08fc
JM
7193 if (params->proberesp && params->proberesp_len) {
7194 wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
7195 params->proberesp, params->proberesp_len);
5ed33546
AN
7196 NLA_PUT(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
7197 params->proberesp);
b92e08fc 7198 }
97a7a0b5
JM
7199 switch (params->hide_ssid) {
7200 case NO_SSID_HIDING:
b92e08fc 7201 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
97a7a0b5
JM
7202 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7203 NL80211_HIDDEN_SSID_NOT_IN_USE);
7204 break;
7205 case HIDDEN_SSID_ZERO_LEN:
b92e08fc 7206 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
97a7a0b5
JM
7207 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7208 NL80211_HIDDEN_SSID_ZERO_LEN);
7209 break;
7210 case HIDDEN_SSID_ZERO_CONTENTS:
b92e08fc 7211 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
97a7a0b5
JM
7212 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7213 NL80211_HIDDEN_SSID_ZERO_CONTENTS);
7214 break;
7215 }
b92e08fc 7216 wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
b11d1d64
JM
7217 if (params->privacy)
7218 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
b92e08fc 7219 wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
b11d1d64
JM
7220 if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
7221 (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
7222 /* Leave out the attribute */
7223 } else if (params->auth_algs & WPA_AUTH_ALG_SHARED)
7224 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
7225 NL80211_AUTHTYPE_SHARED_KEY);
7226 else
7227 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
7228 NL80211_AUTHTYPE_OPEN_SYSTEM);
7229
b92e08fc 7230 wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
b11d1d64
JM
7231 ver = 0;
7232 if (params->wpa_version & WPA_PROTO_WPA)
7233 ver |= NL80211_WPA_VERSION_1;
7234 if (params->wpa_version & WPA_PROTO_RSN)
7235 ver |= NL80211_WPA_VERSION_2;
7236 if (ver)
7237 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
7238
b92e08fc
JM
7239 wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
7240 params->key_mgmt_suites);
b11d1d64
JM
7241 num_suites = 0;
7242 if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
7243 suites[num_suites++] = WLAN_AKM_SUITE_8021X;
7244 if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
7245 suites[num_suites++] = WLAN_AKM_SUITE_PSK;
7246 if (num_suites) {
7247 NLA_PUT(msg, NL80211_ATTR_AKM_SUITES,
7248 num_suites * sizeof(u32), suites);
7249 }
7250
9f12614b
JB
7251 if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X &&
7252 params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40))
7253 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT);
7254
b92e08fc
JM
7255 wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
7256 params->pairwise_ciphers);
de4ed4a8
JM
7257 num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
7258 suites, ARRAY_SIZE(suites));
b11d1d64
JM
7259 if (num_suites) {
7260 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
7261 num_suites * sizeof(u32), suites);
7262 }
7263
b92e08fc
JM
7264 wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
7265 params->group_cipher);
de4ed4a8
JM
7266 suite = wpa_cipher_to_cipher_suite(params->group_cipher);
7267 if (suite)
7268 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite);
d2440ba0 7269
fb91db56 7270 if (params->beacon_ies) {
b92e08fc
JM
7271 wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
7272 params->beacon_ies);
fb91db56
JM
7273 NLA_PUT(msg, NL80211_ATTR_IE, wpabuf_len(params->beacon_ies),
7274 wpabuf_head(params->beacon_ies));
7275 }
7276 if (params->proberesp_ies) {
b92e08fc
JM
7277 wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
7278 params->proberesp_ies);
fb91db56
JM
7279 NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
7280 wpabuf_len(params->proberesp_ies),
7281 wpabuf_head(params->proberesp_ies));
7282 }
7283 if (params->assocresp_ies) {
b92e08fc
JM
7284 wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
7285 params->assocresp_ies);
fb91db56
JM
7286 NLA_PUT(msg, NL80211_ATTR_IE_ASSOC_RESP,
7287 wpabuf_len(params->assocresp_ies),
7288 wpabuf_head(params->assocresp_ies));
7289 }
7290
a0133ee1 7291 if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER) {
b92e08fc
JM
7292 wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
7293 params->ap_max_inactivity);
a0133ee1
VT
7294 NLA_PUT_U16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
7295 params->ap_max_inactivity);
7296 }
7297
d2440ba0
JM
7298 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7299 if (ret) {
7300 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
7301 ret, strerror(-ret));
b4fd6fab 7302 } else {
b4fd6fab 7303 bss->beacon_set = 1;
31357268 7304 nl80211_set_bss(bss, params->cts_protect, params->preamble,
d03e8d11 7305 params->short_slot_time, params->ht_opmode,
e5693c47 7306 params->isolate, params->basic_rates);
e87ef751
PX
7307 if (beacon_set && params->freq &&
7308 params->freq->bandwidth != bss->bandwidth) {
7309 wpa_printf(MSG_DEBUG,
7310 "nl80211: Update BSS %s bandwidth: %d -> %d",
7311 bss->ifname, bss->bandwidth,
7312 params->freq->bandwidth);
7313 ret = nl80211_set_channel(bss, params->freq, 1);
7314 if (ret) {
7315 wpa_printf(MSG_DEBUG,
7316 "nl80211: Frequency set failed: %d (%s)",
7317 ret, strerror(-ret));
7318 } else {
7319 wpa_printf(MSG_DEBUG,
7320 "nl80211: Frequency set succeeded for ht2040 coex");
7321 bss->bandwidth = params->freq->bandwidth;
7322 }
7323 } else if (!beacon_set) {
7324 /*
7325 * cfg80211 updates the driver on frequence change in AP
7326 * mode only at the point when beaconing is started, so
7327 * set the initial value here.
7328 */
7329 bss->bandwidth = params->freq->bandwidth;
7330 }
b4fd6fab 7331 }
d2440ba0
JM
7332 return ret;
7333 nla_put_failure:
5883168a 7334 nlmsg_free(msg);
d2440ba0
JM
7335 return -ENOBUFS;
7336}
7337
7338
1c4ffa87
AO
7339static int nl80211_put_freq_params(struct nl_msg *msg,
7340 struct hostapd_freq_params *freq)
1581b38b 7341{
89b800d7
JB
7342 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq);
7343 if (freq->vht_enabled) {
7344 switch (freq->bandwidth) {
7345 case 20:
7346 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7347 NL80211_CHAN_WIDTH_20);
7348 break;
7349 case 40:
7350 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7351 NL80211_CHAN_WIDTH_40);
7352 break;
7353 case 80:
7354 if (freq->center_freq2)
7355 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7356 NL80211_CHAN_WIDTH_80P80);
7357 else
7358 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7359 NL80211_CHAN_WIDTH_80);
7360 break;
7361 case 160:
7362 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7363 NL80211_CHAN_WIDTH_160);
7364 break;
7365 default:
1c4ffa87 7366 return -EINVAL;
89b800d7
JB
7367 }
7368 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1);
7369 if (freq->center_freq2)
7370 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2,
7371 freq->center_freq2);
7372 } else if (freq->ht_enabled) {
7373 switch (freq->sec_channel_offset) {
f019981a
JM
7374 case -1:
7375 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7376 NL80211_CHAN_HT40MINUS);
7377 break;
7378 case 1:
7379 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7380 NL80211_CHAN_HT40PLUS);
7381 break;
7382 default:
7383 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7384 NL80211_CHAN_HT20);
7385 break;
7386 }
7387 }
1c4ffa87
AO
7388 return 0;
7389
7390nla_put_failure:
7391 return -ENOBUFS;
7392}
7393
7394
e87ef751
PX
7395static int nl80211_set_channel(struct i802_bss *bss,
7396 struct hostapd_freq_params *freq, int set_chan)
1c4ffa87
AO
7397{
7398 struct wpa_driver_nl80211_data *drv = bss->drv;
7399 struct nl_msg *msg;
7400 int ret;
7401
7402 wpa_printf(MSG_DEBUG,
7403 "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
7404 freq->freq, freq->ht_enabled, freq->vht_enabled,
7405 freq->bandwidth, freq->center_freq1, freq->center_freq2);
7406 msg = nlmsg_alloc();
7407 if (!msg)
7408 return -1;
7409
e87ef751
PX
7410 nl80211_cmd(drv, msg, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
7411 NL80211_CMD_SET_WIPHY);
1c4ffa87
AO
7412
7413 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7414 if (nl80211_put_freq_params(msg, freq) < 0)
7415 goto nla_put_failure;
1581b38b 7416
d2440ba0 7417 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 7418 msg = NULL;
e4fb2167 7419 if (ret == 0) {
89b800d7 7420 bss->freq = freq->freq;
1581b38b 7421 return 0;
e4fb2167 7422 }
f019981a 7423 wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
89b800d7 7424 "%d (%s)", freq->freq, ret, strerror(-ret));
1581b38b 7425nla_put_failure:
5883168a 7426 nlmsg_free(msg);
1581b38b
JM
7427 return -1;
7428}
7429
0f4e8b4f 7430
95ab6063
AN
7431static u32 sta_flags_nl80211(int flags)
7432{
7433 u32 f = 0;
7434
7435 if (flags & WPA_STA_AUTHORIZED)
7436 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
7437 if (flags & WPA_STA_WMM)
7438 f |= BIT(NL80211_STA_FLAG_WME);
7439 if (flags & WPA_STA_SHORT_PREAMBLE)
7440 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
7441 if (flags & WPA_STA_MFP)
7442 f |= BIT(NL80211_STA_FLAG_MFP);
45b722f1
AN
7443 if (flags & WPA_STA_TDLS_PEER)
7444 f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
95ab6063
AN
7445
7446 return f;
7447}
7448
7449
62847751 7450static int wpa_driver_nl80211_sta_add(void *priv,
0f4e8b4f
JM
7451 struct hostapd_sta_add_params *params)
7452{
a2e40bb6
FF
7453 struct i802_bss *bss = priv;
7454 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8 7455 struct nl_msg *msg;
95ab6063 7456 struct nl80211_sta_flag_update upd;
0f4e8b4f
JM
7457 int ret = -ENOBUFS;
7458
45b722f1
AN
7459 if ((params->flags & WPA_STA_TDLS_PEER) &&
7460 !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
7461 return -EOPNOTSUPP;
7462
0f4e8b4f
JM
7463 msg = nlmsg_alloc();
7464 if (!msg)
7465 return -ENOMEM;
7466
e4dea253
JM
7467 wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
7468 params->set ? "Set" : "Add", MAC2STR(params->addr));
45b722f1
AN
7469 nl80211_cmd(drv, msg, 0, params->set ? NL80211_CMD_SET_STATION :
7470 NL80211_CMD_NEW_STATION);
0f4e8b4f 7471
62847751 7472 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
0f4e8b4f 7473 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
0f4e8b4f
JM
7474 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
7475 params->supp_rates);
e4dea253
JM
7476 wpa_hexdump(MSG_DEBUG, " * supported rates", params->supp_rates,
7477 params->supp_rates_len);
45b722f1 7478 if (!params->set) {
f11b72c3
JM
7479 if (params->aid) {
7480 wpa_printf(MSG_DEBUG, " * aid=%u", params->aid);
7481 NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
7482 } else {
7483 /*
7484 * cfg80211 validates that AID is non-zero, so we have
7485 * to make this a non-zero value for the TDLS case where
7486 * a dummy STA entry is used for now.
7487 */
7488 wpa_printf(MSG_DEBUG, " * aid=1 (TDLS workaround)");
7489 NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, 1);
7490 }
e4dea253
JM
7491 wpa_printf(MSG_DEBUG, " * listen_interval=%u",
7492 params->listen_interval);
45b722f1
AN
7493 NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
7494 params->listen_interval);
e112764e
JM
7495 } else if (params->aid && (params->flags & WPA_STA_TDLS_PEER)) {
7496 wpa_printf(MSG_DEBUG, " * peer_aid=%u", params->aid);
7497 NLA_PUT_U16(msg, NL80211_ATTR_PEER_AID, params->aid);
45b722f1 7498 }
0f4e8b4f 7499 if (params->ht_capabilities) {
e4dea253
JM
7500 wpa_hexdump(MSG_DEBUG, " * ht_capabilities",
7501 (u8 *) params->ht_capabilities,
7502 sizeof(*params->ht_capabilities));
0f4e8b4f 7503 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
fc4e2d95
JM
7504 sizeof(*params->ht_capabilities),
7505 params->ht_capabilities);
0f4e8b4f 7506 }
0f4e8b4f 7507
05a8d422 7508 if (params->vht_capabilities) {
e4dea253
JM
7509 wpa_hexdump(MSG_DEBUG, " * vht_capabilities",
7510 (u8 *) params->vht_capabilities,
7511 sizeof(*params->vht_capabilities));
05a8d422
JB
7512 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY,
7513 sizeof(*params->vht_capabilities),
7514 params->vht_capabilities);
7515 }
7516
8a458116
MK
7517 if (params->vht_opmode_enabled) {
7518 wpa_printf(MSG_DEBUG, " * opmode=%u", params->vht_opmode);
7519 NLA_PUT_U8(msg, NL80211_ATTR_OPMODE_NOTIF,
7520 params->vht_opmode);
7521 }
7522
122d16f2
SD
7523 wpa_printf(MSG_DEBUG, " * capability=0x%x", params->capability);
7524 NLA_PUT_U16(msg, NL80211_ATTR_STA_CAPABILITY, params->capability);
7525
7526 if (params->ext_capab) {
7527 wpa_hexdump(MSG_DEBUG, " * ext_capab",
7528 params->ext_capab, params->ext_capab_len);
7529 NLA_PUT(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
7530 params->ext_capab_len, params->ext_capab);
7531 }
7532
efc64886
SD
7533 if (params->supp_channels) {
7534 wpa_hexdump(MSG_DEBUG, " * supported channels",
7535 params->supp_channels, params->supp_channels_len);
7536 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_CHANNELS,
7537 params->supp_channels_len, params->supp_channels);
7538 }
7539
7540 if (params->supp_oper_classes) {
7541 wpa_hexdump(MSG_DEBUG, " * supported operating classes",
7542 params->supp_oper_classes,
7543 params->supp_oper_classes_len);
7544 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
7545 params->supp_oper_classes_len,
7546 params->supp_oper_classes);
7547 }
7548
95ab6063
AN
7549 os_memset(&upd, 0, sizeof(upd));
7550 upd.mask = sta_flags_nl80211(params->flags);
7551 upd.set = upd.mask;
e4dea253
JM
7552 wpa_printf(MSG_DEBUG, " * flags set=0x%x mask=0x%x",
7553 upd.set, upd.mask);
95ab6063
AN
7554 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
7555
774bfa62 7556 if (params->flags & WPA_STA_WMM) {
8970bae8
JB
7557 struct nlattr *wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
7558
774bfa62
EP
7559 if (!wme)
7560 goto nla_put_failure;
7561
e4dea253 7562 wpa_printf(MSG_DEBUG, " * qosinfo=0x%x", params->qosinfo);
8970bae8 7563 NLA_PUT_U8(msg, NL80211_STA_WME_UAPSD_QUEUES,
5d061637 7564 params->qosinfo & WMM_QOSINFO_STA_AC_MASK);
8970bae8 7565 NLA_PUT_U8(msg, NL80211_STA_WME_MAX_SP,
bdaf1748 7566 (params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
5d061637 7567 WMM_QOSINFO_STA_SP_MASK);
8970bae8 7568 nla_nest_end(msg, wme);
774bfa62
EP
7569 }
7570
0f4e8b4f 7571 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 7572 msg = NULL;
0f4e8b4f 7573 if (ret)
45b722f1
AN
7574 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
7575 "result: %d (%s)", params->set ? "SET" : "NEW", ret,
7576 strerror(-ret));
0f4e8b4f
JM
7577 if (ret == -EEXIST)
7578 ret = 0;
7579 nla_put_failure:
5883168a 7580 nlmsg_free(msg);
0f4e8b4f
JM
7581 return ret;
7582}
7583
7584
9ebce9c5 7585static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr)
0f4e8b4f 7586{
a2e40bb6 7587 struct wpa_driver_nl80211_data *drv = bss->drv;
0f4e8b4f
JM
7588 struct nl_msg *msg;
7589 int ret;
7590
7591 msg = nlmsg_alloc();
7592 if (!msg)
7593 return -ENOMEM;
7594
9fb04070 7595 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
0f4e8b4f
JM
7596
7597 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 7598 if_nametoindex(bss->ifname));
0f4e8b4f
JM
7599 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
7600
7601 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
83e7bb0e
JM
7602 wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
7603 " --> %d (%s)",
7604 bss->ifname, MAC2STR(addr), ret, strerror(-ret));
0f4e8b4f
JM
7605 if (ret == -ENOENT)
7606 return 0;
7607 return ret;
7608 nla_put_failure:
5883168a 7609 nlmsg_free(msg);
0f4e8b4f
JM
7610 return -ENOBUFS;
7611}
7612
1581b38b 7613
0915d02c
JM
7614static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
7615 int ifidx)
7616{
7617 struct nl_msg *msg;
7618
c6e8e8e4
JM
7619 wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
7620
2135f224
JM
7621 /* stop listening for EAPOL on this interface */
7622 del_ifidx(drv, ifidx);
2135f224 7623
0915d02c
JM
7624 msg = nlmsg_alloc();
7625 if (!msg)
7626 goto nla_put_failure;
7627
9fb04070 7628 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
0915d02c
JM
7629 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
7630
7631 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
7632 return;
5883168a 7633 msg = NULL;
0915d02c 7634 nla_put_failure:
5883168a 7635 nlmsg_free(msg);
e748062b 7636 wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
0915d02c
JM
7637}
7638
7639
a1922f93
JM
7640static const char * nl80211_iftype_str(enum nl80211_iftype mode)
7641{
7642 switch (mode) {
7643 case NL80211_IFTYPE_ADHOC:
7644 return "ADHOC";
7645 case NL80211_IFTYPE_STATION:
7646 return "STATION";
7647 case NL80211_IFTYPE_AP:
7648 return "AP";
1045ec36
JM
7649 case NL80211_IFTYPE_AP_VLAN:
7650 return "AP_VLAN";
7651 case NL80211_IFTYPE_WDS:
7652 return "WDS";
a1922f93
JM
7653 case NL80211_IFTYPE_MONITOR:
7654 return "MONITOR";
1045ec36
JM
7655 case NL80211_IFTYPE_MESH_POINT:
7656 return "MESH_POINT";
a1922f93
JM
7657 case NL80211_IFTYPE_P2P_CLIENT:
7658 return "P2P_CLIENT";
7659 case NL80211_IFTYPE_P2P_GO:
7660 return "P2P_GO";
7aad838c
NS
7661 case NL80211_IFTYPE_P2P_DEVICE:
7662 return "P2P_DEVICE";
a1922f93
JM
7663 default:
7664 return "unknown";
7665 }
7666}
7667
7668
a35187e7
KH
7669static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
7670 const char *ifname,
7671 enum nl80211_iftype iftype,
d6dcfcda
DS
7672 const u8 *addr, int wds,
7673 int (*handler)(struct nl_msg *, void *),
7674 void *arg)
0915d02c 7675{
8970bae8 7676 struct nl_msg *msg;
0915d02c
JM
7677 int ifidx;
7678 int ret = -ENOBUFS;
7679
a1922f93
JM
7680 wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
7681 iftype, nl80211_iftype_str(iftype));
7682
0915d02c
JM
7683 msg = nlmsg_alloc();
7684 if (!msg)
7685 return -1;
7686
9fb04070 7687 nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_INTERFACE);
834ee56f 7688 if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
fa93de40 7689 goto nla_put_failure;
0915d02c
JM
7690 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
7691 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
7692
7693 if (iftype == NL80211_IFTYPE_MONITOR) {
8970bae8 7694 struct nlattr *flags;
0915d02c 7695
8970bae8 7696 flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
0915d02c
JM
7697 if (!flags)
7698 goto nla_put_failure;
7699
8970bae8 7700 NLA_PUT_FLAG(msg, NL80211_MNTR_FLAG_COOK_FRAMES);
0915d02c 7701
8970bae8 7702 nla_nest_end(msg, flags);
fbbfcbac
FF
7703 } else if (wds) {
7704 NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
0915d02c
JM
7705 }
7706
d6dcfcda 7707 ret = send_and_recv_msgs(drv, msg, handler, arg);
5883168a 7708 msg = NULL;
0915d02c
JM
7709 if (ret) {
7710 nla_put_failure:
5883168a 7711 nlmsg_free(msg);
a35187e7
KH
7712 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
7713 ifname, ret, strerror(-ret));
0915d02c
JM
7714 return ret;
7715 }
7716
f632e483 7717 if (iftype == NL80211_IFTYPE_P2P_DEVICE)
6bae92e0 7718 return 0;
6bae92e0 7719
0915d02c 7720 ifidx = if_nametoindex(ifname);
c6e8e8e4
JM
7721 wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
7722 ifname, ifidx);
0915d02c
JM
7723
7724 if (ifidx <= 0)
7725 return -1;
7726
2135f224
JM
7727 /* start listening for EAPOL on this interface */
7728 add_ifidx(drv, ifidx);
7729
7bfc47c3 7730 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
c81eff1a 7731 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
41d931ee
JM
7732 nl80211_remove_iface(drv, ifidx);
7733 return -1;
2135f224 7734 }
2135f224 7735
0915d02c
JM
7736 return ifidx;
7737}
22a7c9d7
JM
7738
7739
a35187e7
KH
7740static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
7741 const char *ifname, enum nl80211_iftype iftype,
d6dcfcda
DS
7742 const u8 *addr, int wds,
7743 int (*handler)(struct nl_msg *, void *),
2aec4f3c 7744 void *arg, int use_existing)
a35187e7
KH
7745{
7746 int ret;
7747
d6dcfcda
DS
7748 ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
7749 arg);
a35187e7 7750
ffbf1eaa 7751 /* if error occurred and interface exists already */
a35187e7 7752 if (ret == -ENFILE && if_nametoindex(ifname)) {
2aec4f3c
JM
7753 if (use_existing) {
7754 wpa_printf(MSG_DEBUG, "nl80211: Continue using existing interface %s",
7755 ifname);
6997f8ba
JM
7756 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
7757 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
7758 addr) < 0 &&
7759 (linux_set_iface_flags(drv->global->ioctl_sock,
7760 ifname, 0) < 0 ||
7761 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
7762 addr) < 0 ||
7763 linux_set_iface_flags(drv->global->ioctl_sock,
7764 ifname, 1) < 0))
7765 return -1;
2aec4f3c
JM
7766 return -ENFILE;
7767 }
a35187e7
KH
7768 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
7769
7770 /* Try to remove the interface that was already there. */
7771 nl80211_remove_iface(drv, if_nametoindex(ifname));
7772
7773 /* Try to create the interface again */
fbbfcbac 7774 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
d6dcfcda 7775 wds, handler, arg);
a35187e7
KH
7776 }
7777
6a71413e 7778 if (ret >= 0 && is_p2p_net_interface(iftype))
4e5cb1a3
JM
7779 nl80211_disable_11b_rates(drv, ret, 1);
7780
a35187e7
KH
7781 return ret;
7782}
0915d02c 7783
2135f224 7784
0915d02c
JM
7785static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
7786{
7787 struct ieee80211_hdr *hdr;
f8b1f695
JM
7788 u16 fc;
7789 union wpa_event_data event;
0915d02c
JM
7790
7791 hdr = (struct ieee80211_hdr *) buf;
7792 fc = le_to_host16(hdr->frame_control);
7793
f8b1f695
JM
7794 os_memset(&event, 0, sizeof(event));
7795 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
7796 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
7797 event.tx_status.dst = hdr->addr1;
7798 event.tx_status.data = buf;
7799 event.tx_status.data_len = len;
7800 event.tx_status.ack = ok;
7801 wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event);
0915d02c
JM
7802}
7803
7804
4b9841d3 7805static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
0d9fc3d8 7806 u8 *buf, size_t len)
0915d02c 7807{
9b90955e
JB
7808 struct ieee80211_hdr *hdr = (void *)buf;
7809 u16 fc;
f8b1f695 7810 union wpa_event_data event;
9b90955e
JB
7811
7812 if (len < sizeof(*hdr))
7813 return;
7814
7815 fc = le_to_host16(hdr->frame_control);
7816
f8b1f695 7817 os_memset(&event, 0, sizeof(event));
9b90955e
JB
7818 event.rx_from_unknown.bssid = get_hdr_bssid(hdr, len);
7819 event.rx_from_unknown.addr = hdr->addr2;
7820 event.rx_from_unknown.wds = (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) ==
7821 (WLAN_FC_FROMDS | WLAN_FC_TODS);
f8b1f695 7822 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
4b9841d3 7823}
0915d02c 7824
4b9841d3
JM
7825
7826static void handle_frame(struct wpa_driver_nl80211_data *drv,
2a8b7416 7827 u8 *buf, size_t len, int datarate, int ssi_signal)
4b9841d3
JM
7828{
7829 struct ieee80211_hdr *hdr;
f8b1f695
JM
7830 u16 fc;
7831 union wpa_event_data event;
0915d02c
JM
7832
7833 hdr = (struct ieee80211_hdr *) buf;
7834 fc = le_to_host16(hdr->frame_control);
0915d02c 7835
4b9841d3 7836 switch (WLAN_FC_GET_TYPE(fc)) {
0915d02c 7837 case WLAN_FC_TYPE_MGMT:
f8b1f695
JM
7838 os_memset(&event, 0, sizeof(event));
7839 event.rx_mgmt.frame = buf;
7840 event.rx_mgmt.frame_len = len;
2a8b7416
JM
7841 event.rx_mgmt.datarate = datarate;
7842 event.rx_mgmt.ssi_signal = ssi_signal;
f8b1f695 7843 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
0915d02c
JM
7844 break;
7845 case WLAN_FC_TYPE_CTRL:
7846 /* can only get here with PS-Poll frames */
7847 wpa_printf(MSG_DEBUG, "CTRL");
0d9fc3d8 7848 from_unknown_sta(drv, buf, len);
0915d02c
JM
7849 break;
7850 case WLAN_FC_TYPE_DATA:
0d9fc3d8 7851 from_unknown_sta(drv, buf, len);
0915d02c
JM
7852 break;
7853 }
7854}
7855
7856
7857static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
7858{
7859 struct wpa_driver_nl80211_data *drv = eloop_ctx;
7860 int len;
7861 unsigned char buf[3000];
7862 struct ieee80211_radiotap_iterator iter;
7863 int ret;
2a8b7416 7864 int datarate = 0, ssi_signal = 0;
4b9841d3 7865 int injected = 0, failed = 0, rxflags = 0;
0915d02c
JM
7866
7867 len = recv(sock, buf, sizeof(buf), 0);
7868 if (len < 0) {
7ac3616d
JM
7869 wpa_printf(MSG_ERROR, "nl80211: Monitor socket recv failed: %s",
7870 strerror(errno));
0915d02c
JM
7871 return;
7872 }
7873
0e80ea2c 7874 if (ieee80211_radiotap_iterator_init(&iter, (void *) buf, len, NULL)) {
7ac3616d 7875 wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame");
0915d02c
JM
7876 return;
7877 }
7878
0915d02c
JM
7879 while (1) {
7880 ret = ieee80211_radiotap_iterator_next(&iter);
7881 if (ret == -ENOENT)
7882 break;
7883 if (ret) {
7ac3616d
JM
7884 wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame (%d)",
7885 ret);
0915d02c
JM
7886 return;
7887 }
7888 switch (iter.this_arg_index) {
7889 case IEEE80211_RADIOTAP_FLAGS:
7890 if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
7891 len -= 4;
7892 break;
7893 case IEEE80211_RADIOTAP_RX_FLAGS:
7894 rxflags = 1;
7895 break;
7896 case IEEE80211_RADIOTAP_TX_FLAGS:
7897 injected = 1;
7898 failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
7899 IEEE80211_RADIOTAP_F_TX_FAIL;
7900 break;
7901 case IEEE80211_RADIOTAP_DATA_RETRIES:
7902 break;
7903 case IEEE80211_RADIOTAP_CHANNEL:
2a8b7416 7904 /* TODO: convert from freq/flags to channel number */
0915d02c
JM
7905 break;
7906 case IEEE80211_RADIOTAP_RATE:
2a8b7416 7907 datarate = *iter.this_arg * 5;
0915d02c 7908 break;
baf513d6
JB
7909 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
7910 ssi_signal = (s8) *iter.this_arg;
0915d02c
JM
7911 break;
7912 }
7913 }
7914
7915 if (rxflags && injected)
7916 return;
7917
7918 if (!injected)
bacb984b
JB
7919 handle_frame(drv, buf + iter._max_length,
7920 len - iter._max_length, datarate, ssi_signal);
0915d02c 7921 else
bacb984b
JB
7922 handle_tx_callback(drv->ctx, buf + iter._max_length,
7923 len - iter._max_length, !failed);
0915d02c
JM
7924}
7925
7926
7927/*
7928 * we post-process the filter code later and rewrite
7929 * this to the offset to the last instruction
7930 */
7931#define PASS 0xFF
7932#define FAIL 0xFE
7933
7934static struct sock_filter msock_filter_insns[] = {
7935 /*
7936 * do a little-endian load of the radiotap length field
7937 */
7938 /* load lower byte into A */
7939 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
7940 /* put it into X (== index register) */
7941 BPF_STMT(BPF_MISC| BPF_TAX, 0),
7942 /* load upper byte into A */
7943 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 3),
7944 /* left-shift it by 8 */
7945 BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
7946 /* or with X */
7947 BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
7948 /* put result into X */
7949 BPF_STMT(BPF_MISC| BPF_TAX, 0),
7950
7951 /*
7952 * Allow management frames through, this also gives us those
7953 * management frames that we sent ourselves with status
7954 */
7955 /* load the lower byte of the IEEE 802.11 frame control field */
7956 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
7957 /* mask off frame type and version */
7958 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
7959 /* accept frame if it's both 0, fall through otherwise */
7960 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
7961
7962 /*
7963 * TODO: add a bit to radiotap RX flags that indicates
7964 * that the sending station is not associated, then
7965 * add a filter here that filters on our DA and that flag
7966 * to allow us to deauth frames to that bad station.
7967 *
65ae1afd 7968 * For now allow all To DS data frames through.
0915d02c 7969 */
65ae1afd
HS
7970 /* load the IEEE 802.11 frame control field */
7971 BPF_STMT(BPF_LD | BPF_H | BPF_IND, 0),
7972 /* mask off frame type, version and DS status */
7973 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0F03),
7974 /* accept frame if version 0, type 2 and To DS, fall through otherwise
7975 */
7976 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0801, PASS, 0),
0915d02c
JM
7977
7978#if 0
7979 /*
fbbfcbac 7980 * drop non-data frames
0915d02c
JM
7981 */
7982 /* load the lower byte of the frame control field */
7983 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
7984 /* mask off QoS bit */
7985 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0c),
7986 /* drop non-data frames */
7987 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 8, 0, FAIL),
fbbfcbac 7988#endif
0915d02c 7989 /* load the upper byte of the frame control field */
fbbfcbac 7990 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
0915d02c
JM
7991 /* mask off toDS/fromDS */
7992 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x03),
fbbfcbac
FF
7993 /* accept WDS frames */
7994 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 3, PASS, 0),
0915d02c
JM
7995
7996 /*
7997 * add header length to index
7998 */
7999 /* load the lower byte of the frame control field */
8000 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
8001 /* mask off QoS bit */
8002 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80),
8003 /* right shift it by 6 to give 0 or 2 */
8004 BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 6),
8005 /* add data frame header length */
8006 BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 24),
8007 /* add index, was start of 802.11 header */
8008 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
8009 /* move to index, now start of LL header */
8010 BPF_STMT(BPF_MISC | BPF_TAX, 0),
8011
8012 /*
8013 * Accept empty data frames, we use those for
8014 * polling activity.
8015 */
8016 BPF_STMT(BPF_LD | BPF_W | BPF_LEN, 0),
8017 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
8018
8019 /*
8020 * Accept EAPOL frames
8021 */
8022 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 0),
8023 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
8024 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 4),
8025 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
8026
8027 /* keep these last two statements or change the code below */
8028 /* return 0 == "DROP" */
8029 BPF_STMT(BPF_RET | BPF_K, 0),
8030 /* return ~0 == "keep all" */
8031 BPF_STMT(BPF_RET | BPF_K, ~0),
8032};
8033
8034static struct sock_fprog msock_filter = {
e7ecab4a 8035 .len = ARRAY_SIZE(msock_filter_insns),
0915d02c
JM
8036 .filter = msock_filter_insns,
8037};
8038
8039
8040static int add_monitor_filter(int s)
8041{
8042 int idx;
8043
8044 /* rewrite all PASS/FAIL jump offsets */
8045 for (idx = 0; idx < msock_filter.len; idx++) {
8046 struct sock_filter *insn = &msock_filter_insns[idx];
8047
8048 if (BPF_CLASS(insn->code) == BPF_JMP) {
8049 if (insn->code == (BPF_JMP|BPF_JA)) {
8050 if (insn->k == PASS)
8051 insn->k = msock_filter.len - idx - 2;
8052 else if (insn->k == FAIL)
8053 insn->k = msock_filter.len - idx - 3;
8054 }
8055
8056 if (insn->jt == PASS)
8057 insn->jt = msock_filter.len - idx - 2;
8058 else if (insn->jt == FAIL)
8059 insn->jt = msock_filter.len - idx - 3;
8060
8061 if (insn->jf == PASS)
8062 insn->jf = msock_filter.len - idx - 2;
8063 else if (insn->jf == FAIL)
8064 insn->jf = msock_filter.len - idx - 3;
8065 }
8066 }
8067
8068 if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
8069 &msock_filter, sizeof(msock_filter))) {
7ac3616d
JM
8070 wpa_printf(MSG_ERROR, "nl80211: setsockopt(SO_ATTACH_FILTER) failed: %s",
8071 strerror(errno));
0915d02c
JM
8072 return -1;
8073 }
8074
8075 return 0;
8076}
8077
8078
460456f8
JM
8079static void nl80211_remove_monitor_interface(
8080 struct wpa_driver_nl80211_data *drv)
8081{
748c0ac0
JM
8082 if (drv->monitor_refcount > 0)
8083 drv->monitor_refcount--;
8084 wpa_printf(MSG_DEBUG, "nl80211: Remove monitor interface: refcount=%d",
8085 drv->monitor_refcount);
3fd1cefb
JB
8086 if (drv->monitor_refcount > 0)
8087 return;
8088
460456f8
JM
8089 if (drv->monitor_ifidx >= 0) {
8090 nl80211_remove_iface(drv, drv->monitor_ifidx);
8091 drv->monitor_ifidx = -1;
8092 }
504e905c
JM
8093 if (drv->monitor_sock >= 0) {
8094 eloop_unregister_read_sock(drv->monitor_sock);
8095 close(drv->monitor_sock);
8096 drv->monitor_sock = -1;
8097 }
460456f8
JM
8098}
8099
8100
0915d02c
JM
8101static int
8102nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
8103{
8104 char buf[IFNAMSIZ];
8105 struct sockaddr_ll ll;
8106 int optval;
8107 socklen_t optlen;
0915d02c 8108
3fd1cefb
JB
8109 if (drv->monitor_ifidx >= 0) {
8110 drv->monitor_refcount++;
748c0ac0
JM
8111 wpa_printf(MSG_DEBUG, "nl80211: Re-use existing monitor interface: refcount=%d",
8112 drv->monitor_refcount);
3fd1cefb
JB
8113 return 0;
8114 }
8115
834ee56f 8116 if (os_strncmp(drv->first_bss->ifname, "p2p-", 4) == 0) {
6758b167
JJ
8117 /*
8118 * P2P interface name is of the format p2p-%s-%d. For monitor
8119 * interface name corresponding to P2P GO, replace "p2p-" with
8120 * "mon-" to retain the same interface name length and to
8121 * indicate that it is a monitor interface.
8122 */
834ee56f 8123 snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss->ifname + 4);
6758b167
JJ
8124 } else {
8125 /* Non-P2P interface with AP functionality. */
834ee56f 8126 snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss->ifname);
6758b167
JJ
8127 }
8128
0915d02c
JM
8129 buf[IFNAMSIZ - 1] = '\0';
8130
8131 drv->monitor_ifidx =
fbbfcbac 8132 nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
2aec4f3c 8133 0, NULL, NULL, 0);
0915d02c 8134
866af8b6 8135 if (drv->monitor_ifidx == -EOPNOTSUPP) {
61cbe2ff
JB
8136 /*
8137 * This is backward compatibility for a few versions of
8138 * the kernel only that didn't advertise the right
8139 * attributes for the only driver that then supported
8140 * AP mode w/o monitor -- ath6kl.
8141 */
866af8b6
JM
8142 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support "
8143 "monitor interface type - try to run without it");
61cbe2ff 8144 drv->device_ap_sme = 1;
866af8b6
JM
8145 }
8146
0915d02c
JM
8147 if (drv->monitor_ifidx < 0)
8148 return -1;
8149
c81eff1a 8150 if (linux_set_iface_flags(drv->global->ioctl_sock, buf, 1))
0915d02c 8151 goto error;
0915d02c
JM
8152
8153 memset(&ll, 0, sizeof(ll));
8154 ll.sll_family = AF_PACKET;
8155 ll.sll_ifindex = drv->monitor_ifidx;
8156 drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8157 if (drv->monitor_sock < 0) {
7ac3616d
JM
8158 wpa_printf(MSG_ERROR, "nl80211: socket[PF_PACKET,SOCK_RAW] failed: %s",
8159 strerror(errno));
0915d02c
JM
8160 goto error;
8161 }
8162
8163 if (add_monitor_filter(drv->monitor_sock)) {
8164 wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
8165 "interface; do filtering in user space");
8166 /* This works, but will cost in performance. */
8167 }
8168
2135f224 8169 if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
7ac3616d
JM
8170 wpa_printf(MSG_ERROR, "nl80211: monitor socket bind failed: %s",
8171 strerror(errno));
0915d02c
JM
8172 goto error;
8173 }
8174
8175 optlen = sizeof(optval);
8176 optval = 20;
8177 if (setsockopt
8178 (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
7ac3616d
JM
8179 wpa_printf(MSG_ERROR, "nl80211: Failed to set socket priority: %s",
8180 strerror(errno));
0915d02c
JM
8181 goto error;
8182 }
8183
8184 if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
8185 drv, NULL)) {
7ac3616d 8186 wpa_printf(MSG_INFO, "nl80211: Could not register monitor read socket");
0915d02c
JM
8187 goto error;
8188 }
8189
748c0ac0 8190 drv->monitor_refcount++;
0915d02c
JM
8191 return 0;
8192 error:
460456f8 8193 nl80211_remove_monitor_interface(drv);
0915d02c
JM
8194 return -1;
8195}
8196
db149ac9 8197
3fd1cefb
JB
8198static int nl80211_setup_ap(struct i802_bss *bss)
8199{
8200 struct wpa_driver_nl80211_data *drv = bss->drv;
8201
748c0ac0
JM
8202 wpa_printf(MSG_DEBUG, "nl80211: Setup AP(%s) - device_ap_sme=%d use_monitor=%d",
8203 bss->ifname, drv->device_ap_sme, drv->use_monitor);
36488c05 8204
a11241fa
JB
8205 /*
8206 * Disable Probe Request reporting unless we need it in this way for
8207 * devices that include the AP SME, in the other case (unless using
8208 * monitor iface) we'll get it through the nl_mgmt socket instead.
8209 */
8210 if (!drv->device_ap_sme)
8211 wpa_driver_nl80211_probe_req_report(bss, 0);
8212
8213 if (!drv->device_ap_sme && !drv->use_monitor)
8214 if (nl80211_mgmt_subscribe_ap(bss))
8215 return -1;
8216
a6cc0602
JM
8217 if (drv->device_ap_sme && !drv->use_monitor)
8218 if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
8219 return -1;
8220
a11241fa 8221 if (!drv->device_ap_sme && drv->use_monitor &&
3fd1cefb
JB
8222 nl80211_create_monitor_interface(drv) &&
8223 !drv->device_ap_sme)
8224 return -1;
8225
8226 if (drv->device_ap_sme &&
8227 wpa_driver_nl80211_probe_req_report(bss, 1) < 0) {
8228 wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
8229 "Probe Request frame reporting in AP mode");
8230 /* Try to survive without this */
8231 }
8232
8233 return 0;
8234}
8235
8236
8237static void nl80211_teardown_ap(struct i802_bss *bss)
8238{
8239 struct wpa_driver_nl80211_data *drv = bss->drv;
8240
748c0ac0
JM
8241 wpa_printf(MSG_DEBUG, "nl80211: Teardown AP(%s) - device_ap_sme=%d use_monitor=%d",
8242 bss->ifname, drv->device_ap_sme, drv->use_monitor);
a6cc0602 8243 if (drv->device_ap_sme) {
3fd1cefb 8244 wpa_driver_nl80211_probe_req_report(bss, 0);
a6cc0602
JM
8245 if (!drv->use_monitor)
8246 nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
8247 } else if (drv->use_monitor)
3fd1cefb 8248 nl80211_remove_monitor_interface(drv);
a11241fa 8249 else
36488c05 8250 nl80211_mgmt_unsubscribe(bss, "AP teardown");
a11241fa 8251
3fd1cefb
JB
8252 bss->beacon_set = 0;
8253}
8254
8255
f10bfc9a
JM
8256static int nl80211_send_eapol_data(struct i802_bss *bss,
8257 const u8 *addr, const u8 *data,
d12dab4c 8258 size_t data_len)
f10bfc9a 8259{
d12dab4c
JB
8260 struct sockaddr_ll ll;
8261 int ret;
8262
8263 if (bss->drv->eapol_tx_sock < 0) {
8264 wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
f10bfc9a
JM
8265 return -1;
8266 }
8267
d12dab4c
JB
8268 os_memset(&ll, 0, sizeof(ll));
8269 ll.sll_family = AF_PACKET;
8270 ll.sll_ifindex = bss->ifindex;
8271 ll.sll_protocol = htons(ETH_P_PAE);
8272 ll.sll_halen = ETH_ALEN;
8273 os_memcpy(ll.sll_addr, addr, ETH_ALEN);
8274 ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
8275 (struct sockaddr *) &ll, sizeof(ll));
8276 if (ret < 0)
8277 wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
8278 strerror(errno));
8279
8280 return ret;
f10bfc9a 8281}
5fb1a232 8282
f10bfc9a 8283
db149ac9
JM
8284static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
8285
8286static int wpa_driver_nl80211_hapd_send_eapol(
8287 void *priv, const u8 *addr, const u8 *data,
4378fc14 8288 size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
db149ac9 8289{
a2e40bb6
FF
8290 struct i802_bss *bss = priv;
8291 struct wpa_driver_nl80211_data *drv = bss->drv;
db149ac9
JM
8292 struct ieee80211_hdr *hdr;
8293 size_t len;
8294 u8 *pos;
8295 int res;
4378fc14 8296 int qos = flags & WPA_STA_WMM;
db149ac9 8297
a11241fa 8298 if (drv->device_ap_sme || !drv->use_monitor)
d12dab4c 8299 return nl80211_send_eapol_data(bss, addr, data, data_len);
f10bfc9a 8300
db149ac9
JM
8301 len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
8302 data_len;
8303 hdr = os_zalloc(len);
8304 if (hdr == NULL) {
7ac3616d
JM
8305 wpa_printf(MSG_INFO, "nl80211: Failed to allocate EAPOL buffer(len=%lu)",
8306 (unsigned long) len);
db149ac9
JM
8307 return -1;
8308 }
8309
8310 hdr->frame_control =
8311 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
8312 hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
8313 if (encrypt)
8314 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
db149ac9
JM
8315 if (qos) {
8316 hdr->frame_control |=
8317 host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
8318 }
db149ac9
JM
8319
8320 memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
8321 memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
8322 memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
8323 pos = (u8 *) (hdr + 1);
8324
db149ac9 8325 if (qos) {
92d521d8
FF
8326 /* Set highest priority in QoS header */
8327 pos[0] = 7;
db149ac9
JM
8328 pos[1] = 0;
8329 pos += 2;
8330 }
db149ac9
JM
8331
8332 memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
8333 pos += sizeof(rfc1042_header);
8334 WPA_PUT_BE16(pos, ETH_P_PAE);
8335 pos += 2;
8336 memcpy(pos, data, data_len);
8337
55231068
JM
8338 res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
8339 0, 0, 0, 0);
db149ac9
JM
8340 if (res < 0) {
8341 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
8342 "failed: %d (%s)",
8343 (unsigned long) len, errno, strerror(errno));
8344 }
7bf12757 8345 os_free(hdr);
db149ac9
JM
8346
8347 return res;
8348}
8349
a8d6ffa4 8350
3234cba4
JM
8351static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
8352 int total_flags,
4c32757d 8353 int flags_or, int flags_and)
a8d6ffa4 8354{
a2e40bb6
FF
8355 struct i802_bss *bss = priv;
8356 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8
JB
8357 struct nl_msg *msg;
8358 struct nlattr *flags;
7e76ee9c 8359 struct nl80211_sta_flag_update upd;
a8d6ffa4
JM
8360
8361 msg = nlmsg_alloc();
8362 if (!msg)
8363 return -ENOMEM;
8364
9fb04070 8365 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
a8d6ffa4
JM
8366
8367 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
3234cba4 8368 if_nametoindex(bss->ifname));
a8d6ffa4
JM
8369 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
8370
7e76ee9c
JM
8371 /*
8372 * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
8373 * can be removed eventually.
8374 */
8970bae8
JB
8375 flags = nla_nest_start(msg, NL80211_ATTR_STA_FLAGS);
8376 if (!flags)
8377 goto nla_put_failure;
0de39516 8378 if (total_flags & WPA_STA_AUTHORIZED)
8970bae8 8379 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_AUTHORIZED);
a8d6ffa4 8380
0de39516 8381 if (total_flags & WPA_STA_WMM)
8970bae8 8382 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_WME);
a8d6ffa4 8383
0de39516 8384 if (total_flags & WPA_STA_SHORT_PREAMBLE)
8970bae8 8385 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_SHORT_PREAMBLE);
a8d6ffa4 8386
0de39516 8387 if (total_flags & WPA_STA_MFP)
8970bae8 8388 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_MFP);
a8d6ffa4 8389
45b722f1 8390 if (total_flags & WPA_STA_TDLS_PEER)
8970bae8 8391 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_TDLS_PEER);
45b722f1 8392
8970bae8 8393 nla_nest_end(msg, flags);
a8d6ffa4 8394
7e76ee9c
JM
8395 os_memset(&upd, 0, sizeof(upd));
8396 upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
8397 upd.set = sta_flags_nl80211(flags_or);
8398 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
8399
a8d6ffa4
JM
8400 return send_and_recv_msgs(drv, msg, NULL, NULL);
8401 nla_put_failure:
5883168a 8402 nlmsg_free(msg);
a8d6ffa4
JM
8403 return -ENOBUFS;
8404}
8405
0915d02c 8406
1581b38b
JM
8407static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
8408 struct wpa_driver_associate_params *params)
8409{
708bc8e0 8410 enum nl80211_iftype nlmode, old_mode;
89b800d7
JB
8411 struct hostapd_freq_params freq = {
8412 .freq = params->freq,
8413 };
b1f625e0
EP
8414
8415 if (params->p2p) {
046b26a2
JM
8416 wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
8417 "group (GO)");
b1f625e0
EP
8418 nlmode = NL80211_IFTYPE_P2P_GO;
8419 } else
8420 nlmode = NL80211_IFTYPE_AP;
8421
708bc8e0 8422 old_mode = drv->nlmode;
834ee56f 8423 if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
708bc8e0
JM
8424 nl80211_remove_monitor_interface(drv);
8425 return -1;
8426 }
8427
13a524a3 8428 if (nl80211_set_channel(drv->first_bss, &freq, 0)) {
708bc8e0 8429 if (old_mode != nlmode)
834ee56f 8430 wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
460456f8 8431 nl80211_remove_monitor_interface(drv);
1581b38b 8432 return -1;
0915d02c 8433 }
1581b38b 8434
1581b38b
JM
8435 return 0;
8436}
1581b38b
JM
8437
8438
5cc4d64b
JM
8439static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
8440{
8441 struct nl_msg *msg;
8442 int ret = -1;
8443
8444 msg = nlmsg_alloc();
8445 if (!msg)
8446 return -1;
8447
9fb04070 8448 nl80211_cmd(drv, msg, 0, NL80211_CMD_LEAVE_IBSS);
5cc4d64b
JM
8449 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
8450 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8451 msg = NULL;
8452 if (ret) {
8453 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
8454 "(%s)", ret, strerror(-ret));
8455 goto nla_put_failure;
8456 }
8457
8458 ret = 0;
8459 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
8460
8461nla_put_failure:
834ee56f 8462 if (wpa_driver_nl80211_set_mode(drv->first_bss,
5d4c78fb
JM
8463 NL80211_IFTYPE_STATION)) {
8464 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
8465 "station mode");
8466 }
8467
5cc4d64b
JM
8468 nlmsg_free(msg);
8469 return ret;
8470}
8471
8472
8473static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
8474 struct wpa_driver_associate_params *params)
8475{
8476 struct nl_msg *msg;
8477 int ret = -1;
8478 int count = 0;
8479
8480 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
8481
834ee56f 8482 if (wpa_driver_nl80211_set_mode(drv->first_bss,
b1f625e0 8483 NL80211_IFTYPE_ADHOC)) {
5cc4d64b
JM
8484 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
8485 "IBSS mode");
8486 return -1;
8487 }
8488
8489retry:
8490 msg = nlmsg_alloc();
8491 if (!msg)
8492 return -1;
8493
9fb04070 8494 nl80211_cmd(drv, msg, 0, NL80211_CMD_JOIN_IBSS);
5cc4d64b
JM
8495 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
8496
8497 if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
8498 goto nla_put_failure;
8499
8500 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
8501 params->ssid, params->ssid_len);
8502 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
8503 params->ssid);
8504 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
8505 drv->ssid_len = params->ssid_len;
8506
8507 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
8508 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
8509
8f05577d
JM
8510 if (params->beacon_int > 0) {
8511 wpa_printf(MSG_DEBUG, " * beacon_int=%d", params->beacon_int);
8512 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL,
8513 params->beacon_int);
8514 }
8515
5cc4d64b
JM
8516 ret = nl80211_set_conn_keys(params, msg);
8517 if (ret)
8518 goto nla_put_failure;
8519
913e3cf7
NC
8520 if (params->bssid && params->fixed_bssid) {
8521 wpa_printf(MSG_DEBUG, " * BSSID=" MACSTR,
8522 MAC2STR(params->bssid));
8523 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
8524 }
8525
4848a38d
JM
8526 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
8527 params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
8528 params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
8529 params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
e640888c
AQ
8530 wpa_printf(MSG_DEBUG, " * control port");
8531 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
8532 }
8533
a95795ad
JM
8534 if (params->wpa_ie) {
8535 wpa_hexdump(MSG_DEBUG,
8536 " * Extra IEs for Beacon/Probe Response frames",
8537 params->wpa_ie, params->wpa_ie_len);
8538 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
8539 params->wpa_ie);
8540 }
8541
5cc4d64b
JM
8542 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8543 msg = NULL;
8544 if (ret) {
8545 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
8546 ret, strerror(-ret));
8547 count++;
8548 if (ret == -EALREADY && count == 1) {
8549 wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
8550 "forced leave");
8551 nl80211_leave_ibss(drv);
8552 nlmsg_free(msg);
8553 goto retry;
8554 }
8555
8556 goto nla_put_failure;
8557 }
8558 ret = 0;
8559 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
8560
8561nla_put_failure:
8562 nlmsg_free(msg);
8563 return ret;
8564}
8565
8566
a0bdd191
JM
8567static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
8568 struct wpa_driver_associate_params *params,
8569 struct nl_msg *msg)
cfaab580 8570{
cfaab580 8571 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
a0bdd191 8572
cfaab580
ZY
8573 if (params->bssid) {
8574 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
8575 MAC2STR(params->bssid));
8576 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
8577 }
a0bdd191 8578
7ac7fd43
DS
8579 if (params->bssid_hint) {
8580 wpa_printf(MSG_DEBUG, " * bssid_hint=" MACSTR,
8581 MAC2STR(params->bssid_hint));
8582 NLA_PUT(msg, NL80211_ATTR_MAC_HINT, ETH_ALEN,
8583 params->bssid_hint);
8584 }
8585
cfaab580
ZY
8586 if (params->freq) {
8587 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
8588 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
30158a0d
SD
8589 drv->assoc_freq = params->freq;
8590 } else
8591 drv->assoc_freq = 0;
a0bdd191 8592
7ac7fd43
DS
8593 if (params->freq_hint) {
8594 wpa_printf(MSG_DEBUG, " * freq_hint=%d", params->freq_hint);
8595 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ_HINT,
8596 params->freq_hint);
8597 }
8598
1f6c0ab8
BS
8599 if (params->bg_scan_period >= 0) {
8600 wpa_printf(MSG_DEBUG, " * bg scan period=%d",
8601 params->bg_scan_period);
8602 NLA_PUT_U16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
8603 params->bg_scan_period);
8604 }
a0bdd191 8605
cfaab580
ZY
8606 if (params->ssid) {
8607 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
8608 params->ssid, params->ssid_len);
8609 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
8610 params->ssid);
8611 if (params->ssid_len > sizeof(drv->ssid))
8612 goto nla_put_failure;
8613 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
8614 drv->ssid_len = params->ssid_len;
8615 }
a0bdd191 8616
cfaab580
ZY
8617 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
8618 if (params->wpa_ie)
8619 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
8620 params->wpa_ie);
8621
64fa840a
JM
8622 if (params->wpa_proto) {
8623 enum nl80211_wpa_versions ver = 0;
cfaab580 8624
64fa840a
JM
8625 if (params->wpa_proto & WPA_PROTO_WPA)
8626 ver |= NL80211_WPA_VERSION_1;
8627 if (params->wpa_proto & WPA_PROTO_RSN)
8628 ver |= NL80211_WPA_VERSION_2;
cfaab580 8629
64fa840a 8630 wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
cfaab580
ZY
8631 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
8632 }
8633
4848a38d 8634 if (params->pairwise_suite != WPA_CIPHER_NONE) {
a0bdd191
JM
8635 u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
8636 wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
8637 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
cfaab580
ZY
8638 }
8639
ae6f9272
JM
8640 if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
8641 !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
8642 /*
8643 * This is likely to work even though many drivers do not
8644 * advertise support for operations without GTK.
8645 */
8646 wpa_printf(MSG_DEBUG, " * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
8647 } else if (params->group_suite != WPA_CIPHER_NONE) {
a0bdd191
JM
8648 u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
8649 wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
8650 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
cfaab580
ZY
8651 }
8652
4848a38d
JM
8653 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
8654 params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
8655 params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
8656 params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
163f801e
JM
8657 params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
8658 params->key_mgmt_suite == WPA_KEY_MGMT_OSEN) {
cfaab580
ZY
8659 int mgmt = WLAN_AKM_SUITE_PSK;
8660
8661 switch (params->key_mgmt_suite) {
4848a38d 8662 case WPA_KEY_MGMT_CCKM:
369c8d7b
JM
8663 mgmt = WLAN_AKM_SUITE_CCKM;
8664 break;
4848a38d 8665 case WPA_KEY_MGMT_IEEE8021X:
cfaab580
ZY
8666 mgmt = WLAN_AKM_SUITE_8021X;
8667 break;
4848a38d 8668 case WPA_KEY_MGMT_FT_IEEE8021X:
6a1ce395
DG
8669 mgmt = WLAN_AKM_SUITE_FT_8021X;
8670 break;
4848a38d 8671 case WPA_KEY_MGMT_FT_PSK:
6a1ce395
DG
8672 mgmt = WLAN_AKM_SUITE_FT_PSK;
8673 break;
163f801e
JM
8674 case WPA_KEY_MGMT_OSEN:
8675 mgmt = WLAN_AKM_SUITE_OSEN;
8676 break;
4848a38d 8677 case WPA_KEY_MGMT_PSK:
cfaab580
ZY
8678 default:
8679 mgmt = WLAN_AKM_SUITE_PSK;
8680 break;
8681 }
163f801e 8682 wpa_printf(MSG_DEBUG, " * akm=0x%x", mgmt);
cfaab580
ZY
8683 NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
8684 }
8685
a0bdd191
JM
8686 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
8687
8b706a99
JM
8688 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
8689 NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
a565084f 8690
80e8a5ee
BG
8691 if (params->disable_ht)
8692 NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
8693
8694 if (params->htcaps && params->htcaps_mask) {
8695 int sz = sizeof(struct ieee80211_ht_capabilities);
6d99bd80 8696 wpa_hexdump(MSG_DEBUG, " * htcaps", params->htcaps, sz);
80e8a5ee 8697 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
6d99bd80
JM
8698 wpa_hexdump(MSG_DEBUG, " * htcaps_mask",
8699 params->htcaps_mask, sz);
80e8a5ee
BG
8700 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
8701 params->htcaps_mask);
8702 }
8703
e9ee8dc3
JB
8704#ifdef CONFIG_VHT_OVERRIDES
8705 if (params->disable_vht) {
8706 wpa_printf(MSG_DEBUG, " * VHT disabled");
8707 NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
8708 }
8709
8710 if (params->vhtcaps && params->vhtcaps_mask) {
8711 int sz = sizeof(struct ieee80211_vht_capabilities);
6d99bd80 8712 wpa_hexdump(MSG_DEBUG, " * vhtcaps", params->vhtcaps, sz);
e9ee8dc3 8713 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
6d99bd80
JM
8714 wpa_hexdump(MSG_DEBUG, " * vhtcaps_mask",
8715 params->vhtcaps_mask, sz);
e9ee8dc3
JB
8716 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
8717 params->vhtcaps_mask);
8718 }
8719#endif /* CONFIG_VHT_OVERRIDES */
8720
a0bdd191
JM
8721 if (params->p2p)
8722 wpa_printf(MSG_DEBUG, " * P2P group");
8723
8724 return 0;
8725nla_put_failure:
8726 return -1;
8727}
8728
8729
8730static int wpa_driver_nl80211_try_connect(
8731 struct wpa_driver_nl80211_data *drv,
8732 struct wpa_driver_associate_params *params)
8733{
8734 struct nl_msg *msg;
8735 enum nl80211_auth_type type;
8736 int ret;
8737 int algs;
8738
8739 msg = nlmsg_alloc();
8740 if (!msg)
8741 return -1;
8742
8743 wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
8744 nl80211_cmd(drv, msg, 0, NL80211_CMD_CONNECT);
8745
8746 ret = nl80211_connect_common(drv, params, msg);
8747 if (ret)
8748 goto nla_put_failure;
8749
8750 algs = 0;
8751 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
8752 algs++;
8753 if (params->auth_alg & WPA_AUTH_ALG_SHARED)
8754 algs++;
8755 if (params->auth_alg & WPA_AUTH_ALG_LEAP)
8756 algs++;
8757 if (algs > 1) {
8758 wpa_printf(MSG_DEBUG, " * Leave out Auth Type for automatic "
8759 "selection");
8760 goto skip_auth_type;
8761 }
8762
8763 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
8764 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
8765 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
8766 type = NL80211_AUTHTYPE_SHARED_KEY;
8767 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
8768 type = NL80211_AUTHTYPE_NETWORK_EAP;
8769 else if (params->auth_alg & WPA_AUTH_ALG_FT)
8770 type = NL80211_AUTHTYPE_FT;
8771 else
8772 goto nla_put_failure;
8773
8774 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
8775 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
8776
8777skip_auth_type:
cfaab580
ZY
8778 ret = nl80211_set_conn_keys(params, msg);
8779 if (ret)
8780 goto nla_put_failure;
8781
8782 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8783 msg = NULL;
8784 if (ret) {
8785 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
8786 "(%s)", ret, strerror(-ret));
8787 goto nla_put_failure;
8788 }
8789 ret = 0;
8790 wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
8791
8792nla_put_failure:
8793 nlmsg_free(msg);
8794 return ret;
8795
8796}
8797
8798
a8c5b43a
CW
8799static int wpa_driver_nl80211_connect(
8800 struct wpa_driver_nl80211_data *drv,
8801 struct wpa_driver_associate_params *params)
8802{
8803 int ret = wpa_driver_nl80211_try_connect(drv, params);
8804 if (ret == -EALREADY) {
8805 /*
8806 * cfg80211 does not currently accept new connections if
8807 * we are already connected. As a workaround, force
8808 * disconnection and try again.
8809 */
8810 wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
8811 "disconnecting before reassociation "
8812 "attempt");
8813 if (wpa_driver_nl80211_disconnect(
8814 drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
8815 return -1;
a8c5b43a
CW
8816 ret = wpa_driver_nl80211_try_connect(drv, params);
8817 }
8818 return ret;
8819}
8820
8821
c2a04078
JM
8822static int wpa_driver_nl80211_associate(
8823 void *priv, struct wpa_driver_associate_params *params)
8824{
a2e40bb6
FF
8825 struct i802_bss *bss = priv;
8826 struct wpa_driver_nl80211_data *drv = bss->drv;
a0bdd191 8827 int ret;
c2a04078
JM
8828 struct nl_msg *msg;
8829
5cc4d64b 8830 if (params->mode == IEEE80211_MODE_AP)
1581b38b 8831 return wpa_driver_nl80211_ap(drv, params);
1581b38b 8832
5cc4d64b
JM
8833 if (params->mode == IEEE80211_MODE_IBSS)
8834 return wpa_driver_nl80211_ibss(drv, params);
8835
4a867032 8836 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
b1f625e0
EP
8837 enum nl80211_iftype nlmode = params->p2p ?
8838 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
8839
8840 if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
4a867032 8841 return -1;
cfaab580 8842 return wpa_driver_nl80211_connect(drv, params);
4a867032 8843 }
cfaab580 8844
add9b7a4 8845 nl80211_mark_disconnected(drv);
c2a04078
JM
8846
8847 msg = nlmsg_alloc();
8848 if (!msg)
8849 return -1;
8850
8851 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
8852 drv->ifindex);
9fb04070 8853 nl80211_cmd(drv, msg, 0, NL80211_CMD_ASSOCIATE);
c2a04078 8854
a0bdd191
JM
8855 ret = nl80211_connect_common(drv, params, msg);
8856 if (ret)
8857 goto nla_put_failure;
01652550 8858
62fa124c
JM
8859 if (params->prev_bssid) {
8860 wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
8861 MAC2STR(params->prev_bssid));
8862 NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
8863 params->prev_bssid);
8864 }
8865
c2a04078
JM
8866 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8867 msg = NULL;
8868 if (ret) {
3b7ea880
BG
8869 wpa_dbg(drv->ctx, MSG_DEBUG,
8870 "nl80211: MLME command failed (assoc): ret=%d (%s)",
8871 ret, strerror(-ret));
8856462d 8872 nl80211_dump_scan(drv);
c2a04078
JM
8873 goto nla_put_failure;
8874 }
8875 ret = 0;
8876 wpa_printf(MSG_DEBUG, "nl80211: Association request send "
8877 "successfully");
8878
8879nla_put_failure:
8880 nlmsg_free(msg);
8881 return ret;
8882}
3f5285e8
JM
8883
8884
ad1e68e6 8885static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
a1922f93 8886 int ifindex, enum nl80211_iftype mode)
3f5285e8 8887{
3f5285e8 8888 struct nl_msg *msg;
ad1e68e6
JM
8889 int ret = -ENOBUFS;
8890
a1922f93
JM
8891 wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
8892 ifindex, mode, nl80211_iftype_str(mode));
8893
ad1e68e6
JM
8894 msg = nlmsg_alloc();
8895 if (!msg)
8896 return -ENOMEM;
8897
9fb04070 8898 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_INTERFACE);
834ee56f 8899 if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
f632e483 8900 goto nla_put_failure;
ad1e68e6
JM
8901 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
8902
8903 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 8904 msg = NULL;
ad1e68e6
JM
8905 if (!ret)
8906 return 0;
8907nla_put_failure:
5883168a 8908 nlmsg_free(msg);
ad1e68e6
JM
8909 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
8910 " %d (%s)", ifindex, mode, ret, strerror(-ret));
8911 return ret;
8912}
8913
8914
b1f625e0
EP
8915static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
8916 enum nl80211_iftype nlmode)
ad1e68e6 8917{
a2e40bb6 8918 struct wpa_driver_nl80211_data *drv = bss->drv;
ad1e68e6 8919 int ret = -1;
26af9dca 8920 int i;
86957e62 8921 int was_ap = is_ap_interface(drv->nlmode);
671a5039 8922 int res;
1581b38b 8923
671a5039 8924 res = nl80211_set_mode(drv, drv->ifindex, nlmode);
8e12685c
AS
8925 if (res && nlmode == nl80211_get_ifmode(bss))
8926 res = 0;
8927
671a5039 8928 if (res == 0) {
ad1e68e6 8929 drv->nlmode = nlmode;
460456f8
JM
8930 ret = 0;
8931 goto done;
ad1e68e6 8932 }
3f5285e8 8933
671a5039
JM
8934 if (res == -ENODEV)
8935 return -1;
8936
460456f8 8937 if (nlmode == drv->nlmode) {
c6e8e8e4
JM
8938 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
8939 "requested mode - ignore error");
460456f8
JM
8940 ret = 0;
8941 goto done; /* Already in the requested mode */
8942 }
3f5285e8 8943
3f5285e8
JM
8944 /* mac80211 doesn't allow mode changes while the device is up, so
8945 * take the device down, try to set the mode again, and bring the
8946 * device back up.
8947 */
26af9dca
JM
8948 wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
8949 "interface down");
8950 for (i = 0; i < 10; i++) {
91724d6f 8951 res = i802_set_iface_flags(bss, 0);
6e8183d7
JM
8952 if (res == -EACCES || res == -ENODEV)
8953 break;
8954 if (res == 0) {
26af9dca
JM
8955 /* Try to set the mode again while the interface is
8956 * down */
8957 ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
6e8183d7
JM
8958 if (ret == -EACCES)
8959 break;
91724d6f 8960 res = i802_set_iface_flags(bss, 1);
6e8183d7 8961 if (res && !ret)
26af9dca 8962 ret = -1;
6e8183d7 8963 else if (ret != -EBUSY)
26af9dca
JM
8964 break;
8965 } else
8966 wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
8967 "interface down");
8968 os_sleep(0, 100000);
3f5285e8
JM
8969 }
8970
c6e8e8e4
JM
8971 if (!ret) {
8972 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
8973 "interface is down");
ad1e68e6 8974 drv->nlmode = nlmode;
7d9c3698 8975 drv->ignore_if_down_event = 1;
c6e8e8e4 8976 }
ad1e68e6 8977
460456f8 8978done:
3fd1cefb
JB
8979 if (ret) {
8980 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
8981 "from %d failed", nlmode, drv->nlmode);
8982 return ret;
8983 }
8984
6a71413e 8985 if (is_p2p_net_interface(nlmode))
edb9bfba 8986 nl80211_disable_11b_rates(drv, drv->ifindex, 1);
1d0c6fb1
JM
8987 else if (drv->disabled_11b_rates)
8988 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
edb9bfba 8989
3fd1cefb 8990 if (is_ap_interface(nlmode)) {
36488c05 8991 nl80211_mgmt_unsubscribe(bss, "start AP");
460456f8 8992 /* Setup additional AP mode functionality if needed */
3fd1cefb 8993 if (nl80211_setup_ap(bss))
460456f8 8994 return -1;
3fd1cefb 8995 } else if (was_ap) {
460456f8 8996 /* Remove additional AP mode functionality */
3fd1cefb 8997 nl80211_teardown_ap(bss);
a11241fa 8998 } else {
36488c05 8999 nl80211_mgmt_unsubscribe(bss, "mode change");
460456f8 9000 }
460456f8 9001
873d0fcf 9002 if (!bss->in_deinit && !is_ap_interface(nlmode) &&
a11241fa
JB
9003 nl80211_mgmt_subscribe_non_ap(bss) < 0)
9004 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
9005 "frame processing - ignore for now");
08359050 9006
3fd1cefb 9007 return 0;
3f5285e8
JM
9008}
9009
9010
65d645ce
AS
9011static int dfs_info_handler(struct nl_msg *msg, void *arg)
9012{
9013 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9014 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9015 int *dfs_capability_ptr = arg;
9016
9017 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9018 genlmsg_attrlen(gnlh, 0), NULL);
9019
9020 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9021 struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
9022 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
9023
9024 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
9025 nla_data(nl_vend), nla_len(nl_vend), NULL);
9026
9027 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
9028 u32 val;
9029 val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
9030 wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
9031 val);
9032 *dfs_capability_ptr = val;
9033 }
9034 }
9035
9036 return NL_SKIP;
9037}
9038
9039
3f5285e8
JM
9040static int wpa_driver_nl80211_get_capa(void *priv,
9041 struct wpa_driver_capa *capa)
9042{
a2e40bb6
FF
9043 struct i802_bss *bss = priv;
9044 struct wpa_driver_nl80211_data *drv = bss->drv;
65d645ce
AS
9045 struct nl_msg *msg;
9046 int dfs_capability = 0;
9047 int ret = 0;
9048
3f5285e8
JM
9049 if (!drv->has_capability)
9050 return -1;
9051 os_memcpy(capa, &drv->capa, sizeof(*capa));
8cd6b7bc
JB
9052 if (drv->extended_capa && drv->extended_capa_mask) {
9053 capa->extended_capa = drv->extended_capa;
9054 capa->extended_capa_mask = drv->extended_capa_mask;
9055 capa->extended_capa_len = drv->extended_capa_len;
9056 }
851b0c55
JM
9057
9058 if ((capa->flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
9059 !drv->allow_p2p_device) {
9060 wpa_printf(MSG_DEBUG, "nl80211: Do not indicate P2P_DEVICE support (p2p_device=1 driver param not specified)");
9061 capa->flags &= ~WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
9062 }
9063
65d645ce
AS
9064 if (drv->dfs_vendor_cmd_avail == 1) {
9065 msg = nlmsg_alloc();
9066 if (!msg)
9067 return -ENOMEM;
9068
9069 nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
9070
9071 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9072 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
9073 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9074 QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY);
9075
9076 ret = send_and_recv_msgs(drv, msg, dfs_info_handler,
9077 &dfs_capability);
9078 if (!ret) {
9079 if (dfs_capability)
9080 capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
9081 }
9082 }
9083
9084 return ret;
9085
9086 nla_put_failure:
9087 nlmsg_free(msg);
9088 return -ENOBUFS;
3f5285e8
JM
9089}
9090
9091
9092static int wpa_driver_nl80211_set_operstate(void *priv, int state)
9093{
a2e40bb6
FF
9094 struct i802_bss *bss = priv;
9095 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 9096
90a545cc
JM
9097 wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
9098 bss->ifname, drv->operstate, state,
9099 state ? "UP" : "DORMANT");
3f5285e8 9100 drv->operstate = state;
36d84860 9101 return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
e2d02c29 9102 state ? IF_OPER_UP : IF_OPER_DORMANT);
3f5285e8
JM
9103}
9104
01652550
JM
9105
9106static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
9107{
a2e40bb6
FF
9108 struct i802_bss *bss = priv;
9109 struct wpa_driver_nl80211_data *drv = bss->drv;
01652550
JM
9110 struct nl_msg *msg;
9111 struct nl80211_sta_flag_update upd;
2eef5177
JM
9112 int ret = -ENOBUFS;
9113
9114 if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
9115 wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
9116 return 0;
9117 }
01652550 9118
1ba51ec0
JM
9119 wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
9120 MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
9121
01652550
JM
9122 msg = nlmsg_alloc();
9123 if (!msg)
9124 return -ENOMEM;
9125
9fb04070 9126 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
01652550
JM
9127
9128 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 9129 if_nametoindex(bss->ifname));
01652550
JM
9130 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
9131
9132 os_memset(&upd, 0, sizeof(upd));
9133 upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
9134 if (authorized)
9135 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
9136 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
9137
2eef5177
JM
9138 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9139 msg = NULL;
9140 if (!ret)
9141 return 0;
01652550 9142 nla_put_failure:
5883168a 9143 nlmsg_free(msg);
2eef5177
JM
9144 wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
9145 ret, strerror(-ret));
9146 return ret;
01652550
JM
9147}
9148
3f5285e8 9149
f07ead6a
JM
9150/* Set kernel driver on given frequency (MHz) */
9151static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
c5121837 9152{
f07ead6a 9153 struct i802_bss *bss = priv;
13a524a3 9154 return nl80211_set_channel(bss, freq, 0);
c5121837
JM
9155}
9156
f7b3920c 9157
c5121837
JM
9158static inline int min_int(int a, int b)
9159{
9160 if (a < b)
9161 return a;
9162 return b;
9163}
9164
9165
9166static int get_key_handler(struct nl_msg *msg, void *arg)
9167{
9168 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9169 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9170
9171 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9172 genlmsg_attrlen(gnlh, 0), NULL);
9173
9174 /*
9175 * TODO: validate the key index and mac address!
9176 * Otherwise, there's a race condition as soon as
9177 * the kernel starts sending key notifications.
9178 */
9179
9180 if (tb[NL80211_ATTR_KEY_SEQ])
9181 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
9182 min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
9183 return NL_SKIP;
9184}
9185
9186
9187static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
9188 int idx, u8 *seq)
9189{
a2e40bb6
FF
9190 struct i802_bss *bss = priv;
9191 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9192 struct nl_msg *msg;
9193
9194 msg = nlmsg_alloc();
9195 if (!msg)
9196 return -ENOMEM;
9197
9fb04070 9198 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_KEY);
c5121837
JM
9199
9200 if (addr)
9201 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
9202 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
9203 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
9204
9205 memset(seq, 0, 6);
9206
9207 return send_and_recv_msgs(drv, msg, get_key_handler, seq);
9208 nla_put_failure:
9e088e74 9209 nlmsg_free(msg);
c5121837
JM
9210 return -ENOBUFS;
9211}
9212
9213
c5121837
JM
9214static int i802_set_rts(void *priv, int rts)
9215{
a2e40bb6
FF
9216 struct i802_bss *bss = priv;
9217 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
9218 struct nl_msg *msg;
9219 int ret = -ENOBUFS;
9220 u32 val;
c5121837 9221
ad649451
JM
9222 msg = nlmsg_alloc();
9223 if (!msg)
9224 return -ENOMEM;
c5121837 9225
ad649451
JM
9226 if (rts >= 2347)
9227 val = (u32) -1;
9228 else
9229 val = rts;
c5121837 9230
9fb04070 9231 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
ad649451
JM
9232 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9233 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
9234
9235 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 9236 msg = NULL;
ad649451
JM
9237 if (!ret)
9238 return 0;
9239nla_put_failure:
5883168a 9240 nlmsg_free(msg);
ad649451
JM
9241 wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
9242 "%d (%s)", rts, ret, strerror(-ret));
9243 return ret;
c5121837
JM
9244}
9245
9246
9247static int i802_set_frag(void *priv, int frag)
9248{
a2e40bb6
FF
9249 struct i802_bss *bss = priv;
9250 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
9251 struct nl_msg *msg;
9252 int ret = -ENOBUFS;
9253 u32 val;
c5121837 9254
ad649451
JM
9255 msg = nlmsg_alloc();
9256 if (!msg)
9257 return -ENOMEM;
c5121837 9258
ad649451
JM
9259 if (frag >= 2346)
9260 val = (u32) -1;
9261 else
9262 val = frag;
c5121837 9263
9fb04070 9264 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
ad649451
JM
9265 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9266 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
9267
9268 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 9269 msg = NULL;
ad649451
JM
9270 if (!ret)
9271 return 0;
9272nla_put_failure:
5883168a 9273 nlmsg_free(msg);
ad649451
JM
9274 wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
9275 "%d: %d (%s)", frag, ret, strerror(-ret));
9276 return ret;
c5121837
JM
9277}
9278
9279
c5121837
JM
9280static int i802_flush(void *priv)
9281{
a2e40bb6
FF
9282 struct i802_bss *bss = priv;
9283 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 9284 struct nl_msg *msg;
82554b10 9285 int res;
c5121837
JM
9286
9287 msg = nlmsg_alloc();
9288 if (!msg)
9289 return -1;
9290
83e7bb0e
JM
9291 wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
9292 bss->ifname);
9fb04070 9293 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
c5121837
JM
9294
9295 /*
9296 * XXX: FIX! this needs to flush all VLANs too
9297 */
9298 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 9299 if_nametoindex(bss->ifname));
c5121837 9300
82554b10
JM
9301 res = send_and_recv_msgs(drv, msg, NULL, NULL);
9302 if (res) {
9303 wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
9304 "(%s)", res, strerror(-res));
9305 }
9306 return res;
c5121837 9307 nla_put_failure:
9e088e74 9308 nlmsg_free(msg);
c5121837
JM
9309 return -ENOBUFS;
9310}
9311
9312
9313static int get_sta_handler(struct nl_msg *msg, void *arg)
9314{
9315 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9316 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9317 struct hostap_sta_driver_data *data = arg;
9318 struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
9319 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
9320 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
9321 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
9322 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
9323 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
9324 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
dc7785f8 9325 [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
c5121837
JM
9326 };
9327
9328 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9329 genlmsg_attrlen(gnlh, 0), NULL);
9330
9331 /*
9332 * TODO: validate the interface and mac address!
9333 * Otherwise, there's a race condition as soon as
9334 * the kernel starts sending station notifications.
9335 */
9336
9337 if (!tb[NL80211_ATTR_STA_INFO]) {
9338 wpa_printf(MSG_DEBUG, "sta stats missing!");
9339 return NL_SKIP;
9340 }
9341 if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
9342 tb[NL80211_ATTR_STA_INFO],
9343 stats_policy)) {
9344 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
9345 return NL_SKIP;
9346 }
9347
9348 if (stats[NL80211_STA_INFO_INACTIVE_TIME])
9349 data->inactive_msec =
9350 nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
9351 if (stats[NL80211_STA_INFO_RX_BYTES])
9352 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
9353 if (stats[NL80211_STA_INFO_TX_BYTES])
9354 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
9355 if (stats[NL80211_STA_INFO_RX_PACKETS])
9356 data->rx_packets =
9357 nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
9358 if (stats[NL80211_STA_INFO_TX_PACKETS])
9359 data->tx_packets =
9360 nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
dc7785f8
YZ
9361 if (stats[NL80211_STA_INFO_TX_FAILED])
9362 data->tx_retry_failed =
9363 nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
c5121837
JM
9364
9365 return NL_SKIP;
9366}
9367
9ebce9c5
JM
9368static int i802_read_sta_data(struct i802_bss *bss,
9369 struct hostap_sta_driver_data *data,
c5121837
JM
9370 const u8 *addr)
9371{
a2e40bb6 9372 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9373 struct nl_msg *msg;
9374
9375 os_memset(data, 0, sizeof(*data));
9376 msg = nlmsg_alloc();
9377 if (!msg)
9378 return -ENOMEM;
9379
9fb04070 9380 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
c5121837
JM
9381
9382 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
a2e40bb6 9383 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
9384
9385 return send_and_recv_msgs(drv, msg, get_sta_handler, data);
9386 nla_put_failure:
9e088e74 9387 nlmsg_free(msg);
c5121837
JM
9388 return -ENOBUFS;
9389}
9390
9391
c5121837
JM
9392static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
9393 int cw_min, int cw_max, int burst_time)
9394{
a2e40bb6
FF
9395 struct i802_bss *bss = priv;
9396 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9397 struct nl_msg *msg;
9398 struct nlattr *txq, *params;
9399
9400 msg = nlmsg_alloc();
9401 if (!msg)
9402 return -1;
9403
9fb04070 9404 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
c5121837 9405
a2e40bb6 9406 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
9407
9408 txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
9409 if (!txq)
9410 goto nla_put_failure;
9411
9412 /* We are only sending parameters for a single TXQ at a time */
9413 params = nla_nest_start(msg, 1);
9414 if (!params)
9415 goto nla_put_failure;
9416
7e3c1781
JM
9417 switch (queue) {
9418 case 0:
9419 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO);
9420 break;
9421 case 1:
9422 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI);
9423 break;
9424 case 2:
9425 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE);
9426 break;
9427 case 3:
9428 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK);
9429 break;
9430 }
c5121837
JM
9431 /* Burst time is configured in units of 0.1 msec and TXOP parameter in
9432 * 32 usec, so need to convert the value here. */
9433 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
9434 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
9435 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
9436 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
9437
9438 nla_nest_end(msg, params);
9439
9440 nla_nest_end(msg, txq);
9441
9442 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
9443 return 0;
9e088e74 9444 msg = NULL;
c5121837 9445 nla_put_failure:
9e088e74 9446 nlmsg_free(msg);
c5121837
JM
9447 return -1;
9448}
9449
9450
9ebce9c5 9451static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
c5121837
JM
9452 const char *ifname, int vlan_id)
9453{
a2e40bb6 9454 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 9455 struct nl_msg *msg;
cd1d72c1 9456 int ret = -ENOBUFS;
c5121837
JM
9457
9458 msg = nlmsg_alloc();
9459 if (!msg)
9460 return -ENOMEM;
9461
bbc706a3
JM
9462 wpa_printf(MSG_DEBUG, "nl80211: %s[%d]: set_sta_vlan(" MACSTR
9463 ", ifname=%s[%d], vlan_id=%d)",
9464 bss->ifname, if_nametoindex(bss->ifname),
9465 MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
9fb04070 9466 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
c5121837
JM
9467
9468 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 9469 if_nametoindex(bss->ifname));
c5121837 9470 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1c766b09 9471 NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
c5121837
JM
9472 if_nametoindex(ifname));
9473
cd1d72c1 9474 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9e088e74 9475 msg = NULL;
cd1d72c1
JM
9476 if (ret < 0) {
9477 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
9478 MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
9479 MAC2STR(addr), ifname, vlan_id, ret,
9480 strerror(-ret));
9481 }
c5121837 9482 nla_put_failure:
9e088e74 9483 nlmsg_free(msg);
cd1d72c1 9484 return ret;
c5121837
JM
9485}
9486
fbbfcbac 9487
c5121837
JM
9488static int i802_get_inact_sec(void *priv, const u8 *addr)
9489{
9490 struct hostap_sta_driver_data data;
9491 int ret;
9492
9493 data.inactive_msec = (unsigned long) -1;
9494 ret = i802_read_sta_data(priv, &data, addr);
9495 if (ret || data.inactive_msec == (unsigned long) -1)
9496 return -1;
9497 return data.inactive_msec / 1000;
9498}
9499
9500
9501static int i802_sta_clear_stats(void *priv, const u8 *addr)
9502{
9503#if 0
9504 /* TODO */
9505#endif
9506 return 0;
9507}
9508
9509
731723a5
JM
9510static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
9511 int reason)
c5121837 9512{
a2e40bb6 9513 struct i802_bss *bss = priv;
e1bd4e19 9514 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9515 struct ieee80211_mgmt mgmt;
9516
e1bd4e19
AT
9517 if (drv->device_ap_sme)
9518 return wpa_driver_nl80211_sta_remove(bss, addr);
9519
c5121837
JM
9520 memset(&mgmt, 0, sizeof(mgmt));
9521 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
9522 WLAN_FC_STYPE_DEAUTH);
9523 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
9524 memcpy(mgmt.sa, own_addr, ETH_ALEN);
9525 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 9526 mgmt.u.deauth.reason_code = host_to_le16(reason);
a2e40bb6 9527 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 9528 IEEE80211_HDRLEN +
9ebce9c5
JM
9529 sizeof(mgmt.u.deauth), 0, 0, 0, 0,
9530 0);
c5121837
JM
9531}
9532
9533
731723a5
JM
9534static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
9535 int reason)
c5121837 9536{
a2e40bb6 9537 struct i802_bss *bss = priv;
e1bd4e19 9538 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9539 struct ieee80211_mgmt mgmt;
9540
e1bd4e19
AT
9541 if (drv->device_ap_sme)
9542 return wpa_driver_nl80211_sta_remove(bss, addr);
9543
c5121837
JM
9544 memset(&mgmt, 0, sizeof(mgmt));
9545 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
9546 WLAN_FC_STYPE_DISASSOC);
9547 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
9548 memcpy(mgmt.sa, own_addr, ETH_ALEN);
9549 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 9550 mgmt.u.disassoc.reason_code = host_to_le16(reason);
a2e40bb6 9551 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 9552 IEEE80211_HDRLEN +
9ebce9c5
JM
9553 sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
9554 0);
c5121837
JM
9555}
9556
9557
9b4d9c8b
JM
9558static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
9559{
9560 char buf[200], *pos, *end;
9561 int i, res;
9562
9563 pos = buf;
9564 end = pos + sizeof(buf);
9565
9566 for (i = 0; i < drv->num_if_indices; i++) {
9567 if (!drv->if_indices[i])
9568 continue;
9569 res = os_snprintf(pos, end - pos, " %d", drv->if_indices[i]);
9570 if (res < 0 || res >= end - pos)
9571 break;
9572 pos += res;
9573 }
9574 *pos = '\0';
9575
9576 wpa_printf(MSG_DEBUG, "nl80211: if_indices[%d]:%s",
9577 drv->num_if_indices, buf);
9578}
9579
9580
f07ead6a
JM
9581static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9582{
9583 int i;
9584 int *old;
9585
9586 wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
9587 ifidx);
b36935be
MB
9588 if (have_ifidx(drv, ifidx)) {
9589 wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
9590 ifidx);
9591 return;
9592 }
f07ead6a
JM
9593 for (i = 0; i < drv->num_if_indices; i++) {
9594 if (drv->if_indices[i] == 0) {
9595 drv->if_indices[i] = ifidx;
9b4d9c8b 9596 dump_ifidx(drv);
f07ead6a
JM
9597 return;
9598 }
9599 }
9600
9601 if (drv->if_indices != drv->default_if_indices)
9602 old = drv->if_indices;
9603 else
9604 old = NULL;
9605
067ffa26
JM
9606 drv->if_indices = os_realloc_array(old, drv->num_if_indices + 1,
9607 sizeof(int));
f07ead6a
JM
9608 if (!drv->if_indices) {
9609 if (!old)
9610 drv->if_indices = drv->default_if_indices;
9611 else
9612 drv->if_indices = old;
9613 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
9614 "interfaces");
9615 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
9616 return;
9617 } else if (!old)
9618 os_memcpy(drv->if_indices, drv->default_if_indices,
9619 sizeof(drv->default_if_indices));
9620 drv->if_indices[drv->num_if_indices] = ifidx;
9621 drv->num_if_indices++;
9b4d9c8b 9622 dump_ifidx(drv);
f07ead6a
JM
9623}
9624
9625
9626static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9627{
9628 int i;
9629
9630 for (i = 0; i < drv->num_if_indices; i++) {
9631 if (drv->if_indices[i] == ifidx) {
9632 drv->if_indices[i] = 0;
9633 break;
9634 }
9635 }
9b4d9c8b 9636 dump_ifidx(drv);
f07ead6a
JM
9637}
9638
9639
9640static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9641{
9642 int i;
9643
9644 for (i = 0; i < drv->num_if_indices; i++)
9645 if (drv->if_indices[i] == ifidx)
9646 return 1;
9647
9648 return 0;
9649}
9650
9651
9652static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
0e80ea2c 9653 const char *bridge_ifname, char *ifname_wds)
f07ead6a
JM
9654{
9655 struct i802_bss *bss = priv;
9656 struct wpa_driver_nl80211_data *drv = bss->drv;
9657 char name[IFNAMSIZ + 1];
9658
9659 os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
69dd2967
SM
9660 if (ifname_wds)
9661 os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
9662
f07ead6a
JM
9663 wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
9664 " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
9665 if (val) {
9666 if (!if_nametoindex(name)) {
9667 if (nl80211_create_iface(drv, name,
9668 NL80211_IFTYPE_AP_VLAN,
2aec4f3c
JM
9669 bss->addr, 1, NULL, NULL, 0) <
9670 0)
f07ead6a
JM
9671 return -1;
9672 if (bridge_ifname &&
c81eff1a
BG
9673 linux_br_add_if(drv->global->ioctl_sock,
9674 bridge_ifname, name) < 0)
f07ead6a
JM
9675 return -1;
9676 }
75227f3a
JM
9677 if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
9678 wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
9679 "interface %s up", name);
9680 }
f07ead6a
JM
9681 return i802_set_sta_vlan(priv, addr, name, 0);
9682 } else {
c34e618d
FF
9683 if (bridge_ifname)
9684 linux_br_del_if(drv->global->ioctl_sock, bridge_ifname,
9685 name);
9686
f07ead6a 9687 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
d0595b25
FF
9688 nl80211_remove_iface(drv, if_nametoindex(name));
9689 return 0;
f07ead6a
JM
9690 }
9691}
9692
9693
9694static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
9695{
9696 struct wpa_driver_nl80211_data *drv = eloop_ctx;
9697 struct sockaddr_ll lladdr;
9698 unsigned char buf[3000];
9699 int len;
9700 socklen_t fromlen = sizeof(lladdr);
9701
9702 len = recvfrom(sock, buf, sizeof(buf), 0,
9703 (struct sockaddr *)&lladdr, &fromlen);
9704 if (len < 0) {
7ac3616d
JM
9705 wpa_printf(MSG_ERROR, "nl80211: EAPOL recv failed: %s",
9706 strerror(errno));
f07ead6a
JM
9707 return;
9708 }
9709
9710 if (have_ifidx(drv, lladdr.sll_ifindex))
9711 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
9712}
9713
9714
94627f6c 9715static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
e17a2477 9716 struct i802_bss *bss,
94627f6c
JM
9717 const char *brname, const char *ifname)
9718{
9719 int ifindex;
9720 char in_br[IFNAMSIZ];
9721
e17a2477 9722 os_strlcpy(bss->brname, brname, IFNAMSIZ);
94627f6c
JM
9723 ifindex = if_nametoindex(brname);
9724 if (ifindex == 0) {
9725 /*
9726 * Bridge was configured, but the bridge device does
9727 * not exist. Try to add it now.
9728 */
c81eff1a 9729 if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
94627f6c
JM
9730 wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
9731 "bridge interface %s: %s",
9732 brname, strerror(errno));
9733 return -1;
9734 }
e17a2477 9735 bss->added_bridge = 1;
94627f6c
JM
9736 add_ifidx(drv, if_nametoindex(brname));
9737 }
9738
9739 if (linux_br_get(in_br, ifname) == 0) {
9740 if (os_strcmp(in_br, brname) == 0)
9741 return 0; /* already in the bridge */
9742
9743 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
9744 "bridge %s", ifname, in_br);
c81eff1a
BG
9745 if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
9746 0) {
94627f6c
JM
9747 wpa_printf(MSG_ERROR, "nl80211: Failed to "
9748 "remove interface %s from bridge "
9749 "%s: %s",
9750 ifname, brname, strerror(errno));
9751 return -1;
9752 }
9753 }
9754
9755 wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
9756 ifname, brname);
c81eff1a 9757 if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
94627f6c
JM
9758 wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
9759 "into bridge %s: %s",
9760 ifname, brname, strerror(errno));
9761 return -1;
9762 }
e17a2477 9763 bss->added_if_into_bridge = 1;
94627f6c
JM
9764
9765 return 0;
9766}
9767
9768
92f475b4
JM
9769static void *i802_init(struct hostapd_data *hapd,
9770 struct wpa_init_params *params)
c5121837
JM
9771{
9772 struct wpa_driver_nl80211_data *drv;
a2e40bb6 9773 struct i802_bss *bss;
c5121837 9774 size_t i;
94627f6c
JM
9775 char brname[IFNAMSIZ];
9776 int ifindex, br_ifindex;
9777 int br_added = 0;
c5121837 9778
0d547d5f
JM
9779 bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
9780 params->global_priv, 1,
9781 params->bssid);
a2e40bb6 9782 if (bss == NULL)
c5121837 9783 return NULL;
c5121837 9784
a2e40bb6 9785 drv = bss->drv;
7635bfb0 9786
94627f6c
JM
9787 if (linux_br_get(brname, params->ifname) == 0) {
9788 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
9789 params->ifname, brname);
9790 br_ifindex = if_nametoindex(brname);
9791 } else {
9792 brname[0] = '\0';
9793 br_ifindex = 0;
9794 }
9795
92f475b4 9796 for (i = 0; i < params->num_bridge; i++) {
94627f6c
JM
9797 if (params->bridge[i]) {
9798 ifindex = if_nametoindex(params->bridge[i]);
9799 if (ifindex)
9800 add_ifidx(drv, ifindex);
9801 if (ifindex == br_ifindex)
9802 br_added = 1;
9803 }
c5121837 9804 }
94627f6c
JM
9805 if (!br_added && br_ifindex &&
9806 (params->num_bridge == 0 || !params->bridge[0]))
9807 add_ifidx(drv, br_ifindex);
c5121837 9808
ad1e68e6
JM
9809 /* start listening for EAPOL on the default AP interface */
9810 add_ifidx(drv, drv->ifindex);
9811
94627f6c 9812 if (params->num_bridge && params->bridge[0] &&
e17a2477 9813 i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
94627f6c
JM
9814 goto failed;
9815
ad1e68e6
JM
9816 drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
9817 if (drv->eapol_sock < 0) {
7ac3616d
JM
9818 wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
9819 strerror(errno));
bbaf0837 9820 goto failed;
ad1e68e6
JM
9821 }
9822
9823 if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
9824 {
7ac3616d 9825 wpa_printf(MSG_INFO, "nl80211: Could not register read socket for eapol");
c5121837 9826 goto failed;
ad1e68e6
JM
9827 }
9828
c81eff1a
BG
9829 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
9830 params->own_addr))
bbaf0837 9831 goto failed;
c5121837 9832
341eebee
JB
9833 memcpy(bss->addr, params->own_addr, ETH_ALEN);
9834
a2e40bb6 9835 return bss;
c5121837
JM
9836
9837failed:
7635bfb0 9838 wpa_driver_nl80211_deinit(bss);
bbaf0837
JM
9839 return NULL;
9840}
c5121837 9841
c5121837 9842
bbaf0837
JM
9843static void i802_deinit(void *priv)
9844{
9ebce9c5
JM
9845 struct i802_bss *bss = priv;
9846 wpa_driver_nl80211_deinit(bss);
c5121837
JM
9847}
9848
c5121837 9849
22a7c9d7
JM
9850static enum nl80211_iftype wpa_driver_nl80211_if_type(
9851 enum wpa_driver_if_type type)
9852{
9853 switch (type) {
9854 case WPA_IF_STATION:
9f51b113 9855 return NL80211_IFTYPE_STATION;
75bde05d
JM
9856 case WPA_IF_P2P_CLIENT:
9857 case WPA_IF_P2P_GROUP:
9f51b113 9858 return NL80211_IFTYPE_P2P_CLIENT;
22a7c9d7
JM
9859 case WPA_IF_AP_VLAN:
9860 return NL80211_IFTYPE_AP_VLAN;
9861 case WPA_IF_AP_BSS:
9862 return NL80211_IFTYPE_AP;
9f51b113
JB
9863 case WPA_IF_P2P_GO:
9864 return NL80211_IFTYPE_P2P_GO;
7aad838c
NS
9865 case WPA_IF_P2P_DEVICE:
9866 return NL80211_IFTYPE_P2P_DEVICE;
22a7c9d7
JM
9867 }
9868 return -1;
9869}
9870
9871
482856c8
JM
9872#ifdef CONFIG_P2P
9873
f2ed8023
JM
9874static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
9875{
9876 struct wpa_driver_nl80211_data *drv;
9877 dl_list_for_each(drv, &global->interfaces,
9878 struct wpa_driver_nl80211_data, list) {
834ee56f 9879 if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
f2ed8023
JM
9880 return 1;
9881 }
9882 return 0;
9883}
9884
9885
9886static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data *drv,
9887 u8 *new_addr)
9888{
9889 unsigned int idx;
9890
9891 if (!drv->global)
9892 return -1;
9893
834ee56f 9894 os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
f2ed8023 9895 for (idx = 0; idx < 64; idx++) {
834ee56f 9896 new_addr[0] = drv->first_bss->addr[0] | 0x02;
f2ed8023
JM
9897 new_addr[0] ^= idx << 2;
9898 if (!nl80211_addr_in_use(drv->global, new_addr))
9899 break;
9900 }
9901 if (idx == 64)
9902 return -1;
9903
9904 wpa_printf(MSG_DEBUG, "nl80211: Assigned new P2P Interface Address "
9905 MACSTR, MAC2STR(new_addr));
9906
9907 return 0;
9908}
9909
482856c8
JM
9910#endif /* CONFIG_P2P */
9911
f2ed8023 9912
f632e483
AS
9913struct wdev_info {
9914 u64 wdev_id;
9915 int wdev_id_set;
9916 u8 macaddr[ETH_ALEN];
9917};
9918
9919static int nl80211_wdev_handler(struct nl_msg *msg, void *arg)
e472e1b4
AS
9920{
9921 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9922 struct nlattr *tb[NL80211_ATTR_MAX + 1];
f632e483 9923 struct wdev_info *wi = arg;
e472e1b4
AS
9924
9925 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9926 genlmsg_attrlen(gnlh, 0), NULL);
9927 if (tb[NL80211_ATTR_WDEV]) {
f632e483
AS
9928 wi->wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
9929 wi->wdev_id_set = 1;
e472e1b4
AS
9930 }
9931
9932 if (tb[NL80211_ATTR_MAC])
f632e483 9933 os_memcpy(wi->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
e472e1b4
AS
9934 ETH_ALEN);
9935
9936 return NL_SKIP;
9937}
9938
9939
7ab68865 9940static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
8043e725 9941 const char *ifname, const u8 *addr,
f3585c8a 9942 void *bss_ctx, void **drv_priv,
e17a2477 9943 char *force_ifname, u8 *if_addr,
2aec4f3c 9944 const char *bridge, int use_existing)
22a7c9d7 9945{
e472e1b4 9946 enum nl80211_iftype nlmode;
a2e40bb6
FF
9947 struct i802_bss *bss = priv;
9948 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7 9949 int ifidx;
2aec4f3c 9950 int added = 1;
22a7c9d7 9951
f3585c8a
JM
9952 if (addr)
9953 os_memcpy(if_addr, addr, ETH_ALEN);
e472e1b4
AS
9954 nlmode = wpa_driver_nl80211_if_type(type);
9955 if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
f632e483
AS
9956 struct wdev_info p2pdev_info;
9957
9958 os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
e472e1b4 9959 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
f632e483 9960 0, nl80211_wdev_handler,
2aec4f3c 9961 &p2pdev_info, use_existing);
f632e483 9962 if (!p2pdev_info.wdev_id_set || ifidx != 0) {
e472e1b4
AS
9963 wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
9964 ifname);
e472e1b4
AS
9965 return -1;
9966 }
f632e483
AS
9967
9968 drv->global->if_add_wdevid = p2pdev_info.wdev_id;
9969 drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
9970 if (!is_zero_ether_addr(p2pdev_info.macaddr))
9971 os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
9972 wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
9973 ifname,
9974 (long long unsigned int) p2pdev_info.wdev_id);
e472e1b4
AS
9975 } else {
9976 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
2aec4f3c
JM
9977 0, NULL, NULL, use_existing);
9978 if (use_existing && ifidx == -ENFILE) {
9979 added = 0;
9980 ifidx = if_nametoindex(ifname);
9981 } else if (ifidx < 0) {
e472e1b4
AS
9982 return -1;
9983 }
22a7c9d7
JM
9984 }
9985
ab7a1add
AS
9986 if (!addr) {
9987 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
9988 os_memcpy(if_addr, bss->addr, ETH_ALEN);
9989 else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
9990 bss->ifname, if_addr) < 0) {
2aec4f3c
JM
9991 if (added)
9992 nl80211_remove_iface(drv, ifidx);
ab7a1add
AS
9993 return -1;
9994 }
c55f774d
JM
9995 }
9996
9997#ifdef CONFIG_P2P
9998 if (!addr &&
9999 (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
10000 type == WPA_IF_P2P_GO)) {
10001 /* Enforce unique P2P Interface Address */
ab7a1add 10002 u8 new_addr[ETH_ALEN];
c55f774d 10003
ab7a1add 10004 if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
c81eff1a 10005 new_addr) < 0) {
c55f774d
JM
10006 nl80211_remove_iface(drv, ifidx);
10007 return -1;
10008 }
f608081c 10009 if (nl80211_addr_in_use(drv->global, new_addr)) {
c55f774d
JM
10010 wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
10011 "for P2P group interface");
f2ed8023 10012 if (nl80211_p2p_interface_addr(drv, new_addr) < 0) {
c55f774d
JM
10013 nl80211_remove_iface(drv, ifidx);
10014 return -1;
10015 }
c81eff1a 10016 if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
c55f774d
JM
10017 new_addr) < 0) {
10018 nl80211_remove_iface(drv, ifidx);
10019 return -1;
10020 }
c55f774d 10021 }
f67eeb5c 10022 os_memcpy(if_addr, new_addr, ETH_ALEN);
c55f774d
JM
10023 }
10024#endif /* CONFIG_P2P */
f3585c8a 10025
22a7c9d7 10026 if (type == WPA_IF_AP_BSS) {
f5eb9da3
JM
10027 struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
10028 if (new_bss == NULL) {
2aec4f3c
JM
10029 if (added)
10030 nl80211_remove_iface(drv, ifidx);
f5eb9da3
JM
10031 return -1;
10032 }
10033
10034 if (bridge &&
10035 i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
10036 wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
10037 "interface %s to a bridge %s",
10038 ifname, bridge);
2aec4f3c
JM
10039 if (added)
10040 nl80211_remove_iface(drv, ifidx);
f5eb9da3
JM
10041 os_free(new_bss);
10042 return -1;
10043 }
10044
c81eff1a
BG
10045 if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
10046 {
34f2f814 10047 nl80211_remove_iface(drv, ifidx);
07179987 10048 os_free(new_bss);
22a7c9d7
JM
10049 return -1;
10050 }
a2e40bb6 10051 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
341eebee 10052 os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
a2e40bb6
FF
10053 new_bss->ifindex = ifidx;
10054 new_bss->drv = drv;
834ee56f
KP
10055 new_bss->next = drv->first_bss->next;
10056 new_bss->freq = drv->first_bss->freq;
a5e1eb20 10057 new_bss->ctx = bss_ctx;
2aec4f3c 10058 new_bss->added_if = added;
834ee56f 10059 drv->first_bss->next = new_bss;
a2e40bb6
FF
10060 if (drv_priv)
10061 *drv_priv = new_bss;
cc7a48d1 10062 nl80211_init_bss(new_bss);
3dd1d890
YAP
10063
10064 /* Subscribe management frames for this WPA_IF_AP_BSS */
10065 if (nl80211_setup_ap(new_bss))
10066 return -1;
22a7c9d7 10067 }
22a7c9d7 10068
ff6a158b
JM
10069 if (drv->global)
10070 drv->global->if_add_ifindex = ifidx;
10071
b36935be
MB
10072 if (ifidx > 0)
10073 add_ifidx(drv, ifidx);
10074
22a7c9d7
JM
10075 return 0;
10076}
10077
10078
9ebce9c5 10079static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
22a7c9d7
JM
10080 enum wpa_driver_if_type type,
10081 const char *ifname)
10082{
a2e40bb6 10083 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7
JM
10084 int ifindex = if_nametoindex(ifname);
10085
2aec4f3c
JM
10086 wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d",
10087 __func__, type, ifname, ifindex, bss->added_if);
158b090c 10088 if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex))
2b72df63 10089 nl80211_remove_iface(drv, ifindex);
b36935be
MB
10090 else if (ifindex > 0 && !bss->added_if)
10091 del_ifidx(drv, ifindex);
c34e618d 10092
c34e618d
FF
10093 if (type != WPA_IF_AP_BSS)
10094 return 0;
10095
e17a2477 10096 if (bss->added_if_into_bridge) {
c81eff1a
BG
10097 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
10098 bss->ifname) < 0)
e17a2477
JM
10099 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
10100 "interface %s from bridge %s: %s",
10101 bss->ifname, bss->brname, strerror(errno));
10102 }
10103 if (bss->added_bridge) {
c81eff1a 10104 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
e17a2477
JM
10105 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
10106 "bridge %s: %s",
10107 bss->brname, strerror(errno));
10108 }
a2e40bb6 10109
834ee56f 10110 if (bss != drv->first_bss) {
8546ea19 10111 struct i802_bss *tbss;
a2e40bb6 10112
2aec4f3c 10113 wpa_printf(MSG_DEBUG, "nl80211: Not the first BSS - remove it");
834ee56f 10114 for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
8546ea19
JM
10115 if (tbss->next == bss) {
10116 tbss->next = bss->next;
3dd1d890
YAP
10117 /* Unsubscribe management frames */
10118 nl80211_teardown_ap(bss);
cc7a48d1 10119 nl80211_destroy_bss(bss);
5c9da160
MB
10120 if (!bss->added_if)
10121 i802_set_iface_flags(bss, 0);
8546ea19
JM
10122 os_free(bss);
10123 bss = NULL;
10124 break;
10125 }
22a7c9d7 10126 }
8546ea19
JM
10127 if (bss)
10128 wpa_printf(MSG_INFO, "nl80211: %s - could not find "
10129 "BSS %p in the list", __func__, bss);
390e489c 10130 } else {
2aec4f3c 10131 wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
390e489c 10132 nl80211_teardown_ap(bss);
2aec4f3c
JM
10133 if (!bss->added_if && !drv->first_bss->next)
10134 wpa_driver_nl80211_del_beacon(drv);
390e489c 10135 nl80211_destroy_bss(bss);
2aec4f3c
JM
10136 if (!bss->added_if)
10137 i802_set_iface_flags(bss, 0);
390e489c
KP
10138 if (drv->first_bss->next) {
10139 drv->first_bss = drv->first_bss->next;
10140 drv->ctx = drv->first_bss->ctx;
10141 os_free(bss);
10142 } else {
10143 wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
10144 }
22a7c9d7 10145 }
22a7c9d7
JM
10146
10147 return 0;
10148}
10149
10150
55777702
JM
10151static int cookie_handler(struct nl_msg *msg, void *arg)
10152{
10153 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10154 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10155 u64 *cookie = arg;
10156 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10157 genlmsg_attrlen(gnlh, 0), NULL);
10158 if (tb[NL80211_ATTR_COOKIE])
10159 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
10160 return NL_SKIP;
10161}
10162
10163
88df0ef7 10164static int nl80211_send_frame_cmd(struct i802_bss *bss,
5dfca53f
JB
10165 unsigned int freq, unsigned int wait,
10166 const u8 *buf, size_t buf_len,
88df0ef7
JB
10167 u64 *cookie_out, int no_cck, int no_ack,
10168 int offchanok)
9884f9cc 10169{
88df0ef7 10170 struct wpa_driver_nl80211_data *drv = bss->drv;
9884f9cc
JB
10171 struct nl_msg *msg;
10172 u64 cookie;
10173 int ret = -1;
10174
10175 msg = nlmsg_alloc();
10176 if (!msg)
10177 return -1;
10178
cc2ada86 10179 wpa_printf(MSG_MSGDUMP, "nl80211: CMD_FRAME freq=%u wait=%u no_cck=%d "
2e3e4566
JM
10180 "no_ack=%d offchanok=%d",
10181 freq, wait, no_cck, no_ack, offchanok);
c91f796f 10182 wpa_hexdump(MSG_MSGDUMP, "CMD_FRAME", buf, buf_len);
9fb04070 10183 nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME);
9884f9cc 10184
f632e483 10185 if (nl80211_set_iface_id(msg, bss) < 0)
d3aaef80 10186 goto nla_put_failure;
c91f796f
NC
10187 if (freq)
10188 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
9db931ed
JM
10189 if (wait)
10190 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
64abb725
JM
10191 if (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
10192 drv->test_use_roc_tx))
88df0ef7 10193 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
b106173a
JM
10194 if (no_cck)
10195 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
ddc53271
JM
10196 if (no_ack)
10197 NLA_PUT_FLAG(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK);
970fa12e 10198
9884f9cc
JB
10199 NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
10200
10201 cookie = 0;
10202 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
10203 msg = NULL;
10204 if (ret) {
10205 wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
a05225c8
JM
10206 "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
10207 freq, wait);
9884f9cc
JB
10208 goto nla_put_failure;
10209 }
cc2ada86 10210 wpa_printf(MSG_MSGDUMP, "nl80211: Frame TX command accepted%s; "
ddc53271
JM
10211 "cookie 0x%llx", no_ack ? " (no ACK)" : "",
10212 (long long unsigned int) cookie);
9884f9cc
JB
10213
10214 if (cookie_out)
ddc53271 10215 *cookie_out = no_ack ? (u64) -1 : cookie;
9884f9cc
JB
10216
10217nla_put_failure:
10218 nlmsg_free(msg);
10219 return ret;
10220}
10221
10222
9ebce9c5
JM
10223static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
10224 unsigned int freq,
190b9062 10225 unsigned int wait_time,
58f6fbe0
JM
10226 const u8 *dst, const u8 *src,
10227 const u8 *bssid,
b106173a
JM
10228 const u8 *data, size_t data_len,
10229 int no_cck)
58f6fbe0 10230{
a2e40bb6 10231 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0 10232 int ret = -1;
58f6fbe0
JM
10233 u8 *buf;
10234 struct ieee80211_hdr *hdr;
58f6fbe0 10235
5dfca53f 10236 wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
55231068
JM
10237 "freq=%u MHz wait=%d ms no_cck=%d)",
10238 drv->ifindex, freq, wait_time, no_cck);
58f6fbe0
JM
10239
10240 buf = os_zalloc(24 + data_len);
10241 if (buf == NULL)
10242 return ret;
10243 os_memcpy(buf + 24, data, data_len);
10244 hdr = (struct ieee80211_hdr *) buf;
10245 hdr->frame_control =
10246 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
10247 os_memcpy(hdr->addr1, dst, ETH_ALEN);
10248 os_memcpy(hdr->addr2, src, ETH_ALEN);
10249 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
10250
f78f2785
JM
10251 if (is_ap_interface(drv->nlmode) &&
10252 (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
10253 (int) freq == bss->freq || drv->device_ap_sme ||
10254 !drv->use_monitor))
9ebce9c5
JM
10255 ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
10256 0, freq, no_cck, 1,
10257 wait_time);
9884f9cc 10258 else
88df0ef7 10259 ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
5dfca53f 10260 24 + data_len,
b106173a 10261 &drv->send_action_cookie,
88df0ef7 10262 no_cck, 0, 1);
58f6fbe0 10263
f8bf1421 10264 os_free(buf);
58f6fbe0
JM
10265 return ret;
10266}
10267
10268
5dfca53f
JB
10269static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
10270{
10271 struct i802_bss *bss = priv;
10272 struct wpa_driver_nl80211_data *drv = bss->drv;
10273 struct nl_msg *msg;
10274 int ret;
10275
10276 msg = nlmsg_alloc();
10277 if (!msg)
10278 return;
10279
316a9e4d
JM
10280 wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
10281 (long long unsigned int) drv->send_action_cookie);
9fb04070 10282 nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME_WAIT_CANCEL);
5dfca53f 10283
7940c790
AS
10284 if (nl80211_set_iface_id(msg, bss) < 0)
10285 goto nla_put_failure;
5dfca53f
JB
10286 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie);
10287
10288 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10289 msg = NULL;
10290 if (ret)
10291 wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
10292 "(%s)", ret, strerror(-ret));
10293
10294 nla_put_failure:
10295 nlmsg_free(msg);
10296}
10297
10298
55777702
JM
10299static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
10300 unsigned int duration)
10301{
a2e40bb6
FF
10302 struct i802_bss *bss = priv;
10303 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
10304 struct nl_msg *msg;
10305 int ret;
10306 u64 cookie;
10307
10308 msg = nlmsg_alloc();
10309 if (!msg)
10310 return -1;
10311
9fb04070 10312 nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL);
55777702 10313
f632e483 10314 if (nl80211_set_iface_id(msg, bss) < 0)
d3aaef80
DS
10315 goto nla_put_failure;
10316
55777702
JM
10317 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
10318 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
10319
10320 cookie = 0;
10321 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
5883168a 10322 msg = NULL;
55777702
JM
10323 if (ret == 0) {
10324 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
10325 "0x%llx for freq=%u MHz duration=%u",
10326 (long long unsigned int) cookie, freq, duration);
10327 drv->remain_on_chan_cookie = cookie;
531f0331 10328 drv->pending_remain_on_chan = 1;
55777702
JM
10329 return 0;
10330 }
10331 wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
15ed5535
JM
10332 "(freq=%d duration=%u): %d (%s)",
10333 freq, duration, ret, strerror(-ret));
55777702 10334nla_put_failure:
5883168a 10335 nlmsg_free(msg);
55777702
JM
10336 return -1;
10337}
10338
10339
10340static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
10341{
a2e40bb6
FF
10342 struct i802_bss *bss = priv;
10343 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
10344 struct nl_msg *msg;
10345 int ret;
10346
10347 if (!drv->pending_remain_on_chan) {
10348 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
10349 "to cancel");
10350 return -1;
10351 }
10352
10353 wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
10354 "0x%llx",
10355 (long long unsigned int) drv->remain_on_chan_cookie);
10356
10357 msg = nlmsg_alloc();
10358 if (!msg)
10359 return -1;
10360
9fb04070 10361 nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
55777702 10362
f632e483 10363 if (nl80211_set_iface_id(msg, bss) < 0)
d3aaef80
DS
10364 goto nla_put_failure;
10365
55777702
JM
10366 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
10367
10368 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 10369 msg = NULL;
55777702
JM
10370 if (ret == 0)
10371 return 0;
10372 wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
10373 "%d (%s)", ret, strerror(-ret));
10374nla_put_failure:
5883168a 10375 nlmsg_free(msg);
55777702
JM
10376 return -1;
10377}
10378
10379
9ebce9c5 10380static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
504e905c 10381{
a2e40bb6 10382 struct wpa_driver_nl80211_data *drv = bss->drv;
504e905c 10383
5582a5d1 10384 if (!report) {
0d891981
JM
10385 if (bss->nl_preq && drv->device_ap_sme &&
10386 is_ap_interface(drv->nlmode)) {
10387 /*
10388 * Do not disable Probe Request reporting that was
10389 * enabled in nl80211_setup_ap().
10390 */
10391 wpa_printf(MSG_DEBUG, "nl80211: Skip disabling of "
10392 "Probe Request reporting nl_preq=%p while "
10393 "in AP mode", bss->nl_preq);
10394 } else if (bss->nl_preq) {
36488c05
JM
10395 wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
10396 "reporting nl_preq=%p", bss->nl_preq);
5f65e9f7 10397 nl80211_destroy_eloop_handle(&bss->nl_preq);
5582a5d1
JB
10398 }
10399 return 0;
10400 }
10401
481234cf 10402 if (bss->nl_preq) {
5582a5d1 10403 wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
36488c05 10404 "already on! nl_preq=%p", bss->nl_preq);
5582a5d1
JB
10405 return 0;
10406 }
10407
481234cf
JM
10408 bss->nl_preq = nl_create_handle(drv->global->nl_cb, "preq");
10409 if (bss->nl_preq == NULL)
5582a5d1 10410 return -1;
36488c05
JM
10411 wpa_printf(MSG_DEBUG, "nl80211: Enable Probe Request "
10412 "reporting nl_preq=%p", bss->nl_preq);
5582a5d1 10413
481234cf 10414 if (nl80211_register_frame(bss, bss->nl_preq,
5582a5d1
JB
10415 (WLAN_FC_TYPE_MGMT << 2) |
10416 (WLAN_FC_STYPE_PROBE_REQ << 4),
a92dfde8
JB
10417 NULL, 0) < 0)
10418 goto out_err;
5582a5d1 10419
5f65e9f7
JB
10420 nl80211_register_eloop_read(&bss->nl_preq,
10421 wpa_driver_nl80211_event_receive,
10422 bss->nl_cb);
5582a5d1 10423
504e905c 10424 return 0;
5582a5d1 10425
a92dfde8 10426 out_err:
221a59c9 10427 nl_destroy_handles(&bss->nl_preq);
5582a5d1 10428 return -1;
504e905c
JM
10429}
10430
10431
4e5cb1a3
JM
10432static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
10433 int ifindex, int disabled)
10434{
10435 struct nl_msg *msg;
10436 struct nlattr *bands, *band;
10437 int ret;
10438
10439 msg = nlmsg_alloc();
10440 if (!msg)
10441 return -1;
10442
9fb04070 10443 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_TX_BITRATE_MASK);
4e5cb1a3
JM
10444 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
10445
10446 bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
10447 if (!bands)
10448 goto nla_put_failure;
10449
10450 /*
10451 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
10452 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
10453 * rates. All 5 GHz rates are left enabled.
10454 */
10455 band = nla_nest_start(msg, NL80211_BAND_2GHZ);
10456 if (!band)
10457 goto nla_put_failure;
1dea5882
JM
10458 if (disabled) {
10459 NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
10460 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
10461 }
4e5cb1a3
JM
10462 nla_nest_end(msg, band);
10463
10464 nla_nest_end(msg, bands);
10465
10466 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10467 msg = NULL;
10468 if (ret) {
10469 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
10470 "(%s)", ret, strerror(-ret));
1d0c6fb1
JM
10471 } else
10472 drv->disabled_11b_rates = disabled;
4e5cb1a3
JM
10473
10474 return ret;
10475
10476nla_put_failure:
10477 nlmsg_free(msg);
10478 return -1;
10479}
10480
10481
af473088
JM
10482static int wpa_driver_nl80211_deinit_ap(void *priv)
10483{
a2e40bb6
FF
10484 struct i802_bss *bss = priv;
10485 struct wpa_driver_nl80211_data *drv = bss->drv;
b1f625e0 10486 if (!is_ap_interface(drv->nlmode))
af473088
JM
10487 return -1;
10488 wpa_driver_nl80211_del_beacon(drv);
60b13c20
IP
10489
10490 /*
10491 * If the P2P GO interface was dynamically added, then it is
10492 * possible that the interface change to station is not possible.
10493 */
10494 if (drv->nlmode == NL80211_IFTYPE_P2P_GO && bss->if_dynamic)
10495 return 0;
10496
b1f625e0 10497 return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
af473088
JM
10498}
10499
10500
695c7038
SW
10501static int wpa_driver_nl80211_stop_ap(void *priv)
10502{
10503 struct i802_bss *bss = priv;
10504 struct wpa_driver_nl80211_data *drv = bss->drv;
10505 if (!is_ap_interface(drv->nlmode))
10506 return -1;
10507 wpa_driver_nl80211_del_beacon(drv);
10508 bss->beacon_set = 0;
10509 return 0;
10510}
10511
10512
3c29244e
EP
10513static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
10514{
10515 struct i802_bss *bss = priv;
10516 struct wpa_driver_nl80211_data *drv = bss->drv;
10517 if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
10518 return -1;
60b13c20
IP
10519
10520 /*
10521 * If the P2P Client interface was dynamically added, then it is
10522 * possible that the interface change to station is not possible.
10523 */
10524 if (bss->if_dynamic)
10525 return 0;
10526
3c29244e
EP
10527 return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
10528}
10529
10530
207ef3fb
JM
10531static void wpa_driver_nl80211_resume(void *priv)
10532{
a2e40bb6 10533 struct i802_bss *bss = priv;
91724d6f
AS
10534
10535 if (i802_set_iface_flags(bss, 1))
10536 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on resume event");
207ef3fb
JM
10537}
10538
10539
7b90c16a
JM
10540static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
10541 const u8 *ies, size_t ies_len)
10542{
10543 struct i802_bss *bss = priv;
10544 struct wpa_driver_nl80211_data *drv = bss->drv;
10545 int ret;
10546 u8 *data, *pos;
10547 size_t data_len;
341eebee 10548 const u8 *own_addr = bss->addr;
7b90c16a
JM
10549
10550 if (action != 1) {
10551 wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
10552 "action %d", action);
10553 return -1;
10554 }
10555
10556 /*
10557 * Action frame payload:
10558 * Category[1] = 6 (Fast BSS Transition)
10559 * Action[1] = 1 (Fast BSS Transition Request)
10560 * STA Address
10561 * Target AP Address
10562 * FT IEs
10563 */
10564
73fc617d
JM
10565 data_len = 2 + 2 * ETH_ALEN + ies_len;
10566 data = os_malloc(data_len);
7b90c16a
JM
10567 if (data == NULL)
10568 return -1;
10569 pos = data;
10570 *pos++ = 0x06; /* FT Action category */
10571 *pos++ = action;
10572 os_memcpy(pos, own_addr, ETH_ALEN);
10573 pos += ETH_ALEN;
10574 os_memcpy(pos, target_ap, ETH_ALEN);
10575 pos += ETH_ALEN;
10576 os_memcpy(pos, ies, ies_len);
10577
190b9062
JB
10578 ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, 0,
10579 drv->bssid, own_addr, drv->bssid,
b106173a 10580 data, data_len, 0);
7b90c16a
JM
10581 os_free(data);
10582
10583 return ret;
10584}
10585
10586
b625473c
JM
10587static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
10588{
10589 struct i802_bss *bss = priv;
10590 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8
JB
10591 struct nl_msg *msg;
10592 struct nlattr *cqm;
f0494d0f 10593 int ret = -1;
b625473c
JM
10594
10595 wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
10596 "hysteresis=%d", threshold, hysteresis);
10597
10598 msg = nlmsg_alloc();
10599 if (!msg)
10600 return -1;
10601
9fb04070 10602 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_CQM);
b625473c
JM
10603
10604 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
10605
8970bae8 10606 cqm = nla_nest_start(msg, NL80211_ATTR_CQM);
b625473c 10607 if (cqm == NULL)
21270bb4 10608 goto nla_put_failure;
b625473c 10609
8970bae8
JB
10610 NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
10611 NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
10612 nla_nest_end(msg, cqm);
21270bb4 10613
f0494d0f 10614 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
b625473c
JM
10615 msg = NULL;
10616
10617nla_put_failure:
b625473c 10618 nlmsg_free(msg);
f0494d0f 10619 return ret;
b625473c
JM
10620}
10621
10622
2cc8d8f4
AO
10623static int get_channel_width(struct nl_msg *msg, void *arg)
10624{
10625 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10626 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10627 struct wpa_signal_info *sig_change = arg;
10628
10629 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10630 genlmsg_attrlen(gnlh, 0), NULL);
10631
10632 sig_change->center_frq1 = -1;
10633 sig_change->center_frq2 = -1;
10634 sig_change->chanwidth = CHAN_WIDTH_UNKNOWN;
10635
10636 if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
10637 sig_change->chanwidth = convert2width(
10638 nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
10639 if (tb[NL80211_ATTR_CENTER_FREQ1])
10640 sig_change->center_frq1 =
10641 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
10642 if (tb[NL80211_ATTR_CENTER_FREQ2])
10643 sig_change->center_frq2 =
10644 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
10645 }
10646
10647 return NL_SKIP;
10648}
10649
10650
10651static int nl80211_get_channel_width(struct wpa_driver_nl80211_data *drv,
10652 struct wpa_signal_info *sig)
10653{
10654 struct nl_msg *msg;
10655
10656 msg = nlmsg_alloc();
10657 if (!msg)
10658 return -ENOMEM;
10659
10660 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_INTERFACE);
10661 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
10662
10663 return send_and_recv_msgs(drv, msg, get_channel_width, sig);
10664
10665nla_put_failure:
10666 nlmsg_free(msg);
10667 return -ENOBUFS;
10668}
10669
10670
1c5c7273
PS
10671static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
10672{
10673 struct i802_bss *bss = priv;
10674 struct wpa_driver_nl80211_data *drv = bss->drv;
10675 int res;
10676
10677 os_memset(si, 0, sizeof(*si));
10678 res = nl80211_get_link_signal(drv, si);
10679 if (res != 0)
10680 return res;
10681
2cc8d8f4
AO
10682 res = nl80211_get_channel_width(drv, si);
10683 if (res != 0)
10684 return res;
10685
1c5c7273
PS
10686 return nl80211_get_link_noise(drv, si);
10687}
10688
10689
57ebba59
JJ
10690static int wpa_driver_nl80211_shared_freq(void *priv)
10691{
10692 struct i802_bss *bss = priv;
10693 struct wpa_driver_nl80211_data *drv = bss->drv;
10694 struct wpa_driver_nl80211_data *driver;
10695 int freq = 0;
10696
10697 /*
10698 * If the same PHY is in connected state with some other interface,
10699 * then retrieve the assoc freq.
10700 */
10701 wpa_printf(MSG_DEBUG, "nl80211: Get shared freq for PHY %s",
10702 drv->phyname);
10703
10704 dl_list_for_each(driver, &drv->global->interfaces,
10705 struct wpa_driver_nl80211_data, list) {
10706 if (drv == driver ||
10707 os_strcmp(drv->phyname, driver->phyname) != 0 ||
10708 !driver->associated)
10709 continue;
10710
10711 wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s "
10712 MACSTR,
834ee56f
KP
10713 driver->phyname, driver->first_bss->ifname,
10714 MAC2STR(driver->first_bss->addr));
d3bd0f05 10715 if (is_ap_interface(driver->nlmode))
834ee56f 10716 freq = driver->first_bss->freq;
d3bd0f05
JJ
10717 else
10718 freq = nl80211_get_assoc_freq(driver);
57ebba59
JJ
10719 wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",
10720 drv->phyname, freq);
10721 }
10722
10723 if (!freq)
10724 wpa_printf(MSG_DEBUG, "nl80211: No shared interface for "
10725 "PHY (%s) in associated state", drv->phyname);
10726
10727 return freq;
10728}
10729
10730
b91ab76e
JM
10731static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
10732 int encrypt)
10733{
10734 struct i802_bss *bss = priv;
55231068
JM
10735 return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
10736 0, 0, 0, 0);
b91ab76e
JM
10737}
10738
10739
c55f774d
JM
10740static int nl80211_set_param(void *priv, const char *param)
10741{
c55f774d
JM
10742 wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
10743 if (param == NULL)
10744 return 0;
10745
10746#ifdef CONFIG_P2P
10747 if (os_strstr(param, "use_p2p_group_interface=1")) {
482856c8
JM
10748 struct i802_bss *bss = priv;
10749 struct wpa_driver_nl80211_data *drv = bss->drv;
10750
c55f774d
JM
10751 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
10752 "interface");
10753 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
10754 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
10755 }
851b0c55
JM
10756
10757 if (os_strstr(param, "p2p_device=1")) {
10758 struct i802_bss *bss = priv;
10759 struct wpa_driver_nl80211_data *drv = bss->drv;
10760 drv->allow_p2p_device = 1;
10761 }
c55f774d
JM
10762#endif /* CONFIG_P2P */
10763
327b01d3
JM
10764 if (os_strstr(param, "use_monitor=1")) {
10765 struct i802_bss *bss = priv;
10766 struct wpa_driver_nl80211_data *drv = bss->drv;
10767 drv->use_monitor = 1;
10768 }
10769
10770 if (os_strstr(param, "force_connect_cmd=1")) {
10771 struct i802_bss *bss = priv;
10772 struct wpa_driver_nl80211_data *drv = bss->drv;
10773 drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
10774 }
10775
64abb725
JM
10776 if (os_strstr(param, "no_offchannel_tx=1")) {
10777 struct i802_bss *bss = priv;
10778 struct wpa_driver_nl80211_data *drv = bss->drv;
10779 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
10780 drv->test_use_roc_tx = 1;
10781 }
10782
c55f774d
JM
10783 return 0;
10784}
10785
10786
f2ed8023
JM
10787static void * nl80211_global_init(void)
10788{
10789 struct nl80211_global *global;
36d84860
BG
10790 struct netlink_config *cfg;
10791
f2ed8023
JM
10792 global = os_zalloc(sizeof(*global));
10793 if (global == NULL)
10794 return NULL;
c81eff1a 10795 global->ioctl_sock = -1;
f2ed8023 10796 dl_list_init(&global->interfaces);
ff6a158b 10797 global->if_add_ifindex = -1;
36d84860
BG
10798
10799 cfg = os_zalloc(sizeof(*cfg));
10800 if (cfg == NULL)
10801 goto err;
10802
10803 cfg->ctx = global;
10804 cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
10805 cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
10806 global->netlink = netlink_init(cfg);
10807 if (global->netlink == NULL) {
10808 os_free(cfg);
10809 goto err;
10810 }
10811
2a7b66f5
BG
10812 if (wpa_driver_nl80211_init_nl_global(global) < 0)
10813 goto err;
10814
c81eff1a
BG
10815 global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
10816 if (global->ioctl_sock < 0) {
7ac3616d
JM
10817 wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
10818 strerror(errno));
c81eff1a
BG
10819 goto err;
10820 }
10821
f2ed8023 10822 return global;
36d84860
BG
10823
10824err:
10825 nl80211_global_deinit(global);
10826 return NULL;
f2ed8023
JM
10827}
10828
10829
10830static void nl80211_global_deinit(void *priv)
10831{
10832 struct nl80211_global *global = priv;
10833 if (global == NULL)
10834 return;
10835 if (!dl_list_empty(&global->interfaces)) {
10836 wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
10837 "nl80211_global_deinit",
10838 dl_list_len(&global->interfaces));
10839 }
36d84860
BG
10840
10841 if (global->netlink)
10842 netlink_deinit(global->netlink);
10843
276e2d67
BG
10844 nl_destroy_handles(&global->nl);
10845
5f65e9f7
JB
10846 if (global->nl_event)
10847 nl80211_destroy_eloop_handle(&global->nl_event);
d6c9aab8
JB
10848
10849 nl_cb_put(global->nl_cb);
2a7b66f5 10850
c81eff1a
BG
10851 if (global->ioctl_sock >= 0)
10852 close(global->ioctl_sock);
10853
f2ed8023
JM
10854 os_free(global);
10855}
10856
10857
6859f1cb
BG
10858static const char * nl80211_get_radio_name(void *priv)
10859{
10860 struct i802_bss *bss = priv;
10861 struct wpa_driver_nl80211_data *drv = bss->drv;
10862 return drv->phyname;
10863}
10864
10865
a6efc65d
JM
10866static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
10867 const u8 *pmkid)
10868{
10869 struct nl_msg *msg;
10870
10871 msg = nlmsg_alloc();
10872 if (!msg)
10873 return -ENOMEM;
10874
9fb04070 10875 nl80211_cmd(bss->drv, msg, 0, cmd);
a6efc65d
JM
10876
10877 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
10878 if (pmkid)
10879 NLA_PUT(msg, NL80211_ATTR_PMKID, 16, pmkid);
10880 if (bssid)
10881 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
10882
10883 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
10884 nla_put_failure:
9e088e74 10885 nlmsg_free(msg);
a6efc65d
JM
10886 return -ENOBUFS;
10887}
10888
10889
10890static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
10891{
10892 struct i802_bss *bss = priv;
10893 wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
10894 return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
10895}
10896
10897
10898static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
10899{
10900 struct i802_bss *bss = priv;
10901 wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
10902 MAC2STR(bssid));
10903 return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
10904}
10905
10906
10907static int nl80211_flush_pmkid(void *priv)
10908{
10909 struct i802_bss *bss = priv;
10910 wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
10911 return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
10912}
10913
10914
0185007c
MK
10915static void clean_survey_results(struct survey_results *survey_results)
10916{
10917 struct freq_survey *survey, *tmp;
10918
10919 if (dl_list_empty(&survey_results->survey_list))
10920 return;
10921
10922 dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
10923 struct freq_survey, list) {
10924 dl_list_del(&survey->list);
10925 os_free(survey);
10926 }
10927}
10928
10929
10930static void add_survey(struct nlattr **sinfo, u32 ifidx,
10931 struct dl_list *survey_list)
10932{
10933 struct freq_survey *survey;
10934
10935 survey = os_zalloc(sizeof(struct freq_survey));
10936 if (!survey)
10937 return;
10938
10939 survey->ifidx = ifidx;
10940 survey->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
10941 survey->filled = 0;
10942
10943 if (sinfo[NL80211_SURVEY_INFO_NOISE]) {
10944 survey->nf = (int8_t)
10945 nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
10946 survey->filled |= SURVEY_HAS_NF;
10947 }
10948
10949 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) {
10950 survey->channel_time =
10951 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
10952 survey->filled |= SURVEY_HAS_CHAN_TIME;
10953 }
10954
10955 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {
10956 survey->channel_time_busy =
10957 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);
10958 survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
10959 }
10960
10961 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) {
10962 survey->channel_time_rx =
10963 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);
10964 survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
10965 }
10966
10967 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) {
10968 survey->channel_time_tx =
10969 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);
10970 survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
10971 }
10972
10973 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)",
10974 survey->freq,
10975 survey->nf,
10976 (unsigned long int) survey->channel_time,
10977 (unsigned long int) survey->channel_time_busy,
10978 (unsigned long int) survey->channel_time_tx,
10979 (unsigned long int) survey->channel_time_rx,
10980 survey->filled);
10981
10982 dl_list_add_tail(survey_list, &survey->list);
10983}
10984
10985
10986static int check_survey_ok(struct nlattr **sinfo, u32 surveyed_freq,
10987 unsigned int freq_filter)
10988{
10989 if (!freq_filter)
10990 return 1;
10991
10992 return freq_filter == surveyed_freq;
10993}
10994
10995
10996static int survey_handler(struct nl_msg *msg, void *arg)
10997{
10998 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10999 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11000 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
11001 struct survey_results *survey_results;
11002 u32 surveyed_freq = 0;
11003 u32 ifidx;
11004
11005 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
11006 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
11007 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
11008 };
11009
11010 survey_results = (struct survey_results *) arg;
11011
11012 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
11013 genlmsg_attrlen(gnlh, 0), NULL);
11014
e28f39b7
SJ
11015 if (!tb[NL80211_ATTR_IFINDEX])
11016 return NL_SKIP;
11017
0185007c
MK
11018 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
11019
11020 if (!tb[NL80211_ATTR_SURVEY_INFO])
11021 return NL_SKIP;
11022
11023 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
11024 tb[NL80211_ATTR_SURVEY_INFO],
11025 survey_policy))
11026 return NL_SKIP;
11027
11028 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) {
11029 wpa_printf(MSG_ERROR, "nl80211: Invalid survey data");
11030 return NL_SKIP;
11031 }
11032
11033 surveyed_freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
11034
11035 if (!check_survey_ok(sinfo, surveyed_freq,
11036 survey_results->freq_filter))
11037 return NL_SKIP;
11038
11039 if (survey_results->freq_filter &&
11040 survey_results->freq_filter != surveyed_freq) {
11041 wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
11042 surveyed_freq);
11043 return NL_SKIP;
11044 }
11045
11046 add_survey(sinfo, ifidx, &survey_results->survey_list);
11047
11048 return NL_SKIP;
11049}
11050
11051
11052static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
11053{
11054 struct i802_bss *bss = priv;
11055 struct wpa_driver_nl80211_data *drv = bss->drv;
11056 struct nl_msg *msg;
11057 int err = -ENOBUFS;
11058 union wpa_event_data data;
11059 struct survey_results *survey_results;
11060
11061 os_memset(&data, 0, sizeof(data));
11062 survey_results = &data.survey_results;
11063
11064 dl_list_init(&survey_results->survey_list);
11065
11066 msg = nlmsg_alloc();
11067 if (!msg)
11068 goto nla_put_failure;
11069
11070 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
11071
11072 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11073
11074 if (freq)
11075 data.survey_results.freq_filter = freq;
11076
11077 do {
11078 wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
11079 err = send_and_recv_msgs(drv, msg, survey_handler,
11080 survey_results);
11081 } while (err > 0);
11082
11083 if (err) {
11084 wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
11085 goto out_clean;
11086 }
11087
11088 wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
11089
11090out_clean:
11091 clean_survey_results(survey_results);
11092nla_put_failure:
11093 return err;
11094}
11095
11096
b14a210c
JB
11097static void nl80211_set_rekey_info(void *priv, const u8 *kek, const u8 *kck,
11098 const u8 *replay_ctr)
11099{
11100 struct i802_bss *bss = priv;
11101 struct wpa_driver_nl80211_data *drv = bss->drv;
11102 struct nlattr *replay_nested;
11103 struct nl_msg *msg;
11104
11105 msg = nlmsg_alloc();
11106 if (!msg)
11107 return;
11108
9fb04070 11109 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
b14a210c
JB
11110
11111 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11112
11113 replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
11114 if (!replay_nested)
11115 goto nla_put_failure;
11116
11117 NLA_PUT(msg, NL80211_REKEY_DATA_KEK, NL80211_KEK_LEN, kek);
11118 NLA_PUT(msg, NL80211_REKEY_DATA_KCK, NL80211_KCK_LEN, kck);
11119 NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
11120 replay_ctr);
11121
11122 nla_nest_end(msg, replay_nested);
11123
11124 send_and_recv_msgs(drv, msg, NULL, NULL);
11125 return;
11126 nla_put_failure:
11127 nlmsg_free(msg);
11128}
11129
11130
39718852
JB
11131static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
11132 const u8 *addr, int qos)
bcf24348 11133{
39718852
JB
11134 /* send data frame to poll STA and check whether
11135 * this frame is ACKed */
bcf24348
JB
11136 struct {
11137 struct ieee80211_hdr hdr;
11138 u16 qos_ctl;
11139 } STRUCT_PACKED nulldata;
11140 size_t size;
11141
11142 /* Send data frame to poll STA and check whether this frame is ACKed */
11143
11144 os_memset(&nulldata, 0, sizeof(nulldata));
11145
11146 if (qos) {
11147 nulldata.hdr.frame_control =
11148 IEEE80211_FC(WLAN_FC_TYPE_DATA,
11149 WLAN_FC_STYPE_QOS_NULL);
11150 size = sizeof(nulldata);
11151 } else {
11152 nulldata.hdr.frame_control =
11153 IEEE80211_FC(WLAN_FC_TYPE_DATA,
11154 WLAN_FC_STYPE_NULLFUNC);
11155 size = sizeof(struct ieee80211_hdr);
11156 }
11157
11158 nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
11159 os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
11160 os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
11161 os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
11162
9ebce9c5
JM
11163 if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
11164 0, 0) < 0)
bcf24348
JB
11165 wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
11166 "send poll frame");
11167}
11168
39718852
JB
11169static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
11170 int qos)
11171{
11172 struct i802_bss *bss = priv;
11173 struct wpa_driver_nl80211_data *drv = bss->drv;
11174 struct nl_msg *msg;
11175
11176 if (!drv->poll_command_supported) {
11177 nl80211_send_null_frame(bss, own_addr, addr, qos);
11178 return;
11179 }
11180
11181 msg = nlmsg_alloc();
11182 if (!msg)
11183 return;
11184
11185 nl80211_cmd(drv, msg, 0, NL80211_CMD_PROBE_CLIENT);
11186
11187 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11188 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
11189
11190 send_and_recv_msgs(drv, msg, NULL, NULL);
11191 return;
11192 nla_put_failure:
11193 nlmsg_free(msg);
11194}
11195
bcf24348 11196
29f338af
JM
11197static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
11198{
11199 struct nl_msg *msg;
11200
11201 msg = nlmsg_alloc();
11202 if (!msg)
11203 return -ENOMEM;
11204
11205 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_SET_POWER_SAVE);
11206 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11207 NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE,
11208 enabled ? NL80211_PS_ENABLED : NL80211_PS_DISABLED);
11209 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
11210nla_put_failure:
11211 nlmsg_free(msg);
11212 return -ENOBUFS;
11213}
11214
11215
11216static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps,
11217 int ctwindow)
11218{
11219 struct i802_bss *bss = priv;
11220
11221 wpa_printf(MSG_DEBUG, "nl80211: set_p2p_powersave (legacy_ps=%d "
11222 "opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
11223
0de38036
JM
11224 if (opp_ps != -1 || ctwindow != -1) {
11225#ifdef ANDROID_P2P
11226 wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
11227#else /* ANDROID_P2P */
29f338af 11228 return -1; /* Not yet supported */
0de38036
JM
11229#endif /* ANDROID_P2P */
11230 }
29f338af
JM
11231
11232 if (legacy_ps == -1)
11233 return 0;
11234 if (legacy_ps != 0 && legacy_ps != 1)
11235 return -1; /* Not yet supported */
11236
11237 return nl80211_set_power_save(bss, legacy_ps);
11238}
11239
11240
04e8003c
JD
11241static int nl80211_start_radar_detection(void *priv,
11242 struct hostapd_freq_params *freq)
f90e9c1c
SW
11243{
11244 struct i802_bss *bss = priv;
11245 struct wpa_driver_nl80211_data *drv = bss->drv;
11246 struct nl_msg *msg;
11247 int ret;
11248
04e8003c
JD
11249 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)",
11250 freq->freq, freq->ht_enabled, freq->vht_enabled,
11251 freq->bandwidth, freq->center_freq1, freq->center_freq2);
11252
f90e9c1c
SW
11253 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) {
11254 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar "
11255 "detection");
11256 return -1;
11257 }
11258
11259 msg = nlmsg_alloc();
11260 if (!msg)
11261 return -1;
11262
11263 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_RADAR_DETECT);
11264 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
04e8003c 11265 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq);
f90e9c1c 11266
04e8003c
JD
11267 if (freq->vht_enabled) {
11268 switch (freq->bandwidth) {
11269 case 20:
11270 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11271 NL80211_CHAN_WIDTH_20);
11272 break;
11273 case 40:
11274 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11275 NL80211_CHAN_WIDTH_40);
11276 break;
11277 case 80:
11278 if (freq->center_freq2)
11279 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11280 NL80211_CHAN_WIDTH_80P80);
11281 else
11282 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11283 NL80211_CHAN_WIDTH_80);
11284 break;
11285 case 160:
11286 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11287 NL80211_CHAN_WIDTH_160);
11288 break;
11289 default:
11290 return -1;
11291 }
11292 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1);
11293 if (freq->center_freq2)
11294 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2,
11295 freq->center_freq2);
11296 } else if (freq->ht_enabled) {
11297 switch (freq->sec_channel_offset) {
11298 case -1:
11299 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11300 NL80211_CHAN_HT40MINUS);
11301 break;
11302 case 1:
11303 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11304 NL80211_CHAN_HT40PLUS);
11305 break;
11306 default:
11307 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11308 NL80211_CHAN_HT20);
11309 break;
11310 }
11311 }
f90e9c1c
SW
11312
11313 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11314 if (ret == 0)
11315 return 0;
11316 wpa_printf(MSG_DEBUG, "nl80211: Failed to start radar detection: "
11317 "%d (%s)", ret, strerror(-ret));
11318nla_put_failure:
11319 return -1;
11320}
11321
03ea1786
AN
11322#ifdef CONFIG_TDLS
11323
11324static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
11325 u8 dialog_token, u16 status_code,
96ecea5e 11326 u32 peer_capab, const u8 *buf, size_t len)
03ea1786
AN
11327{
11328 struct i802_bss *bss = priv;
11329 struct wpa_driver_nl80211_data *drv = bss->drv;
11330 struct nl_msg *msg;
11331
11332 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
11333 return -EOPNOTSUPP;
11334
11335 if (!dst)
11336 return -EINVAL;
11337
11338 msg = nlmsg_alloc();
11339 if (!msg)
11340 return -ENOMEM;
11341
11342 nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_MGMT);
11343 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11344 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
11345 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_ACTION, action_code);
11346 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token);
11347 NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status_code);
96ecea5e
SD
11348 if (peer_capab) {
11349 /*
11350 * The internal enum tdls_peer_capability definition is
11351 * currently identical with the nl80211 enum
11352 * nl80211_tdls_peer_capability, so no conversion is needed
11353 * here.
11354 */
11355 NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY, peer_capab);
11356 }
03ea1786
AN
11357 NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
11358
11359 return send_and_recv_msgs(drv, msg, NULL, NULL);
11360
11361nla_put_failure:
11362 nlmsg_free(msg);
11363 return -ENOBUFS;
11364}
11365
11366
11367static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
11368{
11369 struct i802_bss *bss = priv;
11370 struct wpa_driver_nl80211_data *drv = bss->drv;
11371 struct nl_msg *msg;
11372 enum nl80211_tdls_operation nl80211_oper;
11373
11374 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
11375 return -EOPNOTSUPP;
11376
11377 switch (oper) {
11378 case TDLS_DISCOVERY_REQ:
11379 nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
11380 break;
11381 case TDLS_SETUP:
11382 nl80211_oper = NL80211_TDLS_SETUP;
11383 break;
11384 case TDLS_TEARDOWN:
11385 nl80211_oper = NL80211_TDLS_TEARDOWN;
11386 break;
11387 case TDLS_ENABLE_LINK:
11388 nl80211_oper = NL80211_TDLS_ENABLE_LINK;
11389 break;
11390 case TDLS_DISABLE_LINK:
11391 nl80211_oper = NL80211_TDLS_DISABLE_LINK;
11392 break;
11393 case TDLS_ENABLE:
11394 return 0;
11395 case TDLS_DISABLE:
11396 return 0;
11397 default:
11398 return -EINVAL;
11399 }
11400
11401 msg = nlmsg_alloc();
11402 if (!msg)
11403 return -ENOMEM;
11404
11405 nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_OPER);
11406 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper);
11407 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11408 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
11409
11410 return send_and_recv_msgs(drv, msg, NULL, NULL);
11411
11412nla_put_failure:
11413 nlmsg_free(msg);
11414 return -ENOBUFS;
11415}
11416
11417#endif /* CONFIG TDLS */
11418
11419
216eede8
DS
11420#ifdef ANDROID
11421
11422typedef struct android_wifi_priv_cmd {
11423 char *buf;
11424 int used_len;
11425 int total_len;
11426} android_wifi_priv_cmd;
11427
11428static int drv_errors = 0;
11429
11430static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
11431{
11432 drv_errors++;
11433 if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
11434 drv_errors = 0;
11435 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
11436 }
11437}
11438
11439
11440static int android_priv_cmd(struct i802_bss *bss, const char *cmd)
11441{
11442 struct wpa_driver_nl80211_data *drv = bss->drv;
11443 struct ifreq ifr;
11444 android_wifi_priv_cmd priv_cmd;
11445 char buf[MAX_DRV_CMD_SIZE];
11446 int ret;
11447
11448 os_memset(&ifr, 0, sizeof(ifr));
11449 os_memset(&priv_cmd, 0, sizeof(priv_cmd));
11450 os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
11451
11452 os_memset(buf, 0, sizeof(buf));
11453 os_strlcpy(buf, cmd, sizeof(buf));
11454
11455 priv_cmd.buf = buf;
11456 priv_cmd.used_len = sizeof(buf);
11457 priv_cmd.total_len = sizeof(buf);
11458 ifr.ifr_data = &priv_cmd;
11459
11460 ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
11461 if (ret < 0) {
11462 wpa_printf(MSG_ERROR, "%s: failed to issue private commands",
11463 __func__);
11464 wpa_driver_send_hang_msg(drv);
11465 return ret;
11466 }
11467
11468 drv_errors = 0;
11469 return 0;
11470}
11471
11472
11473static int android_pno_start(struct i802_bss *bss,
11474 struct wpa_driver_scan_params *params)
11475{
11476 struct wpa_driver_nl80211_data *drv = bss->drv;
11477 struct ifreq ifr;
11478 android_wifi_priv_cmd priv_cmd;
11479 int ret = 0, i = 0, bp;
11480 char buf[WEXT_PNO_MAX_COMMAND_SIZE];
11481
11482 bp = WEXT_PNOSETUP_HEADER_SIZE;
11483 os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
11484 buf[bp++] = WEXT_PNO_TLV_PREFIX;
11485 buf[bp++] = WEXT_PNO_TLV_VERSION;
11486 buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
11487 buf[bp++] = WEXT_PNO_TLV_RESERVED;
11488
11489 while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) {
11490 /* Check that there is enough space needed for 1 more SSID, the
11491 * other sections and null termination */
11492 if ((bp + WEXT_PNO_SSID_HEADER_SIZE + MAX_SSID_LEN +
11493 WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf))
11494 break;
11495 wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan",
a97bde0a
JM
11496 params->ssids[i].ssid,
11497 params->ssids[i].ssid_len);
216eede8
DS
11498 buf[bp++] = WEXT_PNO_SSID_SECTION;
11499 buf[bp++] = params->ssids[i].ssid_len;
11500 os_memcpy(&buf[bp], params->ssids[i].ssid,
11501 params->ssids[i].ssid_len);
11502 bp += params->ssids[i].ssid_len;
11503 i++;
11504 }
11505
11506 buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
11507 os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x",
11508 WEXT_PNO_SCAN_INTERVAL);
11509 bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
11510
11511 buf[bp++] = WEXT_PNO_REPEAT_SECTION;
11512 os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x",
11513 WEXT_PNO_REPEAT);
11514 bp += WEXT_PNO_REPEAT_LENGTH;
11515
11516 buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
11517 os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x",
11518 WEXT_PNO_MAX_REPEAT);
11519 bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
11520
11521 memset(&ifr, 0, sizeof(ifr));
11522 memset(&priv_cmd, 0, sizeof(priv_cmd));
24f051eb 11523 os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
216eede8
DS
11524
11525 priv_cmd.buf = buf;
11526 priv_cmd.used_len = bp;
11527 priv_cmd.total_len = bp;
11528 ifr.ifr_data = &priv_cmd;
11529
11530 ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
11531
11532 if (ret < 0) {
11533 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
11534 ret);
11535 wpa_driver_send_hang_msg(drv);
11536 return ret;
11537 }
11538
11539 drv_errors = 0;
11540
11541 return android_priv_cmd(bss, "PNOFORCE 1");
11542}
11543
11544
11545static int android_pno_stop(struct i802_bss *bss)
11546{
11547 return android_priv_cmd(bss, "PNOFORCE 0");
11548}
11549
11550#endif /* ANDROID */
11551
11552
9ebce9c5
JM
11553static int driver_nl80211_set_key(const char *ifname, void *priv,
11554 enum wpa_alg alg, const u8 *addr,
11555 int key_idx, int set_tx,
11556 const u8 *seq, size_t seq_len,
11557 const u8 *key, size_t key_len)
11558{
11559 struct i802_bss *bss = priv;
11560 return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
11561 set_tx, seq, seq_len, key, key_len);
11562}
11563
11564
11565static int driver_nl80211_scan2(void *priv,
11566 struct wpa_driver_scan_params *params)
11567{
11568 struct i802_bss *bss = priv;
11569 return wpa_driver_nl80211_scan(bss, params);
11570}
11571
11572
11573static int driver_nl80211_deauthenticate(void *priv, const u8 *addr,
11574 int reason_code)
11575{
11576 struct i802_bss *bss = priv;
11577 return wpa_driver_nl80211_deauthenticate(bss, addr, reason_code);
11578}
11579
11580
11581static int driver_nl80211_authenticate(void *priv,
11582 struct wpa_driver_auth_params *params)
11583{
11584 struct i802_bss *bss = priv;
11585 return wpa_driver_nl80211_authenticate(bss, params);
11586}
11587
11588
11589static void driver_nl80211_deinit(void *priv)
11590{
11591 struct i802_bss *bss = priv;
11592 wpa_driver_nl80211_deinit(bss);
11593}
11594
11595
11596static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
11597 const char *ifname)
11598{
11599 struct i802_bss *bss = priv;
11600 return wpa_driver_nl80211_if_remove(bss, type, ifname);
11601}
11602
11603
11604static int driver_nl80211_send_mlme(void *priv, const u8 *data,
11605 size_t data_len, int noack)
11606{
11607 struct i802_bss *bss = priv;
11608 return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
11609 0, 0, 0, 0);
11610}
11611
11612
11613static int driver_nl80211_sta_remove(void *priv, const u8 *addr)
11614{
11615 struct i802_bss *bss = priv;
11616 return wpa_driver_nl80211_sta_remove(bss, addr);
11617}
11618
11619
9ebce9c5
JM
11620static int driver_nl80211_set_sta_vlan(void *priv, const u8 *addr,
11621 const char *ifname, int vlan_id)
11622{
11623 struct i802_bss *bss = priv;
11624 return i802_set_sta_vlan(bss, addr, ifname, vlan_id);
11625}
9ebce9c5
JM
11626
11627
11628static int driver_nl80211_read_sta_data(void *priv,
11629 struct hostap_sta_driver_data *data,
11630 const u8 *addr)
11631{
11632 struct i802_bss *bss = priv;
11633 return i802_read_sta_data(bss, data, addr);
11634}
11635
11636
11637static int driver_nl80211_send_action(void *priv, unsigned int freq,
11638 unsigned int wait_time,
11639 const u8 *dst, const u8 *src,
11640 const u8 *bssid,
11641 const u8 *data, size_t data_len,
11642 int no_cck)
11643{
11644 struct i802_bss *bss = priv;
11645 return wpa_driver_nl80211_send_action(bss, freq, wait_time, dst, src,
11646 bssid, data, data_len, no_cck);
11647}
11648
11649
11650static int driver_nl80211_probe_req_report(void *priv, int report)
11651{
11652 struct i802_bss *bss = priv;
11653 return wpa_driver_nl80211_probe_req_report(bss, report);
11654}
11655
11656
6a1ce395
DG
11657static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
11658 const u8 *ies, size_t ies_len)
11659{
11660 int ret;
11661 struct nl_msg *msg;
11662 struct i802_bss *bss = priv;
11663 struct wpa_driver_nl80211_data *drv = bss->drv;
11664 u16 mdid = WPA_GET_LE16(md);
11665
11666 msg = nlmsg_alloc();
11667 if (!msg)
11668 return -ENOMEM;
11669
11670 wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
11671 nl80211_cmd(drv, msg, 0, NL80211_CMD_UPDATE_FT_IES);
11672 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11673 NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies);
11674 NLA_PUT_U16(msg, NL80211_ATTR_MDID, mdid);
11675
11676 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11677 if (ret) {
11678 wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
11679 "err=%d (%s)", ret, strerror(-ret));
11680 }
11681
11682 return ret;
11683
11684nla_put_failure:
11685 nlmsg_free(msg);
11686 return -ENOBUFS;
11687}
11688
11689
597b94f5
AS
11690const u8 * wpa_driver_nl80211_get_macaddr(void *priv)
11691{
11692 struct i802_bss *bss = priv;
11693 struct wpa_driver_nl80211_data *drv = bss->drv;
11694
11695 if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE)
11696 return NULL;
11697
11698 return bss->addr;
11699}
11700
11701
a771c07d
JM
11702static const char * scan_state_str(enum scan_states scan_state)
11703{
11704 switch (scan_state) {
11705 case NO_SCAN:
11706 return "NO_SCAN";
11707 case SCAN_REQUESTED:
11708 return "SCAN_REQUESTED";
11709 case SCAN_STARTED:
11710 return "SCAN_STARTED";
11711 case SCAN_COMPLETED:
11712 return "SCAN_COMPLETED";
11713 case SCAN_ABORTED:
11714 return "SCAN_ABORTED";
11715 case SCHED_SCAN_STARTED:
11716 return "SCHED_SCAN_STARTED";
11717 case SCHED_SCAN_STOPPED:
11718 return "SCHED_SCAN_STOPPED";
11719 case SCHED_SCAN_RESULTS:
11720 return "SCHED_SCAN_RESULTS";
11721 }
11722
11723 return "??";
11724}
11725
11726
11727static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
11728{
11729 struct i802_bss *bss = priv;
11730 struct wpa_driver_nl80211_data *drv = bss->drv;
11731 int res;
11732 char *pos, *end;
11733
11734 pos = buf;
11735 end = buf + buflen;
11736
11737 res = os_snprintf(pos, end - pos,
11738 "ifindex=%d\n"
11739 "ifname=%s\n"
11740 "brname=%s\n"
11741 "addr=" MACSTR "\n"
11742 "freq=%d\n"
11743 "%s%s%s%s%s",
11744 bss->ifindex,
11745 bss->ifname,
11746 bss->brname,
11747 MAC2STR(bss->addr),
11748 bss->freq,
11749 bss->beacon_set ? "beacon_set=1\n" : "",
11750 bss->added_if_into_bridge ?
11751 "added_if_into_bridge=1\n" : "",
11752 bss->added_bridge ? "added_bridge=1\n" : "",
11753 bss->in_deinit ? "in_deinit=1\n" : "",
11754 bss->if_dynamic ? "if_dynamic=1\n" : "");
11755 if (res < 0 || res >= end - pos)
11756 return pos - buf;
11757 pos += res;
11758
11759 if (bss->wdev_id_set) {
11760 res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
11761 (unsigned long long) bss->wdev_id);
11762 if (res < 0 || res >= end - pos)
11763 return pos - buf;
11764 pos += res;
11765 }
11766
11767 res = os_snprintf(pos, end - pos,
11768 "phyname=%s\n"
11769 "drv_ifindex=%d\n"
11770 "operstate=%d\n"
11771 "scan_state=%s\n"
11772 "auth_bssid=" MACSTR "\n"
11773 "auth_attempt_bssid=" MACSTR "\n"
11774 "bssid=" MACSTR "\n"
11775 "prev_bssid=" MACSTR "\n"
11776 "associated=%d\n"
11777 "assoc_freq=%u\n"
11778 "monitor_sock=%d\n"
11779 "monitor_ifidx=%d\n"
11780 "monitor_refcount=%d\n"
11781 "last_mgmt_freq=%u\n"
11782 "eapol_tx_sock=%d\n"
d6a36f39 11783 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
a771c07d
JM
11784 drv->phyname,
11785 drv->ifindex,
11786 drv->operstate,
11787 scan_state_str(drv->scan_state),
11788 MAC2STR(drv->auth_bssid),
11789 MAC2STR(drv->auth_attempt_bssid),
11790 MAC2STR(drv->bssid),
11791 MAC2STR(drv->prev_bssid),
11792 drv->associated,
11793 drv->assoc_freq,
11794 drv->monitor_sock,
11795 drv->monitor_ifidx,
11796 drv->monitor_refcount,
11797 drv->last_mgmt_freq,
11798 drv->eapol_tx_sock,
11799 drv->ignore_if_down_event ?
11800 "ignore_if_down_event=1\n" : "",
11801 drv->scan_complete_events ?
11802 "scan_complete_events=1\n" : "",
11803 drv->disabled_11b_rates ?
11804 "disabled_11b_rates=1\n" : "",
11805 drv->pending_remain_on_chan ?
11806 "pending_remain_on_chan=1\n" : "",
11807 drv->in_interface_list ? "in_interface_list=1\n" : "",
11808 drv->device_ap_sme ? "device_ap_sme=1\n" : "",
11809 drv->poll_command_supported ?
11810 "poll_command_supported=1\n" : "",
11811 drv->data_tx_status ? "data_tx_status=1\n" : "",
11812 drv->scan_for_auth ? "scan_for_auth=1\n" : "",
11813 drv->retry_auth ? "retry_auth=1\n" : "",
11814 drv->use_monitor ? "use_monitor=1\n" : "",
11815 drv->ignore_next_local_disconnect ?
11816 "ignore_next_local_disconnect=1\n" : "",
d6a36f39
JM
11817 drv->ignore_next_local_deauth ?
11818 "ignore_next_local_deauth=1\n" : "",
a771c07d
JM
11819 drv->allow_p2p_device ? "allow_p2p_device=1\n" : "");
11820 if (res < 0 || res >= end - pos)
11821 return pos - buf;
11822 pos += res;
11823
11824 if (drv->has_capability) {
11825 res = os_snprintf(pos, end - pos,
11826 "capa.key_mgmt=0x%x\n"
11827 "capa.enc=0x%x\n"
11828 "capa.auth=0x%x\n"
11829 "capa.flags=0x%x\n"
11830 "capa.max_scan_ssids=%d\n"
11831 "capa.max_sched_scan_ssids=%d\n"
11832 "capa.sched_scan_supported=%d\n"
11833 "capa.max_match_sets=%d\n"
11834 "capa.max_remain_on_chan=%u\n"
11835 "capa.max_stations=%u\n"
11836 "capa.probe_resp_offloads=0x%x\n"
11837 "capa.max_acl_mac_addrs=%u\n"
11838 "capa.num_multichan_concurrent=%u\n",
11839 drv->capa.key_mgmt,
11840 drv->capa.enc,
11841 drv->capa.auth,
11842 drv->capa.flags,
11843 drv->capa.max_scan_ssids,
11844 drv->capa.max_sched_scan_ssids,
11845 drv->capa.sched_scan_supported,
11846 drv->capa.max_match_sets,
11847 drv->capa.max_remain_on_chan,
11848 drv->capa.max_stations,
11849 drv->capa.probe_resp_offloads,
11850 drv->capa.max_acl_mac_addrs,
11851 drv->capa.num_multichan_concurrent);
11852 if (res < 0 || res >= end - pos)
11853 return pos - buf;
11854 pos += res;
11855 }
11856
11857 return pos - buf;
11858}
11859
11860
1c4ffa87
AO
11861static int set_beacon_data(struct nl_msg *msg, struct beacon_data *settings)
11862{
11863 if (settings->head)
11864 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD,
11865 settings->head_len, settings->head);
11866
11867 if (settings->tail)
11868 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL,
11869 settings->tail_len, settings->tail);
11870
11871 if (settings->beacon_ies)
11872 NLA_PUT(msg, NL80211_ATTR_IE,
11873 settings->beacon_ies_len, settings->beacon_ies);
11874
11875 if (settings->proberesp_ies)
11876 NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
11877 settings->proberesp_ies_len, settings->proberesp_ies);
11878
11879 if (settings->assocresp_ies)
11880 NLA_PUT(msg,
11881 NL80211_ATTR_IE_ASSOC_RESP,
11882 settings->assocresp_ies_len, settings->assocresp_ies);
11883
11884 if (settings->probe_resp)
11885 NLA_PUT(msg, NL80211_ATTR_PROBE_RESP,
11886 settings->probe_resp_len, settings->probe_resp);
11887
11888 return 0;
11889
11890nla_put_failure:
11891 return -ENOBUFS;
11892}
11893
11894
11895static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
11896{
11897 struct nl_msg *msg;
11898 struct i802_bss *bss = priv;
11899 struct wpa_driver_nl80211_data *drv = bss->drv;
11900 struct nlattr *beacon_csa;
11901 int ret = -ENOBUFS;
11902
8d1fdde7 11903 wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
1c4ffa87 11904 settings->cs_count, settings->block_tx,
8d1fdde7
JD
11905 settings->freq_params.freq, settings->freq_params.bandwidth,
11906 settings->freq_params.center_freq1,
11907 settings->freq_params.center_freq2);
1c4ffa87 11908
991aa9c7 11909 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
1c4ffa87
AO
11910 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
11911 return -EOPNOTSUPP;
11912 }
11913
11914 if ((drv->nlmode != NL80211_IFTYPE_AP) &&
11915 (drv->nlmode != NL80211_IFTYPE_P2P_GO))
11916 return -EOPNOTSUPP;
11917
11918 /* check settings validity */
11919 if (!settings->beacon_csa.tail ||
11920 ((settings->beacon_csa.tail_len <=
11921 settings->counter_offset_beacon) ||
11922 (settings->beacon_csa.tail[settings->counter_offset_beacon] !=
11923 settings->cs_count)))
11924 return -EINVAL;
11925
11926 if (settings->beacon_csa.probe_resp &&
11927 ((settings->beacon_csa.probe_resp_len <=
11928 settings->counter_offset_presp) ||
11929 (settings->beacon_csa.probe_resp[settings->counter_offset_presp] !=
11930 settings->cs_count)))
11931 return -EINVAL;
11932
11933 msg = nlmsg_alloc();
11934 if (!msg)
11935 return -ENOMEM;
11936
11937 nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
11938 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11939 NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count);
11940 ret = nl80211_put_freq_params(msg, &settings->freq_params);
11941 if (ret)
11942 goto error;
11943
11944 if (settings->block_tx)
11945 NLA_PUT_FLAG(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX);
11946
11947 /* beacon_after params */
11948 ret = set_beacon_data(msg, &settings->beacon_after);
11949 if (ret)
11950 goto error;
11951
11952 /* beacon_csa params */
11953 beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES);
11954 if (!beacon_csa)
11955 goto nla_put_failure;
11956
11957 ret = set_beacon_data(msg, &settings->beacon_csa);
11958 if (ret)
11959 goto error;
11960
11961 NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_BEACON,
11962 settings->counter_offset_beacon);
11963
11964 if (settings->beacon_csa.probe_resp)
11965 NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_PRESP,
11966 settings->counter_offset_presp);
11967
11968 nla_nest_end(msg, beacon_csa);
11969 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11970 if (ret) {
11971 wpa_printf(MSG_DEBUG, "nl80211: switch_channel failed err=%d (%s)",
11972 ret, strerror(-ret));
11973 }
11974 return ret;
11975
11976nla_put_failure:
11977 ret = -ENOBUFS;
11978error:
11979 nlmsg_free(msg);
11980 wpa_printf(MSG_DEBUG, "nl80211: Could not build channel switch request");
11981 return ret;
11982}
11983
11984
6b9f7af6
JM
11985#ifdef CONFIG_TESTING_OPTIONS
11986static int cmd_reply_handler(struct nl_msg *msg, void *arg)
11987{
11988 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11989 struct wpabuf *buf = arg;
11990
11991 if (!buf)
11992 return NL_SKIP;
11993
11994 if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
11995 wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
11996 return NL_SKIP;
11997 }
11998
11999 wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
12000 genlmsg_attrlen(gnlh, 0));
12001
12002 return NL_SKIP;
12003}
12004#endif /* CONFIG_TESTING_OPTIONS */
12005
12006
adef8948
BL
12007static int vendor_reply_handler(struct nl_msg *msg, void *arg)
12008{
12009 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12010 struct nlattr *nl_vendor_reply, *nl;
12011 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12012 struct wpabuf *buf = arg;
12013 int rem;
12014
12015 if (!buf)
12016 return NL_SKIP;
12017
12018 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
12019 genlmsg_attrlen(gnlh, 0), NULL);
12020 nl_vendor_reply = tb[NL80211_ATTR_VENDOR_DATA];
12021
12022 if (!nl_vendor_reply)
12023 return NL_SKIP;
12024
12025 if ((size_t) nla_len(nl_vendor_reply) > wpabuf_tailroom(buf)) {
12026 wpa_printf(MSG_INFO, "nl80211: Vendor command: insufficient buffer space for reply");
12027 return NL_SKIP;
12028 }
12029
12030 nla_for_each_nested(nl, nl_vendor_reply, rem) {
12031 wpabuf_put_data(buf, nla_data(nl), nla_len(nl));
12032 }
12033
12034 return NL_SKIP;
12035}
12036
12037
12038static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
12039 unsigned int subcmd, const u8 *data,
12040 size_t data_len, struct wpabuf *buf)
12041{
12042 struct i802_bss *bss = priv;
12043 struct wpa_driver_nl80211_data *drv = bss->drv;
12044 struct nl_msg *msg;
12045 int ret;
12046
12047 msg = nlmsg_alloc();
12048 if (!msg)
12049 return -ENOMEM;
12050
6b9f7af6
JM
12051#ifdef CONFIG_TESTING_OPTIONS
12052 if (vendor_id == 0xffffffff) {
12053 nl80211_cmd(drv, msg, 0, subcmd);
12054 if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
12055 0)
12056 goto nla_put_failure;
12057 ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
12058 if (ret)
12059 wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
12060 ret);
12061 return ret;
12062 }
12063#endif /* CONFIG_TESTING_OPTIONS */
12064
adef8948
BL
12065 nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
12066 if (nl80211_set_iface_id(msg, bss) < 0)
12067 goto nla_put_failure;
12068 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, vendor_id);
12069 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd);
12070 if (data)
12071 NLA_PUT(msg, NL80211_ATTR_VENDOR_DATA, data_len, data);
12072
12073 ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, buf);
12074 if (ret)
12075 wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d",
12076 ret);
12077 return ret;
12078
12079nla_put_failure:
12080 nlmsg_free(msg);
12081 return -ENOBUFS;
12082}
12083
12084
049105b4
KP
12085static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
12086 u8 qos_map_set_len)
12087{
12088 struct i802_bss *bss = priv;
12089 struct wpa_driver_nl80211_data *drv = bss->drv;
12090 struct nl_msg *msg;
12091 int ret;
12092
12093 msg = nlmsg_alloc();
12094 if (!msg)
12095 return -ENOMEM;
12096
12097 wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
12098 qos_map_set, qos_map_set_len);
12099
12100 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_QOS_MAP);
12101 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
12102 NLA_PUT(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set);
12103
12104 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
12105 if (ret)
12106 wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
12107
12108 return ret;
12109
12110nla_put_failure:
12111 nlmsg_free(msg);
12112 return -ENOBUFS;
12113}
12114
12115
3f5285e8
JM
12116const struct wpa_driver_ops wpa_driver_nl80211_ops = {
12117 .name = "nl80211",
12118 .desc = "Linux nl80211/cfg80211",
12119 .get_bssid = wpa_driver_nl80211_get_bssid,
12120 .get_ssid = wpa_driver_nl80211_get_ssid,
9ebce9c5
JM
12121 .set_key = driver_nl80211_set_key,
12122 .scan2 = driver_nl80211_scan2,
d21c63b9
LC
12123 .sched_scan = wpa_driver_nl80211_sched_scan,
12124 .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
3f5285e8 12125 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
9ebce9c5
JM
12126 .deauthenticate = driver_nl80211_deauthenticate,
12127 .authenticate = driver_nl80211_authenticate,
3f5285e8 12128 .associate = wpa_driver_nl80211_associate,
f2ed8023
JM
12129 .global_init = nl80211_global_init,
12130 .global_deinit = nl80211_global_deinit,
12131 .init2 = wpa_driver_nl80211_init,
9ebce9c5 12132 .deinit = driver_nl80211_deinit,
3f5285e8
JM
12133 .get_capa = wpa_driver_nl80211_get_capa,
12134 .set_operstate = wpa_driver_nl80211_set_operstate,
01652550 12135 .set_supp_port = wpa_driver_nl80211_set_supp_port,
6d158490 12136 .set_country = wpa_driver_nl80211_set_country,
f0793bf1 12137 .get_country = wpa_driver_nl80211_get_country,
19c3b566 12138 .set_ap = wpa_driver_nl80211_set_ap,
3c4ca363 12139 .set_acl = wpa_driver_nl80211_set_acl,
22a7c9d7 12140 .if_add = wpa_driver_nl80211_if_add,
9ebce9c5
JM
12141 .if_remove = driver_nl80211_if_remove,
12142 .send_mlme = driver_nl80211_send_mlme,
c3965310 12143 .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
0f4e8b4f 12144 .sta_add = wpa_driver_nl80211_sta_add,
9ebce9c5 12145 .sta_remove = driver_nl80211_sta_remove,
db149ac9 12146 .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
a8d6ffa4 12147 .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
c5121837 12148 .hapd_init = i802_init,
c5121837 12149 .hapd_deinit = i802_deinit,
f7b3920c 12150 .set_wds_sta = i802_set_wds_sta,
c5121837
JM
12151 .get_seqnum = i802_get_seqnum,
12152 .flush = i802_flush,
c5121837
JM
12153 .get_inact_sec = i802_get_inact_sec,
12154 .sta_clear_stats = i802_sta_clear_stats,
c5121837
JM
12155 .set_rts = i802_set_rts,
12156 .set_frag = i802_set_frag,
c5121837 12157 .set_tx_queue_params = i802_set_tx_queue_params,
9ebce9c5 12158 .set_sta_vlan = driver_nl80211_set_sta_vlan,
ee7ab173
JB
12159 .sta_deauth = i802_sta_deauth,
12160 .sta_disassoc = i802_sta_disassoc,
9ebce9c5 12161 .read_sta_data = driver_nl80211_read_sta_data,
e3802622 12162 .set_freq = i802_set_freq,
9ebce9c5 12163 .send_action = driver_nl80211_send_action,
5dfca53f 12164 .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
55777702
JM
12165 .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
12166 .cancel_remain_on_channel =
12167 wpa_driver_nl80211_cancel_remain_on_channel,
9ebce9c5 12168 .probe_req_report = driver_nl80211_probe_req_report,
af473088 12169 .deinit_ap = wpa_driver_nl80211_deinit_ap,
3c29244e 12170 .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
207ef3fb 12171 .resume = wpa_driver_nl80211_resume,
7b90c16a 12172 .send_ft_action = nl80211_send_ft_action,
b625473c 12173 .signal_monitor = nl80211_signal_monitor,
1c5c7273 12174 .signal_poll = nl80211_signal_poll,
b91ab76e 12175 .send_frame = nl80211_send_frame,
57ebba59 12176 .shared_freq = wpa_driver_nl80211_shared_freq,
c55f774d 12177 .set_param = nl80211_set_param,
6859f1cb 12178 .get_radio_name = nl80211_get_radio_name,
a6efc65d
JM
12179 .add_pmkid = nl80211_add_pmkid,
12180 .remove_pmkid = nl80211_remove_pmkid,
12181 .flush_pmkid = nl80211_flush_pmkid,
b14a210c 12182 .set_rekey_info = nl80211_set_rekey_info,
bcf24348 12183 .poll_client = nl80211_poll_client,
29f338af 12184 .set_p2p_powersave = nl80211_set_p2p_powersave,
f90e9c1c 12185 .start_dfs_cac = nl80211_start_radar_detection,
695c7038 12186 .stop_ap = wpa_driver_nl80211_stop_ap,
03ea1786
AN
12187#ifdef CONFIG_TDLS
12188 .send_tdls_mgmt = nl80211_send_tdls_mgmt,
12189 .tdls_oper = nl80211_tdls_oper,
12190#endif /* CONFIG_TDLS */
6a1ce395 12191 .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
597b94f5 12192 .get_mac_addr = wpa_driver_nl80211_get_macaddr,
0185007c 12193 .get_survey = wpa_driver_nl80211_get_survey,
a771c07d 12194 .status = wpa_driver_nl80211_status,
1c4ffa87 12195 .switch_channel = nl80211_switch_channel,
0de38036
JM
12196#ifdef ANDROID_P2P
12197 .set_noa = wpa_driver_set_p2p_noa,
12198 .get_noa = wpa_driver_get_p2p_noa,
12199 .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
12200#endif /* ANDROID_P2P */
5e2c3490
JM
12201#ifdef ANDROID
12202 .driver_cmd = wpa_driver_nl80211_driver_cmd,
12203#endif /* ANDROID */
adef8948 12204 .vendor_cmd = nl80211_vendor_cmd,
049105b4 12205 .set_qos_map = nl80211_set_qos_map,
3f5285e8 12206};