]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/drivers/driver_nl80211.c
nl80211: Cancel rfkill timeout on deinit
[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);
e390df05 4827 eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
8401a6b0 4828 rfkill_deinit(drv->rfkill);
3f5285e8 4829
bbaf0837
JM
4830 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
4831
146fa9b3
JM
4832 if (!drv->start_iface_up)
4833 (void) i802_set_iface_flags(bss, 0);
8e12685c 4834 if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
49b4b205
JM
4835 if (!drv->hostapd || !drv->start_mode_ap)
4836 wpa_driver_nl80211_set_mode(bss,
4837 NL80211_IFTYPE_STATION);
b378c41f 4838 nl80211_mgmt_unsubscribe(bss, "deinit");
8e12685c
AS
4839 } else {
4840 nl80211_mgmt_unsubscribe(bss, "deinit");
eb4582f2 4841 nl80211_del_p2pdev(bss);
8e12685c 4842 }
1afc986d 4843 nl_cb_put(drv->nl_cb);
3f5285e8 4844
834ee56f 4845 nl80211_destroy_bss(drv->first_bss);
cc7a48d1 4846
3812464c
JM
4847 os_free(drv->filter_ssids);
4848
536fd62d
JM
4849 os_free(drv->auth_ie);
4850
dac12351 4851 if (drv->in_interface_list)
f2ed8023
JM
4852 dl_list_del(&drv->list);
4853
8cd6b7bc
JB
4854 os_free(drv->extended_capa);
4855 os_free(drv->extended_capa_mask);
834ee56f 4856 os_free(drv->first_bss);
3f5285e8
JM
4857 os_free(drv);
4858}
4859
4860
4861/**
4862 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
ad1e68e6 4863 * @eloop_ctx: Driver private data
3f5285e8
JM
4864 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
4865 *
4866 * This function can be used as registered timeout when starting a scan to
4867 * generate a scan completed event if the driver does not report this.
4868 */
4869static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
4870{
ad1e68e6 4871 struct wpa_driver_nl80211_data *drv = eloop_ctx;
b1f625e0 4872 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
834ee56f 4873 wpa_driver_nl80211_set_mode(drv->first_bss,
b1f625e0
EP
4874 drv->ap_scan_as_station);
4875 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
ad1e68e6 4876 }
3f5285e8
JM
4877 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
4878 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
4879}
4880
4881
95ac3bf4
JM
4882static struct nl_msg *
4883nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
d3aaef80 4884 struct wpa_driver_scan_params *params, u64 *wdev_id)
3f5285e8 4885{
95ac3bf4 4886 struct nl_msg *msg;
6a1063e0 4887 size_t i;
3f5285e8 4888
0e75527f 4889 msg = nlmsg_alloc();
f0494d0f 4890 if (!msg)
95ac3bf4 4891 return NULL;
3812464c 4892
95ac3bf4 4893 nl80211_cmd(drv, msg, 0, cmd);
0e75527f 4894
d3aaef80
DS
4895 if (!wdev_id)
4896 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4897 else
4898 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, *wdev_id);
3f5285e8 4899
f0494d0f 4900 if (params->num_ssids) {
8970bae8
JB
4901 struct nlattr *ssids;
4902
4903 ssids = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
f0494d0f 4904 if (ssids == NULL)
95ac3bf4 4905 goto fail;
f0494d0f
JM
4906 for (i = 0; i < params->num_ssids; i++) {
4907 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
4908 params->ssids[i].ssid,
4909 params->ssids[i].ssid_len);
8970bae8
JB
4910 if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
4911 params->ssids[i].ssid) < 0)
95ac3bf4 4912 goto fail;
f0494d0f 4913 }
8970bae8 4914 nla_nest_end(msg, ssids);
3f5285e8
JM
4915 }
4916
d173df52 4917 if (params->extra_ies) {
3b1c7bfd
JM
4918 wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
4919 params->extra_ies, params->extra_ies_len);
95ac3bf4
JM
4920 if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
4921 params->extra_ies) < 0)
4922 goto fail;
d173df52
JM
4923 }
4924
d3a98225 4925 if (params->freqs) {
8970bae8
JB
4926 struct nlattr *freqs;
4927 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
f0494d0f 4928 if (freqs == NULL)
95ac3bf4 4929 goto fail;
9fad706c
JM
4930 for (i = 0; params->freqs[i]; i++) {
4931 wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
4932 "MHz", params->freqs[i]);
8970bae8 4933 if (nla_put_u32(msg, i + 1, params->freqs[i]) < 0)
95ac3bf4 4934 goto fail;
9fad706c 4935 }
8970bae8 4936 nla_nest_end(msg, freqs);
d3a98225
JM
4937 }
4938
95ac3bf4
JM
4939 os_free(drv->filter_ssids);
4940 drv->filter_ssids = params->filter_ssids;
4941 params->filter_ssids = NULL;
4942 drv->num_filter_ssids = params->num_filter_ssids;
4943
949938aa
JM
4944 if (params->only_new_results) {
4945 wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
4946 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS,
4947 NL80211_SCAN_FLAG_FLUSH);
4948 }
4949
95ac3bf4
JM
4950 return msg;
4951
4952fail:
d3aaef80 4953nla_put_failure:
95ac3bf4
JM
4954 nlmsg_free(msg);
4955 return NULL;
4956}
4957
4958
4959/**
4960 * wpa_driver_nl80211_scan - Request the driver to initiate scan
9ebce9c5 4961 * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
95ac3bf4
JM
4962 * @params: Scan parameters
4963 * Returns: 0 on success, -1 on failure
4964 */
9ebce9c5 4965static int wpa_driver_nl80211_scan(struct i802_bss *bss,
95ac3bf4
JM
4966 struct wpa_driver_scan_params *params)
4967{
95ac3bf4
JM
4968 struct wpa_driver_nl80211_data *drv = bss->drv;
4969 int ret = -1, timeout;
8970bae8 4970 struct nl_msg *msg = NULL;
95ac3bf4 4971
565110cd 4972 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
95ac3bf4
JM
4973 drv->scan_for_auth = 0;
4974
d3aaef80
DS
4975 msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params,
4976 bss->wdev_id_set ? &bss->wdev_id : NULL);
95ac3bf4
JM
4977 if (!msg)
4978 return -1;
4979
47185fc7 4980 if (params->p2p_probe) {
8970bae8
JB
4981 struct nlattr *rates;
4982
8a6a1e1b
JM
4983 wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
4984
8970bae8 4985 rates = nla_nest_start(msg, NL80211_ATTR_SCAN_SUPP_RATES);
f0494d0f
JM
4986 if (rates == NULL)
4987 goto nla_put_failure;
4988
47185fc7
RM
4989 /*
4990 * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
4991 * by masking out everything else apart from the OFDM rates 6,
4992 * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
4993 * rates are left enabled.
4994 */
8970bae8 4995 NLA_PUT(msg, NL80211_BAND_2GHZ, 8,
47185fc7 4996 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
8970bae8 4997 nla_nest_end(msg, rates);
970fa12e
RM
4998
4999 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
47185fc7
RM
5000 }
5001
0e75527f
JM
5002 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5003 msg = NULL;
5004 if (ret) {
5005 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
5006 "(%s)", ret, strerror(-ret));
04eff7d5 5007 if (drv->hostapd && is_ap_interface(drv->nlmode)) {
72e7fb3f
YP
5008 enum nl80211_iftype old_mode = drv->nlmode;
5009
ad1e68e6
JM
5010 /*
5011 * mac80211 does not allow scan requests in AP mode, so
5012 * try to do this in station mode.
5013 */
b1f625e0
EP
5014 if (wpa_driver_nl80211_set_mode(
5015 bss, NL80211_IFTYPE_STATION))
ad1e68e6
JM
5016 goto nla_put_failure;
5017
085b29f1 5018 if (wpa_driver_nl80211_scan(bss, params)) {
b1f625e0 5019 wpa_driver_nl80211_set_mode(bss, drv->nlmode);
ad1e68e6
JM
5020 goto nla_put_failure;
5021 }
5022
5023 /* Restore AP mode when processing scan results */
72e7fb3f 5024 drv->ap_scan_as_station = old_mode;
ad1e68e6
JM
5025 ret = 0;
5026 } else
5027 goto nla_put_failure;
3f5285e8
JM
5028 }
5029
a771c07d 5030 drv->scan_state = SCAN_REQUESTED;
3f5285e8
JM
5031 /* Not all drivers generate "scan completed" wireless event, so try to
5032 * read results after a timeout. */
0e75527f 5033 timeout = 10;
3f5285e8
JM
5034 if (drv->scan_complete_events) {
5035 /*
d173df52
JM
5036 * The driver seems to deliver events to notify when scan is
5037 * complete, so use longer timeout to avoid race conditions
5038 * with scanning and following association request.
3f5285e8
JM
5039 */
5040 timeout = 30;
5041 }
5042 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
5043 "seconds", ret, timeout);
5044 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
0e75527f
JM
5045 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
5046 drv, drv->ctx);
3f5285e8 5047
0e75527f 5048nla_put_failure:
0e75527f 5049 nlmsg_free(msg);
3f5285e8
JM
5050 return ret;
5051}
5052
5053
d21c63b9
LC
5054/**
5055 * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
5056 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
5057 * @params: Scan parameters
5058 * @interval: Interval between scan cycles in milliseconds
5059 * Returns: 0 on success, -1 on failure or if not supported
5060 */
5061static int wpa_driver_nl80211_sched_scan(void *priv,
5062 struct wpa_driver_scan_params *params,
5063 u32 interval)
5064{
5065 struct i802_bss *bss = priv;
5066 struct wpa_driver_nl80211_data *drv = bss->drv;
6afbc3d6 5067 int ret = -1;
95ac3bf4 5068 struct nl_msg *msg;
d21c63b9
LC
5069 size_t i;
5070
565110cd
JM
5071 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request");
5072
216eede8
DS
5073#ifdef ANDROID
5074 if (!drv->capa.sched_scan_supported)
5075 return android_pno_start(bss, params);
5076#endif /* ANDROID */
5077
d3aaef80
DS
5078 msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params,
5079 bss->wdev_id_set ? &bss->wdev_id : NULL);
6afbc3d6
JM
5080 if (!msg)
5081 goto nla_put_failure;
d21c63b9 5082
d21c63b9
LC
5083 NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
5084
bf8d6d24
TP
5085 if ((drv->num_filter_ssids &&
5086 (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
5087 params->filter_rssi) {
8970bae8
JB
5088 struct nlattr *match_sets;
5089 match_sets = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
6afbc3d6
JM
5090 if (match_sets == NULL)
5091 goto nla_put_failure;
bd525934
LC
5092
5093 for (i = 0; i < drv->num_filter_ssids; i++) {
8970bae8 5094 struct nlattr *match_set_ssid;
bd525934
LC
5095 wpa_hexdump_ascii(MSG_MSGDUMP,
5096 "nl80211: Sched scan filter SSID",
5097 drv->filter_ssids[i].ssid,
5098 drv->filter_ssids[i].ssid_len);
5099
8970bae8 5100 match_set_ssid = nla_nest_start(msg, i + 1);
6afbc3d6
JM
5101 if (match_set_ssid == NULL)
5102 goto nla_put_failure;
8970bae8 5103 NLA_PUT(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
bd525934
LC
5104 drv->filter_ssids[i].ssid_len,
5105 drv->filter_ssids[i].ssid);
ff5e1d14
JB
5106 if (params->filter_rssi)
5107 NLA_PUT_U32(msg,
5108 NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
5109 params->filter_rssi);
bd525934 5110
adc96dc2 5111 nla_nest_end(msg, match_set_ssid);
bd525934
LC
5112 }
5113
ff5e1d14
JB
5114 /*
5115 * Due to backward compatibility code, newer kernels treat this
5116 * matchset (with only an RSSI filter) as the default for all
5117 * other matchsets, unless it's the only one, in which case the
5118 * matchset will actually allow all SSIDs above the RSSI.
5119 */
bf8d6d24 5120 if (params->filter_rssi) {
8970bae8
JB
5121 struct nlattr *match_set_rssi;
5122 match_set_rssi = nla_nest_start(msg, 0);
6afbc3d6
JM
5123 if (match_set_rssi == NULL)
5124 goto nla_put_failure;
8970bae8 5125 NLA_PUT_U32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
bf8d6d24
TP
5126 params->filter_rssi);
5127 wpa_printf(MSG_MSGDUMP,
5128 "nl80211: Sched scan RSSI filter %d dBm",
5129 params->filter_rssi);
8970bae8 5130 nla_nest_end(msg, match_set_rssi);
bf8d6d24
TP
5131 }
5132
8970bae8 5133 nla_nest_end(msg, match_sets);
bd525934
LC
5134 }
5135
d21c63b9
LC
5136 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5137
5138 /* TODO: if we get an error here, we should fall back to normal scan */
5139
5140 msg = NULL;
5141 if (ret) {
5142 wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
5143 "ret=%d (%s)", ret, strerror(-ret));
5144 goto nla_put_failure;
5145 }
5146
5147 wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
5148 "scan interval %d msec", ret, interval);
5149
5150nla_put_failure:
d21c63b9 5151 nlmsg_free(msg);
d21c63b9
LC
5152 return ret;
5153}
5154
5155
5156/**
5157 * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
5158 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
5159 * Returns: 0 on success, -1 on failure or if not supported
5160 */
5161static int wpa_driver_nl80211_stop_sched_scan(void *priv)
5162{
5163 struct i802_bss *bss = priv;
5164 struct wpa_driver_nl80211_data *drv = bss->drv;
5165 int ret = 0;
5166 struct nl_msg *msg;
5167
216eede8
DS
5168#ifdef ANDROID
5169 if (!drv->capa.sched_scan_supported)
5170 return android_pno_stop(bss);
5171#endif /* ANDROID */
5172
d21c63b9
LC
5173 msg = nlmsg_alloc();
5174 if (!msg)
5175 return -1;
5176
9fb04070 5177 nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_SCHED_SCAN);
d21c63b9
LC
5178
5179 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5180
5181 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5182 msg = NULL;
5183 if (ret) {
5184 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop failed: "
5185 "ret=%d (%s)", ret, strerror(-ret));
5186 goto nla_put_failure;
5187 }
5188
5189 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop sent (ret=%d)", ret);
5190
5191nla_put_failure:
5192 nlmsg_free(msg);
5193 return ret;
5194}
5195
5196
3812464c
JM
5197static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
5198{
5199 const u8 *end, *pos;
5200
5201 if (ies == NULL)
5202 return NULL;
5203
5204 pos = ies;
5205 end = ies + ies_len;
5206
5207 while (pos + 1 < end) {
5208 if (pos + 2 + pos[1] > end)
5209 break;
5210 if (pos[0] == ie)
5211 return pos;
5212 pos += 2 + pos[1];
5213 }
5214
5215 return NULL;
5216}
5217
5218
5219static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
5220 const u8 *ie, size_t ie_len)
5221{
5222 const u8 *ssid;
5223 size_t i;
5224
5225 if (drv->filter_ssids == NULL)
5226 return 0;
5227
5228 ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
5229 if (ssid == NULL)
5230 return 1;
5231
5232 for (i = 0; i < drv->num_filter_ssids; i++) {
5233 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
5234 os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
5235 0)
5236 return 0;
5237 }
5238
5239 return 1;
5240}
5241
5242
b3db1e1c 5243static int bss_info_handler(struct nl_msg *msg, void *arg)
3f5285e8 5244{
b3db1e1c
JM
5245 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5246 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5247 struct nlattr *bss[NL80211_BSS_MAX + 1];
5248 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
5249 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
5250 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
5251 [NL80211_BSS_TSF] = { .type = NLA_U64 },
5252 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
5253 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
5254 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
5255 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
5256 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
e6b8efeb 5257 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
b3ad11bb 5258 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
8c090654 5259 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
b3db1e1c 5260 };
3812464c
JM
5261 struct nl80211_bss_info_arg *_arg = arg;
5262 struct wpa_scan_results *res = _arg->res;
3f5285e8
JM
5263 struct wpa_scan_res **tmp;
5264 struct wpa_scan_res *r;
8c090654
JM
5265 const u8 *ie, *beacon_ie;
5266 size_t ie_len, beacon_ie_len;
5267 u8 *pos;
46957a9b 5268 size_t i;
3f5285e8 5269
b3db1e1c
JM
5270 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5271 genlmsg_attrlen(gnlh, 0), NULL);
5272 if (!tb[NL80211_ATTR_BSS])
5273 return NL_SKIP;
5274 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
5275 bss_policy))
5276 return NL_SKIP;
f5a8d422
JM
5277 if (bss[NL80211_BSS_STATUS]) {
5278 enum nl80211_bss_status status;
5279 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
5280 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
5281 bss[NL80211_BSS_FREQUENCY]) {
5282 _arg->assoc_freq =
5283 nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
5284 wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
5285 _arg->assoc_freq);
5286 }
20f5a4c2
JM
5287 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
5288 bss[NL80211_BSS_BSSID]) {
5289 os_memcpy(_arg->assoc_bssid,
5290 nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN);
5291 wpa_printf(MSG_DEBUG, "nl80211: Associated with "
5292 MACSTR, MAC2STR(_arg->assoc_bssid));
5293 }
f5a8d422
JM
5294 }
5295 if (!res)
5296 return NL_SKIP;
b3db1e1c
JM
5297 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
5298 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
5299 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
5300 } else {
5301 ie = NULL;
5302 ie_len = 0;
5303 }
8c090654
JM
5304 if (bss[NL80211_BSS_BEACON_IES]) {
5305 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
5306 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
5307 } else {
5308 beacon_ie = NULL;
5309 beacon_ie_len = 0;
5310 }
3f5285e8 5311
3812464c
JM
5312 if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
5313 ie ? ie_len : beacon_ie_len))
5314 return NL_SKIP;
5315
8c090654 5316 r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
3f5285e8 5317 if (r == NULL)
b3db1e1c
JM
5318 return NL_SKIP;
5319 if (bss[NL80211_BSS_BSSID])
5320 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
5321 ETH_ALEN);
5322 if (bss[NL80211_BSS_FREQUENCY])
5323 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
5324 if (bss[NL80211_BSS_BEACON_INTERVAL])
5325 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
5326 if (bss[NL80211_BSS_CAPABILITY])
5327 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
7c2849d2
JM
5328 r->flags |= WPA_SCAN_NOISE_INVALID;
5329 if (bss[NL80211_BSS_SIGNAL_MBM]) {
b3db1e1c 5330 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
7c2849d2
JM
5331 r->level /= 100; /* mBm to dBm */
5332 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
5333 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
5334 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
98ac6763 5335 r->flags |= WPA_SCAN_QUAL_INVALID;
7c2849d2
JM
5336 } else
5337 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
b3db1e1c
JM
5338 if (bss[NL80211_BSS_TSF])
5339 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
b3ad11bb
JM
5340 if (bss[NL80211_BSS_SEEN_MS_AGO])
5341 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
b3db1e1c 5342 r->ie_len = ie_len;
8c090654
JM
5343 pos = (u8 *) (r + 1);
5344 if (ie) {
5345 os_memcpy(pos, ie, ie_len);
5346 pos += ie_len;
5347 }
5348 r->beacon_ie_len = beacon_ie_len;
5349 if (beacon_ie)
5350 os_memcpy(pos, beacon_ie, beacon_ie_len);
3f5285e8 5351
e6b8efeb
JM
5352 if (bss[NL80211_BSS_STATUS]) {
5353 enum nl80211_bss_status status;
5354 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
5355 switch (status) {
5356 case NL80211_BSS_STATUS_AUTHENTICATED:
5357 r->flags |= WPA_SCAN_AUTHENTICATED;
5358 break;
5359 case NL80211_BSS_STATUS_ASSOCIATED:
5360 r->flags |= WPA_SCAN_ASSOCIATED;
5361 break;
5362 default:
5363 break;
5364 }
5365 }
5366
46957a9b
JM
5367 /*
5368 * cfg80211 maintains separate BSS table entries for APs if the same
5369 * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
5370 * not use frequency as a separate key in the BSS table, so filter out
5371 * duplicated entries. Prefer associated BSS entry in such a case in
4ea6a471
JM
5372 * order to get the correct frequency into the BSS table. Similarly,
5373 * prefer newer entries over older.
46957a9b
JM
5374 */
5375 for (i = 0; i < res->num; i++) {
5376 const u8 *s1, *s2;
5377 if (os_memcmp(res->res[i]->bssid, r->bssid, ETH_ALEN) != 0)
5378 continue;
5379
5380 s1 = nl80211_get_ie((u8 *) (res->res[i] + 1),
5381 res->res[i]->ie_len, WLAN_EID_SSID);
5382 s2 = nl80211_get_ie((u8 *) (r + 1), r->ie_len, WLAN_EID_SSID);
5383 if (s1 == NULL || s2 == NULL || s1[1] != s2[1] ||
5384 os_memcmp(s1, s2, 2 + s1[1]) != 0)
5385 continue;
5386
5387 /* Same BSSID,SSID was already included in scan results */
5388 wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
5389 "for " MACSTR, MAC2STR(r->bssid));
5390
4ea6a471
JM
5391 if (((r->flags & WPA_SCAN_ASSOCIATED) &&
5392 !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) ||
5393 r->age < res->res[i]->age) {
46957a9b
JM
5394 os_free(res->res[i]);
5395 res->res[i] = r;
5396 } else
5397 os_free(r);
5398 return NL_SKIP;
5399 }
5400
067ffa26
JM
5401 tmp = os_realloc_array(res->res, res->num + 1,
5402 sizeof(struct wpa_scan_res *));
3f5285e8
JM
5403 if (tmp == NULL) {
5404 os_free(r);
b3db1e1c 5405 return NL_SKIP;
3f5285e8
JM
5406 }
5407 tmp[res->num++] = r;
5408 res->res = tmp;
b3db1e1c
JM
5409
5410 return NL_SKIP;
3f5285e8 5411}
b3db1e1c 5412
3f5285e8 5413
d72aad94
JM
5414static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
5415 const u8 *addr)
5416{
5417 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
5418 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
582507be 5419 "mismatch (" MACSTR ")", MAC2STR(addr));
d72aad94
JM
5420 wpa_driver_nl80211_mlme(drv, addr,
5421 NL80211_CMD_DEAUTHENTICATE,
77339912 5422 WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
d72aad94
JM
5423 }
5424}
5425
5426
e6b8efeb
JM
5427static void wpa_driver_nl80211_check_bss_status(
5428 struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
5429{
5430 size_t i;
5431
5432 for (i = 0; i < res->num; i++) {
5433 struct wpa_scan_res *r = res->res[i];
5434 if (r->flags & WPA_SCAN_AUTHENTICATED) {
5435 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
5436 "indicates BSS status with " MACSTR
5437 " as authenticated",
5438 MAC2STR(r->bssid));
b1f625e0 5439 if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
5440 os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
5441 os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
5442 0) {
5443 wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
5444 " in local state (auth=" MACSTR
5445 " assoc=" MACSTR ")",
5446 MAC2STR(drv->auth_bssid),
5447 MAC2STR(drv->bssid));
582507be 5448 clear_state_mismatch(drv, r->bssid);
e6b8efeb
JM
5449 }
5450 }
5451
5452 if (r->flags & WPA_SCAN_ASSOCIATED) {
5453 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
5454 "indicate BSS status with " MACSTR
5455 " as associated",
5456 MAC2STR(r->bssid));
b1f625e0 5457 if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
5458 !drv->associated) {
5459 wpa_printf(MSG_DEBUG, "nl80211: Local state "
5460 "(not associated) does not match "
5461 "with BSS state");
d72aad94 5462 clear_state_mismatch(drv, r->bssid);
b1f625e0 5463 } else if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
5464 os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
5465 0) {
5466 wpa_printf(MSG_DEBUG, "nl80211: Local state "
5467 "(associated with " MACSTR ") does "
5468 "not match with BSS state",
d72aad94
JM
5469 MAC2STR(drv->bssid));
5470 clear_state_mismatch(drv, r->bssid);
5471 clear_state_mismatch(drv, drv->bssid);
e6b8efeb
JM
5472 }
5473 }
5474 }
5475}
5476
5477
7e5ba1b9 5478static struct wpa_scan_results *
8856462d 5479nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
3f5285e8 5480{
b3db1e1c 5481 struct nl_msg *msg;
3f5285e8 5482 struct wpa_scan_results *res;
b3db1e1c 5483 int ret;
3812464c 5484 struct nl80211_bss_info_arg arg;
3f5285e8
JM
5485
5486 res = os_zalloc(sizeof(*res));
b3db1e1c 5487 if (res == NULL)
8e2c104f 5488 return NULL;
b3db1e1c
JM
5489 msg = nlmsg_alloc();
5490 if (!msg)
5491 goto nla_put_failure;
3f5285e8 5492
9fb04070 5493 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
834ee56f 5494 if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
fdc554b8 5495 goto nla_put_failure;
3f5285e8 5496
3812464c
JM
5497 arg.drv = drv;
5498 arg.res = res;
5499 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
b3db1e1c
JM
5500 msg = NULL;
5501 if (ret == 0) {
577db0ae
GM
5502 wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu "
5503 "BSSes)", (unsigned long) res->num);
5504 nl80211_get_noise_for_scan_results(drv, res);
b3db1e1c 5505 return res;
3f5285e8 5506 }
b3db1e1c
JM
5507 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
5508 "(%s)", ret, strerror(-ret));
5509nla_put_failure:
5510 nlmsg_free(msg);
5511 wpa_scan_results_free(res);
5512 return NULL;
3f5285e8
JM
5513}
5514
5515
8856462d
JM
5516/**
5517 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
5518 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
5519 * Returns: Scan results on success, -1 on failure
5520 */
5521static struct wpa_scan_results *
5522wpa_driver_nl80211_get_scan_results(void *priv)
5523{
a2e40bb6
FF
5524 struct i802_bss *bss = priv;
5525 struct wpa_driver_nl80211_data *drv = bss->drv;
8856462d
JM
5526 struct wpa_scan_results *res;
5527
5528 res = nl80211_get_scan_results(drv);
5529 if (res)
5530 wpa_driver_nl80211_check_bss_status(drv, res);
5531 return res;
5532}
5533
5534
5535static void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
5536{
5537 struct wpa_scan_results *res;
5538 size_t i;
5539
5540 res = nl80211_get_scan_results(drv);
5541 if (res == NULL) {
5542 wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
5543 return;
5544 }
5545
5546 wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
5547 for (i = 0; i < res->num; i++) {
5548 struct wpa_scan_res *r = res->res[i];
5549 wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s%s",
5550 (int) i, (int) res->num, MAC2STR(r->bssid),
5551 r->flags & WPA_SCAN_AUTHENTICATED ? " [auth]" : "",
5552 r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
5553 }
5554
5555 wpa_scan_results_free(res);
5556}
5557
5558
de4ed4a8
JM
5559static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
5560{
5561 switch (alg) {
5562 case WPA_ALG_WEP:
5563 if (key_len == 5)
5564 return WLAN_CIPHER_SUITE_WEP40;
5565 return WLAN_CIPHER_SUITE_WEP104;
5566 case WPA_ALG_TKIP:
5567 return WLAN_CIPHER_SUITE_TKIP;
5568 case WPA_ALG_CCMP:
5569 return WLAN_CIPHER_SUITE_CCMP;
5570 case WPA_ALG_GCMP:
5571 return WLAN_CIPHER_SUITE_GCMP;
5572 case WPA_ALG_CCMP_256:
5573 return WLAN_CIPHER_SUITE_CCMP_256;
5574 case WPA_ALG_GCMP_256:
5575 return WLAN_CIPHER_SUITE_GCMP_256;
5576 case WPA_ALG_IGTK:
5577 return WLAN_CIPHER_SUITE_AES_CMAC;
5578 case WPA_ALG_BIP_GMAC_128:
5579 return WLAN_CIPHER_SUITE_BIP_GMAC_128;
5580 case WPA_ALG_BIP_GMAC_256:
5581 return WLAN_CIPHER_SUITE_BIP_GMAC_256;
5582 case WPA_ALG_BIP_CMAC_256:
5583 return WLAN_CIPHER_SUITE_BIP_CMAC_256;
5584 case WPA_ALG_SMS4:
5585 return WLAN_CIPHER_SUITE_SMS4;
5586 case WPA_ALG_KRK:
5587 return WLAN_CIPHER_SUITE_KRK;
5588 case WPA_ALG_NONE:
5589 case WPA_ALG_PMK:
5590 wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
5591 alg);
5592 return 0;
5593 }
5594
5595 wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
5596 alg);
5597 return 0;
5598}
5599
5600
5601static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
5602{
5603 switch (cipher) {
5604 case WPA_CIPHER_CCMP_256:
5605 return WLAN_CIPHER_SUITE_CCMP_256;
5606 case WPA_CIPHER_GCMP_256:
5607 return WLAN_CIPHER_SUITE_GCMP_256;
5608 case WPA_CIPHER_CCMP:
5609 return WLAN_CIPHER_SUITE_CCMP;
5610 case WPA_CIPHER_GCMP:
5611 return WLAN_CIPHER_SUITE_GCMP;
5612 case WPA_CIPHER_TKIP:
5613 return WLAN_CIPHER_SUITE_TKIP;
5614 case WPA_CIPHER_WEP104:
5615 return WLAN_CIPHER_SUITE_WEP104;
5616 case WPA_CIPHER_WEP40:
5617 return WLAN_CIPHER_SUITE_WEP40;
ae6f9272
JM
5618 case WPA_CIPHER_GTK_NOT_USED:
5619 return WLAN_CIPHER_SUITE_NO_GROUP_ADDR;
de4ed4a8
JM
5620 }
5621
5622 return 0;
5623}
5624
5625
5626static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
5627 int max_suites)
5628{
5629 int num_suites = 0;
5630
5631 if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
5632 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP_256;
5633 if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
5634 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP_256;
5635 if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
5636 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
5637 if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
5638 suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
5639 if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
5640 suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
5641 if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
5642 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
5643 if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
5644 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
5645
5646 return num_suites;
5647}
5648
5649
9ebce9c5 5650static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
71934751
JM
5651 enum wpa_alg alg, const u8 *addr,
5652 int key_idx, int set_tx,
642187d6
JM
5653 const u8 *seq, size_t seq_len,
5654 const u8 *key, size_t key_len)
3f5285e8 5655{
a2e40bb6 5656 struct wpa_driver_nl80211_data *drv = bss->drv;
e472e1b4 5657 int ifindex;
3f5285e8 5658 struct nl_msg *msg;
1ad1cdc2 5659 int ret;
dc01de8a 5660 int tdls = 0;
3f5285e8 5661
e472e1b4
AS
5662 /* Ignore for P2P Device */
5663 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
5664 return 0;
5665
5666 ifindex = if_nametoindex(ifname);
8393e1a0 5667 wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
1ad1cdc2 5668 "set_tx=%d seq_len=%lu key_len=%lu",
8393e1a0 5669 __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
3f5285e8 5670 (unsigned long) seq_len, (unsigned long) key_len);
8c66e185 5671#ifdef CONFIG_TDLS
dc01de8a 5672 if (key_idx == -1) {
8c66e185 5673 key_idx = 0;
dc01de8a
JM
5674 tdls = 1;
5675 }
8c66e185 5676#endif /* CONFIG_TDLS */
3f5285e8
JM
5677
5678 msg = nlmsg_alloc();
1ad1cdc2
JM
5679 if (!msg)
5680 return -ENOMEM;
3f5285e8
JM
5681
5682 if (alg == WPA_ALG_NONE) {
9fb04070 5683 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_KEY);
3f5285e8 5684 } else {
9fb04070 5685 nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_KEY);
3f5285e8 5686 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
e6ef73f1 5687 wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
de4ed4a8
JM
5688 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
5689 wpa_alg_to_cipher_suite(alg, key_len));
3f5285e8
JM
5690 }
5691
e6ef73f1 5692 if (seq && seq_len) {
1ad1cdc2 5693 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
e6ef73f1
JM
5694 wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
5695 }
1ad1cdc2 5696
0382097e 5697 if (addr && !is_broadcast_ether_addr(addr)) {
3f5285e8
JM
5698 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
5699 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
89c38e32
JM
5700
5701 if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
5702 wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK");
5703 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE,
5704 NL80211_KEYTYPE_GROUP);
5705 }
60ea8187 5706 } else if (addr && is_broadcast_ether_addr(addr)) {
8970bae8
JB
5707 struct nlattr *types;
5708
60ea8187 5709 wpa_printf(MSG_DEBUG, " broadcast key");
8970bae8
JB
5710
5711 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
60ea8187
JM
5712 if (!types)
5713 goto nla_put_failure;
8970bae8
JB
5714 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
5715 nla_nest_end(msg, types);
3f5285e8
JM
5716 }
5717 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1ad1cdc2 5718 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
3f5285e8 5719
1ad1cdc2 5720 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
15664ad0 5721 if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
1ad1cdc2
JM
5722 ret = 0;
5723 if (ret)
5724 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
5725 ret, strerror(-ret));
3f5285e8 5726
1ad1cdc2
JM
5727 /*
5728 * If we failed or don't need to set the default TX key (below),
5729 * we're done here.
5730 */
dc01de8a 5731 if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
1ad1cdc2 5732 return ret;
b1f625e0 5733 if (is_ap_interface(drv->nlmode) && addr &&
0382097e 5734 !is_broadcast_ether_addr(addr))
de12717a 5735 return ret;
3f5285e8 5736
1ad1cdc2
JM
5737 msg = nlmsg_alloc();
5738 if (!msg)
5739 return -ENOMEM;
3f5285e8 5740
9fb04070 5741 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_KEY);
1ad1cdc2
JM
5742 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
5743 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5744 if (alg == WPA_ALG_IGTK)
5745 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
5746 else
5747 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
60ea8187 5748 if (addr && is_broadcast_ether_addr(addr)) {
8970bae8
JB
5749 struct nlattr *types;
5750
5751 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
60ea8187
JM
5752 if (!types)
5753 goto nla_put_failure;
8970bae8
JB
5754 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
5755 nla_nest_end(msg, types);
60ea8187 5756 } else if (addr) {
8970bae8
JB
5757 struct nlattr *types;
5758
5759 types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
60ea8187
JM
5760 if (!types)
5761 goto nla_put_failure;
8970bae8
JB
5762 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST);
5763 nla_nest_end(msg, types);
60ea8187 5764 }
3f5285e8 5765
1ad1cdc2
JM
5766 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5767 if (ret == -ENOENT)
5768 ret = 0;
5769 if (ret)
5770 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
5771 "err=%d %s)", ret, strerror(-ret));
5772 return ret;
3f5285e8
JM
5773
5774nla_put_failure:
5883168a 5775 nlmsg_free(msg);
6241fcb1 5776 return -ENOBUFS;
3f5285e8
JM
5777}
5778
5779
71934751 5780static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
0194fedb
JB
5781 int key_idx, int defkey,
5782 const u8 *seq, size_t seq_len,
5783 const u8 *key, size_t key_len)
5784{
5785 struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
5786 if (!key_attr)
5787 return -1;
5788
5789 if (defkey && alg == WPA_ALG_IGTK)
5790 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
5791 else if (defkey)
5792 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
5793
5794 NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
5795
de4ed4a8
JM
5796 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5797 wpa_alg_to_cipher_suite(alg, key_len));
0194fedb
JB
5798
5799 if (seq && seq_len)
5800 NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
5801
5802 NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
5803
5804 nla_nest_end(msg, key_attr);
5805
5806 return 0;
5807 nla_put_failure:
5808 return -1;
5809}
5810
c811d5bc 5811
cfaab580
ZY
5812static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
5813 struct nl_msg *msg)
5814{
5815 int i, privacy = 0;
5816 struct nlattr *nl_keys, *nl_key;
5817
5818 for (i = 0; i < 4; i++) {
5819 if (!params->wep_key[i])
5820 continue;
5821 privacy = 1;
5822 break;
5823 }
ce04af5a
JM
5824 if (params->wps == WPS_MODE_PRIVACY)
5825 privacy = 1;
5826 if (params->pairwise_suite &&
5827 params->pairwise_suite != WPA_CIPHER_NONE)
5828 privacy = 1;
5829
cfaab580
ZY
5830 if (!privacy)
5831 return 0;
5832
5833 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
5834
5835 nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
5836 if (!nl_keys)
5837 goto nla_put_failure;
5838
5839 for (i = 0; i < 4; i++) {
5840 if (!params->wep_key[i])
5841 continue;
5842
5843 nl_key = nla_nest_start(msg, i);
5844 if (!nl_key)
5845 goto nla_put_failure;
5846
5847 NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
5848 params->wep_key[i]);
5849 if (params->wep_key_len[i] == 5)
5850 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5851 WLAN_CIPHER_SUITE_WEP40);
5852 else
5853 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5854 WLAN_CIPHER_SUITE_WEP104);
5855
5856 NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
5857
5858 if (i == params->wep_tx_keyidx)
5859 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
5860
5861 nla_nest_end(msg, nl_key);
5862 }
5863 nla_nest_end(msg, nl_keys);
5864
5865 return 0;
5866
5867nla_put_failure:
5868 return -ENOBUFS;
5869}
5870
5871
c2a04078 5872static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
77339912
JM
5873 const u8 *addr, int cmd, u16 reason_code,
5874 int local_state_change)
c2a04078
JM
5875{
5876 int ret = -1;
5877 struct nl_msg *msg;
5878
5879 msg = nlmsg_alloc();
5880 if (!msg)
5881 return -1;
5882
9fb04070 5883 nl80211_cmd(drv, msg, 0, cmd);
c2a04078
JM
5884
5885 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5886 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
817762d9
MI
5887 if (addr)
5888 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
77339912
JM
5889 if (local_state_change)
5890 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
c2a04078
JM
5891
5892 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5893 msg = NULL;
5894 if (ret) {
3b7ea880
BG
5895 wpa_dbg(drv->ctx, MSG_DEBUG,
5896 "nl80211: MLME command failed: reason=%u ret=%d (%s)",
5897 reason_code, ret, strerror(-ret));
c2a04078
JM
5898 goto nla_put_failure;
5899 }
5900 ret = 0;
5901
5902nla_put_failure:
5903 nlmsg_free(msg);
5904 return ret;
5905}
3f5285e8
JM
5906
5907
cfaab580 5908static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
817762d9 5909 int reason_code)
cfaab580 5910{
3f53c006
JJ
5911 int ret;
5912
817762d9 5913 wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
add9b7a4 5914 nl80211_mark_disconnected(drv);
817762d9 5915 /* Disconnect command doesn't need BSSID - it uses cached value */
3f53c006
JJ
5916 ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
5917 reason_code, 0);
5918 /*
5919 * For locally generated disconnect, supplicant already generates a
5920 * DEAUTH event, so ignore the event from NL80211.
5921 */
5922 drv->ignore_next_local_disconnect = ret == 0;
5923
5924 return ret;
cfaab580
ZY
5925}
5926
5927
9ebce9c5
JM
5928static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
5929 const u8 *addr, int reason_code)
3f5285e8 5930{
a2e40bb6 5931 struct wpa_driver_nl80211_data *drv = bss->drv;
d6a36f39 5932 int ret;
9392c9be
AS
5933
5934 if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
5935 nl80211_mark_disconnected(drv);
5936 return nl80211_leave_ibss(drv);
5937 }
cfaab580 5938 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
817762d9 5939 return wpa_driver_nl80211_disconnect(drv, reason_code);
2e75a2b3
JM
5940 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
5941 __func__, MAC2STR(addr), reason_code);
add9b7a4 5942 nl80211_mark_disconnected(drv);
d6a36f39
JM
5943 ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
5944 reason_code, 0);
5945 /*
5946 * For locally generated deauthenticate, supplicant already generates a
5947 * DEAUTH event, so ignore the event from NL80211.
5948 */
5949 drv->ignore_next_local_deauth = ret == 0;
5950 return ret;
3f5285e8
JM
5951}
5952
5953
536fd62d
JM
5954static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
5955 struct wpa_driver_auth_params *params)
5956{
5957 int i;
5958
5959 drv->auth_freq = params->freq;
5960 drv->auth_alg = params->auth_alg;
5961 drv->auth_wep_tx_keyidx = params->wep_tx_keyidx;
5962 drv->auth_local_state_change = params->local_state_change;
5963 drv->auth_p2p = params->p2p;
5964
5965 if (params->bssid)
5966 os_memcpy(drv->auth_bssid_, params->bssid, ETH_ALEN);
5967 else
5968 os_memset(drv->auth_bssid_, 0, ETH_ALEN);
5969
5970 if (params->ssid) {
5971 os_memcpy(drv->auth_ssid, params->ssid, params->ssid_len);
5972 drv->auth_ssid_len = params->ssid_len;
5973 } else
5974 drv->auth_ssid_len = 0;
5975
5976
5977 os_free(drv->auth_ie);
5978 drv->auth_ie = NULL;
5979 drv->auth_ie_len = 0;
5980 if (params->ie) {
5981 drv->auth_ie = os_malloc(params->ie_len);
5982 if (drv->auth_ie) {
5983 os_memcpy(drv->auth_ie, params->ie, params->ie_len);
5984 drv->auth_ie_len = params->ie_len;
5985 }
5986 }
5987
5988 for (i = 0; i < 4; i++) {
5989 if (params->wep_key[i] && params->wep_key_len[i] &&
5990 params->wep_key_len[i] <= 16) {
5991 os_memcpy(drv->auth_wep_key[i], params->wep_key[i],
5992 params->wep_key_len[i]);
5993 drv->auth_wep_key_len[i] = params->wep_key_len[i];
5994 } else
5995 drv->auth_wep_key_len[i] = 0;
5996 }
5997}
5998
5999
c2a04078 6000static int wpa_driver_nl80211_authenticate(
9ebce9c5 6001 struct i802_bss *bss, struct wpa_driver_auth_params *params)
c2a04078 6002{
a2e40bb6 6003 struct wpa_driver_nl80211_data *drv = bss->drv;
a0b2f99b 6004 int ret = -1, i;
c2a04078
JM
6005 struct nl_msg *msg;
6006 enum nl80211_auth_type type;
2f4f73b1 6007 enum nl80211_iftype nlmode;
6d6f4bb8 6008 int count = 0;
536fd62d
JM
6009 int is_retry;
6010
6011 is_retry = drv->retry_auth;
6012 drv->retry_auth = 0;
e8d70a73 6013 drv->ignore_deauth_event = 0;
c2a04078 6014
add9b7a4 6015 nl80211_mark_disconnected(drv);
e6b8efeb 6016 os_memset(drv->auth_bssid, 0, ETH_ALEN);
add9b7a4
JM
6017 if (params->bssid)
6018 os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
6019 else
6020 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
af473088 6021 /* FIX: IBSS mode */
2f4f73b1
EP
6022 nlmode = params->p2p ?
6023 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
6024 if (drv->nlmode != nlmode &&
9ebce9c5 6025 wpa_driver_nl80211_set_mode(bss, nlmode) < 0)
4a867032
JM
6026 return -1;
6027
6d6f4bb8 6028retry:
c2a04078
JM
6029 msg = nlmsg_alloc();
6030 if (!msg)
6031 return -1;
6032
6033 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
6034 drv->ifindex);
a0b2f99b 6035
9fb04070 6036 nl80211_cmd(drv, msg, 0, NL80211_CMD_AUTHENTICATE);
0194fedb 6037
a0b2f99b
JM
6038 for (i = 0; i < 4; i++) {
6039 if (!params->wep_key[i])
6040 continue;
9ebce9c5 6041 wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
2ea2fcc7 6042 NULL, i,
a0b2f99b
JM
6043 i == params->wep_tx_keyidx, NULL, 0,
6044 params->wep_key[i],
6045 params->wep_key_len[i]);
0194fedb
JB
6046 if (params->wep_tx_keyidx != i)
6047 continue;
6048 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
6049 params->wep_key[i], params->wep_key_len[i])) {
6050 nlmsg_free(msg);
6051 return -1;
6052 }
a0b2f99b
JM
6053 }
6054
c2a04078
JM
6055 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
6056 if (params->bssid) {
6057 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
6058 MAC2STR(params->bssid));
6059 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
6060 }
6061 if (params->freq) {
6062 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
6063 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
6064 }
6065 if (params->ssid) {
6066 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
6067 params->ssid, params->ssid_len);
6068 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
6069 params->ssid);
6070 }
6071 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
6072 if (params->ie)
6073 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
569fed90
JM
6074 if (params->sae_data) {
6075 wpa_hexdump(MSG_DEBUG, " * SAE data", params->sae_data,
6076 params->sae_data_len);
6077 NLA_PUT(msg, NL80211_ATTR_SAE_DATA, params->sae_data_len,
6078 params->sae_data);
6079 }
abd9fafa 6080 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
c2a04078 6081 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
abd9fafa 6082 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
c2a04078 6083 type = NL80211_AUTHTYPE_SHARED_KEY;
abd9fafa 6084 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
c2a04078 6085 type = NL80211_AUTHTYPE_NETWORK_EAP;
abd9fafa 6086 else if (params->auth_alg & WPA_AUTH_ALG_FT)
c2a04078 6087 type = NL80211_AUTHTYPE_FT;
569fed90
JM
6088 else if (params->auth_alg & WPA_AUTH_ALG_SAE)
6089 type = NL80211_AUTHTYPE_SAE;
c2a04078
JM
6090 else
6091 goto nla_put_failure;
6092 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
6093 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
77339912
JM
6094 if (params->local_state_change) {
6095 wpa_printf(MSG_DEBUG, " * Local state change only");
6096 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
6097 }
c2a04078
JM
6098
6099 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6100 msg = NULL;
6101 if (ret) {
3b7ea880
BG
6102 wpa_dbg(drv->ctx, MSG_DEBUG,
6103 "nl80211: MLME command failed (auth): ret=%d (%s)",
6104 ret, strerror(-ret));
6d6f4bb8 6105 count++;
77339912
JM
6106 if (ret == -EALREADY && count == 1 && params->bssid &&
6107 !params->local_state_change) {
6d6f4bb8
JM
6108 /*
6109 * mac80211 does not currently accept new
6110 * authentication if we are already authenticated. As a
6111 * workaround, force deauthentication and try again.
6112 */
6113 wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
6114 "after forced deauthentication");
e8d70a73 6115 drv->ignore_deauth_event = 1;
6d6f4bb8 6116 wpa_driver_nl80211_deauthenticate(
5205c4f9 6117 bss, params->bssid,
6d6f4bb8
JM
6118 WLAN_REASON_PREV_AUTH_NOT_VALID);
6119 nlmsg_free(msg);
6120 goto retry;
6121 }
536fd62d
JM
6122
6123 if (ret == -ENOENT && params->freq && !is_retry) {
6124 /*
6125 * cfg80211 has likely expired the BSS entry even
6126 * though it was previously available in our internal
6127 * BSS table. To recover quickly, start a single
6128 * channel scan on the specified channel.
6129 */
6130 struct wpa_driver_scan_params scan;
6131 int freqs[2];
6132
6133 os_memset(&scan, 0, sizeof(scan));
6134 scan.num_ssids = 1;
6135 if (params->ssid) {
6136 scan.ssids[0].ssid = params->ssid;
6137 scan.ssids[0].ssid_len = params->ssid_len;
6138 }
6139 freqs[0] = params->freq;
6140 freqs[1] = 0;
6141 scan.freqs = freqs;
6142 wpa_printf(MSG_DEBUG, "nl80211: Trigger single "
6143 "channel scan to refresh cfg80211 BSS "
6144 "entry");
6145 ret = wpa_driver_nl80211_scan(bss, &scan);
6146 if (ret == 0) {
6147 nl80211_copy_auth_params(drv, params);
6148 drv->scan_for_auth = 1;
6149 }
8c3ba078
JM
6150 } else if (is_retry) {
6151 /*
6152 * Need to indicate this with an event since the return
6153 * value from the retry is not delivered to core code.
6154 */
6155 union wpa_event_data event;
6156 wpa_printf(MSG_DEBUG, "nl80211: Authentication retry "
6157 "failed");
6158 os_memset(&event, 0, sizeof(event));
6159 os_memcpy(event.timeout_event.addr, drv->auth_bssid_,
6160 ETH_ALEN);
6161 wpa_supplicant_event(drv->ctx, EVENT_AUTH_TIMED_OUT,
6162 &event);
536fd62d
JM
6163 }
6164
c2a04078
JM
6165 goto nla_put_failure;
6166 }
6167 ret = 0;
6168 wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
6169 "successfully");
6170
6171nla_put_failure:
6172 nlmsg_free(msg);
6173 return ret;
6174}
6175
6176
536fd62d
JM
6177static int wpa_driver_nl80211_authenticate_retry(
6178 struct wpa_driver_nl80211_data *drv)
6179{
6180 struct wpa_driver_auth_params params;
834ee56f 6181 struct i802_bss *bss = drv->first_bss;
536fd62d
JM
6182 int i;
6183
6184 wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
6185
6186 os_memset(&params, 0, sizeof(params));
6187 params.freq = drv->auth_freq;
6188 params.auth_alg = drv->auth_alg;
6189 params.wep_tx_keyidx = drv->auth_wep_tx_keyidx;
6190 params.local_state_change = drv->auth_local_state_change;
6191 params.p2p = drv->auth_p2p;
6192
6193 if (!is_zero_ether_addr(drv->auth_bssid_))
6194 params.bssid = drv->auth_bssid_;
6195
6196 if (drv->auth_ssid_len) {
6197 params.ssid = drv->auth_ssid;
6198 params.ssid_len = drv->auth_ssid_len;
6199 }
6200
6201 params.ie = drv->auth_ie;
6202 params.ie_len = drv->auth_ie_len;
6203
6204 for (i = 0; i < 4; i++) {
6205 if (drv->auth_wep_key_len[i]) {
6206 params.wep_key[i] = drv->auth_wep_key[i];
6207 params.wep_key_len[i] = drv->auth_wep_key_len[i];
6208 }
6209 }
6210
6211 drv->retry_auth = 1;
6212 return wpa_driver_nl80211_authenticate(bss, &params);
6213}
6214
6215
282d5590
JM
6216struct phy_info_arg {
6217 u16 *num_modes;
6218 struct hostapd_hw_modes *modes;
43245552 6219 int last_mode, last_chan_idx;
282d5590
JM
6220};
6221
e62a1d43
JM
6222static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
6223 struct nlattr *ampdu_factor,
6224 struct nlattr *ampdu_density,
6225 struct nlattr *mcs_set)
6226{
6227 if (capa)
6228 mode->ht_capab = nla_get_u16(capa);
6229
6230 if (ampdu_factor)
6231 mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
6232
6233 if (ampdu_density)
6234 mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
6235
6236 if (mcs_set && nla_len(mcs_set) >= 16) {
6237 u8 *mcs;
6238 mcs = nla_data(mcs_set);
6239 os_memcpy(mode->mcs_set, mcs, 16);
6240 }
6241}
6242
6243
6244static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
6245 struct nlattr *capa,
6246 struct nlattr *mcs_set)
6247{
6248 if (capa)
6249 mode->vht_capab = nla_get_u32(capa);
6250
6251 if (mcs_set && nla_len(mcs_set) >= 8) {
6252 u8 *mcs;
6253 mcs = nla_data(mcs_set);
6254 os_memcpy(mode->vht_mcs_set, mcs, 8);
6255 }
6256}
6257
6258
214a77b0
JM
6259static void phy_info_freq(struct hostapd_hw_modes *mode,
6260 struct hostapd_channel_data *chan,
6261 struct nlattr *tb_freq[])
6262{
e864c0ae 6263 u8 channel;
214a77b0
JM
6264 chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
6265 chan->flag = 0;
bbbacbf2 6266 chan->dfs_cac_ms = 0;
e864c0ae
JM
6267 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
6268 chan->chan = channel;
214a77b0
JM
6269
6270 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
6271 chan->flag |= HOSTAPD_CHAN_DISABLED;
9fcd300d
JM
6272 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
6273 chan->flag |= HOSTAPD_CHAN_PASSIVE_SCAN | HOSTAPD_CHAN_NO_IBSS;
214a77b0
JM
6274 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
6275 chan->flag |= HOSTAPD_CHAN_RADAR;
6276
fc96522e
SW
6277 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
6278 enum nl80211_dfs_state state =
6279 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
6280
6281 switch (state) {
6282 case NL80211_DFS_USABLE:
6283 chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
6284 break;
6285 case NL80211_DFS_AVAILABLE:
6286 chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
6287 break;
6288 case NL80211_DFS_UNAVAILABLE:
6289 chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
6290 break;
6291 }
6292 }
bbbacbf2
JD
6293
6294 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
6295 chan->dfs_cac_ms = nla_get_u32(
6296 tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
6297 }
214a77b0
JM
6298}
6299
6300
e62a1d43
JM
6301static int phy_info_freqs(struct phy_info_arg *phy_info,
6302 struct hostapd_hw_modes *mode, struct nlattr *tb)
282d5590 6303{
282d5590
JM
6304 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
6305 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
6306 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
9fcd300d 6307 [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
282d5590
JM
6308 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
6309 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
fc96522e 6310 [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
282d5590 6311 };
e62a1d43
JM
6312 int new_channels = 0;
6313 struct hostapd_channel_data *channel;
6314 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
6315 struct nlattr *nl_freq;
6316 int rem_freq, idx;
6317
6318 if (tb == NULL)
6319 return NL_OK;
6320
6321 nla_for_each_nested(nl_freq, tb, rem_freq) {
6322 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
6323 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
6324 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
6325 continue;
6326 new_channels++;
6327 }
6328
6329 channel = os_realloc_array(mode->channels,
6330 mode->num_channels + new_channels,
6331 sizeof(struct hostapd_channel_data));
6332 if (!channel)
6333 return NL_SKIP;
6334
6335 mode->channels = channel;
6336 mode->num_channels += new_channels;
6337
6338 idx = phy_info->last_chan_idx;
6339
6340 nla_for_each_nested(nl_freq, tb, rem_freq) {
6341 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
6342 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
6343 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
6344 continue;
214a77b0 6345 phy_info_freq(mode, &mode->channels[idx], tb_freq);
e62a1d43
JM
6346 idx++;
6347 }
6348 phy_info->last_chan_idx = idx;
6349
6350 return NL_OK;
6351}
6352
6353
6354static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
6355{
282d5590
JM
6356 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
6357 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
3cfcad1b
JM
6358 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
6359 { .type = NLA_FLAG },
282d5590 6360 };
e62a1d43 6361 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
282d5590 6362 struct nlattr *nl_rate;
e62a1d43
JM
6363 int rem_rate, idx;
6364
6365 if (tb == NULL)
6366 return NL_OK;
6367
6368 nla_for_each_nested(nl_rate, tb, rem_rate) {
6369 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
6370 nla_data(nl_rate), nla_len(nl_rate),
6371 rate_policy);
6372 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
6373 continue;
6374 mode->num_rates++;
6375 }
6376
6377 mode->rates = os_calloc(mode->num_rates, sizeof(int));
6378 if (!mode->rates)
6379 return NL_SKIP;
6380
6381 idx = 0;
6382
6383 nla_for_each_nested(nl_rate, tb, rem_rate) {
6384 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
6385 nla_data(nl_rate), nla_len(nl_rate),
6386 rate_policy);
6387 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
6388 continue;
6389 mode->rates[idx] = nla_get_u32(
6390 tb_rate[NL80211_BITRATE_ATTR_RATE]);
e62a1d43
JM
6391 idx++;
6392 }
6393
6394 return NL_OK;
6395}
6396
6397
6398static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
6399{
6400 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
282d5590 6401 struct hostapd_hw_modes *mode;
e62a1d43 6402 int ret;
282d5590 6403
3cfcad1b
JM
6404 if (phy_info->last_mode != nl_band->nla_type) {
6405 mode = os_realloc_array(phy_info->modes,
6406 *phy_info->num_modes + 1,
6407 sizeof(*mode));
6408 if (!mode)
6409 return NL_SKIP;
6410 phy_info->modes = mode;
6411
6412 mode = &phy_info->modes[*(phy_info->num_modes)];
6413 os_memset(mode, 0, sizeof(*mode));
6414 mode->mode = NUM_HOSTAPD_MODES;
c8ebeda4
MK
6415 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
6416 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
6417
6418 /*
6419 * Unsupported VHT MCS stream is defined as value 3, so the VHT
6420 * MCS RX/TX map must be initialized with 0xffff to mark all 8
6421 * possible streams as unsupported. This will be overridden if
6422 * driver advertises VHT support.
6423 */
6424 mode->vht_mcs_set[0] = 0xff;
6425 mode->vht_mcs_set[1] = 0xff;
6426 mode->vht_mcs_set[4] = 0xff;
6427 mode->vht_mcs_set[5] = 0xff;
6428
3cfcad1b
JM
6429 *(phy_info->num_modes) += 1;
6430 phy_info->last_mode = nl_band->nla_type;
6431 phy_info->last_chan_idx = 0;
6432 } else
6433 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
282d5590 6434
3cfcad1b
JM
6435 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
6436 nla_len(nl_band), NULL);
282d5590 6437
e62a1d43
JM
6438 phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
6439 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
6440 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
6441 tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
6442 phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
6443 tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
6444 ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
6445 if (ret != NL_OK)
6446 return ret;
6447 ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
6448 if (ret != NL_OK)
6449 return ret;
282d5590 6450
3cfcad1b
JM
6451 return NL_OK;
6452}
6453
6454
6455static int phy_info_handler(struct nl_msg *msg, void *arg)
6456{
6457 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
6458 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6459 struct phy_info_arg *phy_info = arg;
6460 struct nlattr *nl_band;
6461 int rem_band;
6462
6463 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6464 genlmsg_attrlen(gnlh, 0), NULL);
6465
6466 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
6467 return NL_SKIP;
6468
6469 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
6470 {
6471 int res = phy_info_band(phy_info, nl_band);
6472 if (res != NL_OK)
6473 return res;
6474 }
6475
282d5590
JM
6476 return NL_SKIP;
6477}
6478
3cfcad1b 6479
282d5590 6480static struct hostapd_hw_modes *
c30a4ab0
JB
6481wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
6482 u16 *num_modes)
282d5590
JM
6483{
6484 u16 m;
6485 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
6486 int i, mode11g_idx = -1;
6487
c30a4ab0
JB
6488 /* heuristic to set up modes */
6489 for (m = 0; m < *num_modes; m++) {
6490 if (!modes[m].num_channels)
6491 continue;
6492 if (modes[m].channels[0].freq < 4000) {
6493 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
6494 for (i = 0; i < modes[m].num_rates; i++) {
6495 if (modes[m].rates[i] > 200) {
6496 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
6497 break;
6498 }
6499 }
6500 } else if (modes[m].channels[0].freq > 50000)
6501 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
6502 else
6503 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
6504 }
6505
282d5590
JM
6506 /* If only 802.11g mode is included, use it to construct matching
6507 * 802.11b mode data. */
6508
6509 for (m = 0; m < *num_modes; m++) {
6510 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
6511 return modes; /* 802.11b already included */
6512 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
6513 mode11g_idx = m;
6514 }
6515
6516 if (mode11g_idx < 0)
6517 return modes; /* 2.4 GHz band not supported at all */
6518
067ffa26 6519 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
282d5590
JM
6520 if (nmodes == NULL)
6521 return modes; /* Could not add 802.11b mode */
6522
6523 mode = &nmodes[*num_modes];
6524 os_memset(mode, 0, sizeof(*mode));
6525 (*num_modes)++;
6526 modes = nmodes;
6527
6528 mode->mode = HOSTAPD_MODE_IEEE80211B;
6529
6530 mode11g = &modes[mode11g_idx];
6531 mode->num_channels = mode11g->num_channels;
6532 mode->channels = os_malloc(mode11g->num_channels *
6533 sizeof(struct hostapd_channel_data));
6534 if (mode->channels == NULL) {
6535 (*num_modes)--;
6536 return modes; /* Could not add 802.11b mode */
6537 }
6538 os_memcpy(mode->channels, mode11g->channels,
6539 mode11g->num_channels * sizeof(struct hostapd_channel_data));
6540
6541 mode->num_rates = 0;
fb7842aa 6542 mode->rates = os_malloc(4 * sizeof(int));
282d5590
JM
6543 if (mode->rates == NULL) {
6544 os_free(mode->channels);
6545 (*num_modes)--;
6546 return modes; /* Could not add 802.11b mode */
6547 }
6548
6549 for (i = 0; i < mode11g->num_rates; i++) {
fb7842aa
JM
6550 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
6551 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
282d5590
JM
6552 continue;
6553 mode->rates[mode->num_rates] = mode11g->rates[i];
6554 mode->num_rates++;
6555 if (mode->num_rates == 4)
6556 break;
6557 }
6558
6559 if (mode->num_rates == 0) {
6560 os_free(mode->channels);
6561 os_free(mode->rates);
6562 (*num_modes)--;
6563 return modes; /* No 802.11b rates */
6564 }
6565
6566 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
6567 "information");
6568
6569 return modes;
6570}
6571
6572
d8e66e80
JM
6573static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
6574 int end)
6575{
6576 int c;
6577
6578 for (c = 0; c < mode->num_channels; c++) {
6579 struct hostapd_channel_data *chan = &mode->channels[c];
6580 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
6581 chan->flag |= HOSTAPD_CHAN_HT40;
6582 }
6583}
6584
6585
6586static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
6587 int end)
6588{
6589 int c;
6590
6591 for (c = 0; c < mode->num_channels; c++) {
6592 struct hostapd_channel_data *chan = &mode->channels[c];
6593 if (!(chan->flag & HOSTAPD_CHAN_HT40))
6594 continue;
6595 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
6596 chan->flag |= HOSTAPD_CHAN_HT40MINUS;
6597 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
6598 chan->flag |= HOSTAPD_CHAN_HT40PLUS;
6599 }
6600}
6601
6602
35f3d3ed 6603static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
6651f1f9
HS
6604 struct phy_info_arg *results)
6605{
6651f1f9
HS
6606 u16 m;
6607
6651f1f9
HS
6608 for (m = 0; m < *results->num_modes; m++) {
6609 int c;
6610 struct hostapd_hw_modes *mode = &results->modes[m];
6611
6612 for (c = 0; c < mode->num_channels; c++) {
6613 struct hostapd_channel_data *chan = &mode->channels[c];
6614 if ((u32) chan->freq - 10 >= start &&
6615 (u32) chan->freq + 10 <= end)
6616 chan->max_tx_power = max_eirp;
6617 }
6618 }
6619}
6620
6621
35f3d3ed 6622static void nl80211_reg_rule_ht40(u32 start, u32 end,
d8e66e80
JM
6623 struct phy_info_arg *results)
6624{
d8e66e80
JM
6625 u16 m;
6626
d8e66e80
JM
6627 for (m = 0; m < *results->num_modes; m++) {
6628 if (!(results->modes[m].ht_capab &
6629 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6630 continue;
6631 nl80211_set_ht40_mode(&results->modes[m], start, end);
6632 }
6633}
6634
6635
6636static void nl80211_reg_rule_sec(struct nlattr *tb[],
6637 struct phy_info_arg *results)
6638{
6639 u32 start, end, max_bw;
6640 u16 m;
6641
6642 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6643 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
6644 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
6645 return;
6646
6647 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6648 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6649 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
6650
6651 if (max_bw < 20)
6652 return;
6653
6654 for (m = 0; m < *results->num_modes; m++) {
6655 if (!(results->modes[m].ht_capab &
6656 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6657 continue;
6658 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
6659 }
6660}
6661
6662
53cfad46
EP
6663static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
6664 int end)
6665{
6666 int c;
6667
6668 for (c = 0; c < mode->num_channels; c++) {
6669 struct hostapd_channel_data *chan = &mode->channels[c];
6670 if (chan->freq - 10 >= start && chan->freq + 70 <= end)
6671 chan->flag |= HOSTAPD_CHAN_VHT_10_70;
6672
6673 if (chan->freq - 30 >= start && chan->freq + 50 <= end)
6674 chan->flag |= HOSTAPD_CHAN_VHT_30_50;
6675
6676 if (chan->freq - 50 >= start && chan->freq + 30 <= end)
6677 chan->flag |= HOSTAPD_CHAN_VHT_50_30;
6678
6679 if (chan->freq - 70 >= start && chan->freq + 10 <= end)
6680 chan->flag |= HOSTAPD_CHAN_VHT_70_10;
6681 }
6682}
6683
6684
6685static void nl80211_reg_rule_vht(struct nlattr *tb[],
6686 struct phy_info_arg *results)
6687{
6688 u32 start, end, max_bw;
6689 u16 m;
6690
6691 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6692 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
6693 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
6694 return;
6695
6696 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6697 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6698 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
6699
6700 if (max_bw < 80)
6701 return;
6702
6703 for (m = 0; m < *results->num_modes; m++) {
6704 if (!(results->modes[m].ht_capab &
6705 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6706 continue;
6707 /* TODO: use a real VHT support indication */
6708 if (!results->modes[m].vht_capab)
6709 continue;
6710
6711 nl80211_set_vht_mode(&results->modes[m], start, end);
6712 }
6713}
6714
6715
1412beee
JD
6716static const char * dfs_domain_name(enum nl80211_dfs_regions region)
6717{
6718 switch (region) {
6719 case NL80211_DFS_UNSET:
6720 return "DFS-UNSET";
6721 case NL80211_DFS_FCC:
6722 return "DFS-FCC";
6723 case NL80211_DFS_ETSI:
6724 return "DFS-ETSI";
6725 case NL80211_DFS_JP:
6726 return "DFS-JP";
6727 default:
6728 return "DFS-invalid";
6729 }
6730}
6731
6732
d8e66e80
JM
6733static int nl80211_get_reg(struct nl_msg *msg, void *arg)
6734{
6735 struct phy_info_arg *results = arg;
6736 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
6737 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6738 struct nlattr *nl_rule;
6739 struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
6740 int rem_rule;
6741 static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
6742 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6743 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6744 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6745 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6746 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6747 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6748 };
6749
6750 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6751 genlmsg_attrlen(gnlh, 0), NULL);
6752 if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
6753 !tb_msg[NL80211_ATTR_REG_RULES]) {
6754 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
6755 "available");
6756 return NL_SKIP;
6757 }
6758
1412beee
JD
6759 if (tb_msg[NL80211_ATTR_DFS_REGION]) {
6760 enum nl80211_dfs_regions dfs_domain;
6761 dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
6762 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
6763 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
6764 dfs_domain_name(dfs_domain));
6765 } else {
6766 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
6767 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
6768 }
d8e66e80
JM
6769
6770 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6771 {
bfb79dde 6772 u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
d8e66e80
JM
6773 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6774 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
35f3d3ed
JM
6775 if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6776 tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
6777 continue;
6778 start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6779 end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6780 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6781 max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
6782 if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6783 max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
bfb79dde
JM
6784 if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
6785 flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
6786
6787 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
6788 start, end, max_bw, max_eirp,
6789 flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
6790 flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
6791 flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
6792 flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
6793 "",
6794 flags & NL80211_RRF_DFS ? " (DFS)" : "",
6795 flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
6796 flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
6797 flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
35f3d3ed
JM
6798 if (max_bw >= 40)
6799 nl80211_reg_rule_ht40(start, end, results);
6800 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6801 nl80211_reg_rule_max_eirp(start, end, max_eirp,
6802 results);
d8e66e80
JM
6803 }
6804
6805 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6806 {
6807 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6808 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
6809 nl80211_reg_rule_sec(tb_rule, results);
6810 }
6811
53cfad46
EP
6812 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6813 {
6814 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6815 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
6816 nl80211_reg_rule_vht(tb_rule, results);
6817 }
6818
d8e66e80
JM
6819 return NL_SKIP;
6820}
6821
6822
53cfad46
EP
6823static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
6824 struct phy_info_arg *results)
d8e66e80
JM
6825{
6826 struct nl_msg *msg;
6827
6828 msg = nlmsg_alloc();
6829 if (!msg)
6830 return -ENOMEM;
6831
9fb04070 6832 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
d8e66e80
JM
6833 return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
6834}
6835
6836
282d5590
JM
6837static struct hostapd_hw_modes *
6838wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
6839{
43245552 6840 u32 feat;
a2e40bb6
FF
6841 struct i802_bss *bss = priv;
6842 struct wpa_driver_nl80211_data *drv = bss->drv;
282d5590
JM
6843 struct nl_msg *msg;
6844 struct phy_info_arg result = {
6845 .num_modes = num_modes,
6846 .modes = NULL,
43245552 6847 .last_mode = -1,
282d5590
JM
6848 };
6849
6850 *num_modes = 0;
6851 *flags = 0;
6852
6853 msg = nlmsg_alloc();
6854 if (!msg)
6855 return NULL;
6856
43245552
DJ
6857 feat = get_nl80211_protocol_features(drv);
6858 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
6859 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_WIPHY);
6860 else
6861 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
282d5590 6862
43245552 6863 NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
be24917d
IP
6864 if (nl80211_set_iface_id(msg, bss) < 0)
6865 goto nla_put_failure;
282d5590 6866
d8e66e80 6867 if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
53cfad46 6868 nl80211_set_regulatory_flags(drv, &result);
c30a4ab0
JB
6869 return wpa_driver_nl80211_postprocess_modes(result.modes,
6870 num_modes);
d8e66e80 6871 }
5883168a 6872 msg = NULL;
282d5590 6873 nla_put_failure:
5883168a 6874 nlmsg_free(msg);
282d5590
JM
6875 return NULL;
6876}
6877
6878
a11241fa
JB
6879static int wpa_driver_nl80211_send_mntr(struct wpa_driver_nl80211_data *drv,
6880 const void *data, size_t len,
6881 int encrypt, int noack)
2c2010ac
JM
6882{
6883 __u8 rtap_hdr[] = {
6884 0x00, 0x00, /* radiotap version */
6885 0x0e, 0x00, /* radiotap length */
6886 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
6887 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
6888 0x00, /* padding */
6889 0x00, 0x00, /* RX and TX flags to indicate that */
6890 0x00, 0x00, /* this is the injected frame directly */
6891 };
6892 struct iovec iov[2] = {
6893 {
6894 .iov_base = &rtap_hdr,
6895 .iov_len = sizeof(rtap_hdr),
6896 },
6897 {
6898 .iov_base = (void *) data,
6899 .iov_len = len,
6900 }
6901 };
6902 struct msghdr msg = {
6903 .msg_name = NULL,
6904 .msg_namelen = 0,
6905 .msg_iov = iov,
6906 .msg_iovlen = 2,
6907 .msg_control = NULL,
6908 .msg_controllen = 0,
6909 .msg_flags = 0,
6910 };
ebbec8b2 6911 int res;
fab25336 6912 u16 txflags = 0;
2c2010ac
JM
6913
6914 if (encrypt)
6915 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
6916
866af8b6
JM
6917 if (drv->monitor_sock < 0) {
6918 wpa_printf(MSG_DEBUG, "nl80211: No monitor socket available "
6919 "for %s", __func__);
6920 return -1;
6921 }
6922
fab25336
HS
6923 if (noack)
6924 txflags |= IEEE80211_RADIOTAP_F_TX_NOACK;
9d7a63dc 6925 WPA_PUT_LE16(&rtap_hdr[12], txflags);
fab25336 6926
ebbec8b2
JM
6927 res = sendmsg(drv->monitor_sock, &msg, 0);
6928 if (res < 0) {
6929 wpa_printf(MSG_INFO, "nl80211: sendmsg: %s", strerror(errno));
6930 return -1;
6931 }
6932 return 0;
2c2010ac
JM
6933}
6934
6935
a11241fa
JB
6936static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
6937 const void *data, size_t len,
55231068
JM
6938 int encrypt, int noack,
6939 unsigned int freq, int no_cck,
6940 int offchanok, unsigned int wait_time)
a11241fa
JB
6941{
6942 struct wpa_driver_nl80211_data *drv = bss->drv;
6943 u64 cookie;
41cc50d1 6944 int res;
a11241fa 6945
af964484
JM
6946 if (freq == 0) {
6947 wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
6948 bss->freq);
55231068 6949 freq = bss->freq;
af964484 6950 }
55231068 6951
739faee2
JM
6952 if (drv->use_monitor) {
6953 wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_mntr",
6954 freq, bss->freq);
a11241fa
JB
6955 return wpa_driver_nl80211_send_mntr(drv, data, len,
6956 encrypt, noack);
739faee2 6957 }
a11241fa 6958
739faee2 6959 wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
41cc50d1
JM
6960 res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
6961 &cookie, no_cck, noack, offchanok);
6962 if (res == 0 && !noack) {
6963 const struct ieee80211_mgmt *mgmt;
6964 u16 fc;
6965
6966 mgmt = (const struct ieee80211_mgmt *) data;
6967 fc = le_to_host16(mgmt->frame_control);
6968 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
6969 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
6970 wpa_printf(MSG_MSGDUMP,
6971 "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
6972 (long long unsigned int)
6973 drv->send_action_cookie,
6974 (long long unsigned int) cookie);
6975 drv->send_action_cookie = cookie;
6976 }
6977 }
6978
6979 return res;
a11241fa
JB
6980}
6981
6982
9ebce9c5
JM
6983static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
6984 size_t data_len, int noack,
6985 unsigned int freq, int no_cck,
6986 int offchanok,
6987 unsigned int wait_time)
2c2010ac 6988{
a2e40bb6 6989 struct wpa_driver_nl80211_data *drv = bss->drv;
2c2010ac 6990 struct ieee80211_mgmt *mgmt;
7a47d567 6991 int encrypt = 1;
2c2010ac
JM
6992 u16 fc;
6993
6994 mgmt = (struct ieee80211_mgmt *) data;
6995 fc = le_to_host16(mgmt->frame_control);
af964484
JM
6996 wpa_printf(MSG_DEBUG, "nl80211: send_mlme - noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x nlmode=%d",
6997 noack, freq, no_cck, offchanok, wait_time, fc, drv->nlmode);
2c2010ac 6998
8e12685c
AS
6999 if ((is_sta_interface(drv->nlmode) ||
7000 drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
5582a5d1
JB
7001 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
7002 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
7003 /*
7004 * The use of last_mgmt_freq is a bit of a hack,
7005 * but it works due to the single-threaded nature
7006 * of wpa_supplicant.
7007 */
af964484
JM
7008 if (freq == 0) {
7009 wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
7010 drv->last_mgmt_freq);
55231068 7011 freq = drv->last_mgmt_freq;
af964484 7012 }
55231068 7013 return nl80211_send_frame_cmd(bss, freq, 0,
88df0ef7
JB
7014 data, data_len, NULL, 1, noack,
7015 1);
5582a5d1
JB
7016 }
7017
61cbe2ff 7018 if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
af964484
JM
7019 if (freq == 0) {
7020 wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
7021 bss->freq);
55231068 7022 freq = bss->freq;
af964484 7023 }
b5671498
JM
7024 return nl80211_send_frame_cmd(bss, freq,
7025 (int) freq == bss->freq ? 0 :
7026 wait_time,
d8d6b32e
DG
7027 data, data_len,
7028 &drv->send_action_cookie,
55231068 7029 no_cck, noack, offchanok);
86957e62
JM
7030 }
7031
2c2010ac
JM
7032 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
7033 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
7034 /*
7035 * Only one of the authentication frame types is encrypted.
7036 * In order for static WEP encryption to work properly (i.e.,
7037 * to not encrypt the frame), we need to tell mac80211 about
7038 * the frames that must not be encrypted.
7039 */
7040 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
7041 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
7a47d567
JB
7042 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
7043 encrypt = 0;
2c2010ac
JM
7044 }
7045
739faee2 7046 wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
a11241fa 7047 return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
55231068
JM
7048 noack, freq, no_cck, offchanok,
7049 wait_time);
7050}
7051
7052
31357268 7053static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
e5693c47
JM
7054 int slot, int ht_opmode, int ap_isolate,
7055 int *basic_rates)
31357268
JM
7056{
7057 struct wpa_driver_nl80211_data *drv = bss->drv;
7058 struct nl_msg *msg;
7059
7060 msg = nlmsg_alloc();
7061 if (!msg)
7062 return -ENOMEM;
7063
9fb04070 7064 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_BSS);
31357268
JM
7065
7066 if (cts >= 0)
7067 NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
7068 if (preamble >= 0)
7069 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
7070 if (slot >= 0)
7071 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
7072 if (ht_opmode >= 0)
7073 NLA_PUT_U16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode);
d03e8d11
JM
7074 if (ap_isolate >= 0)
7075 NLA_PUT_U8(msg, NL80211_ATTR_AP_ISOLATE, ap_isolate);
e5693c47
JM
7076
7077 if (basic_rates) {
7078 u8 rates[NL80211_MAX_SUPP_RATES];
7079 u8 rates_len = 0;
7080 int i;
7081
7082 for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0;
7083 i++)
7084 rates[rates_len++] = basic_rates[i] / 5;
7085
7086 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
7087 }
7088
31357268
JM
7089 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
7090
7091 return send_and_recv_msgs(drv, msg, NULL, NULL);
7092 nla_put_failure:
5883168a 7093 nlmsg_free(msg);
31357268
JM
7094 return -ENOBUFS;
7095}
7096
7097
3c4ca363
VN
7098static int wpa_driver_nl80211_set_acl(void *priv,
7099 struct hostapd_acl_params *params)
7100{
7101 struct i802_bss *bss = priv;
7102 struct wpa_driver_nl80211_data *drv = bss->drv;
7103 struct nl_msg *msg;
7104 struct nlattr *acl;
7105 unsigned int i;
7106 int ret = 0;
7107
7108 if (!(drv->capa.max_acl_mac_addrs))
7109 return -ENOTSUP;
7110
7111 if (params->num_mac_acl > drv->capa.max_acl_mac_addrs)
7112 return -ENOTSUP;
7113
7114 msg = nlmsg_alloc();
7115 if (!msg)
7116 return -ENOMEM;
7117
7118 wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
7119 params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
7120
7121 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_MAC_ACL);
7122
7123 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7124
7125 NLA_PUT_U32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
7126 NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
7127 NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED);
7128
7129 acl = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
7130 if (acl == NULL)
7131 goto nla_put_failure;
7132
7133 for (i = 0; i < params->num_mac_acl; i++)
7134 NLA_PUT(msg, i + 1, ETH_ALEN, params->mac_acl[i].addr);
7135
7136 nla_nest_end(msg, acl);
7137
7138 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7139 msg = NULL;
7140 if (ret) {
7141 wpa_printf(MSG_DEBUG, "nl80211: Failed to set MAC ACL: %d (%s)",
7142 ret, strerror(-ret));
7143 }
7144
7145nla_put_failure:
7146 nlmsg_free(msg);
7147
7148 return ret;
7149}
7150
7151
19c3b566
JM
7152static int wpa_driver_nl80211_set_ap(void *priv,
7153 struct wpa_driver_ap_params *params)
d2440ba0 7154{
a2e40bb6
FF
7155 struct i802_bss *bss = priv;
7156 struct wpa_driver_nl80211_data *drv = bss->drv;
d2440ba0
JM
7157 struct nl_msg *msg;
7158 u8 cmd = NL80211_CMD_NEW_BEACON;
7159 int ret;
b4fd6fab 7160 int beacon_set;
8b897f5a 7161 int ifindex = if_nametoindex(bss->ifname);
b11d1d64 7162 int num_suites;
de4ed4a8 7163 u32 suites[10], suite;
b11d1d64 7164 u32 ver;
b4fd6fab 7165
b4fd6fab 7166 beacon_set = bss->beacon_set;
d2440ba0
JM
7167
7168 msg = nlmsg_alloc();
7169 if (!msg)
7170 return -ENOMEM;
7171
7172 wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
b4fd6fab
JM
7173 beacon_set);
7174 if (beacon_set)
d2440ba0
JM
7175 cmd = NL80211_CMD_SET_BEACON;
7176
9fb04070 7177 nl80211_cmd(drv, msg, 0, cmd);
b92e08fc
JM
7178 wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
7179 params->head, params->head_len);
19c3b566 7180 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, params->head_len, params->head);
b92e08fc
JM
7181 wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
7182 params->tail, params->tail_len);
19c3b566 7183 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len, params->tail);
b92e08fc 7184 wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", ifindex);
b4fd6fab 7185 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
b92e08fc 7186 wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
19c3b566 7187 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
b92e08fc 7188 wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
19c3b566 7189 NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
b92e08fc
JM
7190 wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
7191 params->ssid, params->ssid_len);
ccb941e6
JM
7192 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
7193 params->ssid);
b92e08fc
JM
7194 if (params->proberesp && params->proberesp_len) {
7195 wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
7196 params->proberesp, params->proberesp_len);
5ed33546
AN
7197 NLA_PUT(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
7198 params->proberesp);
b92e08fc 7199 }
97a7a0b5
JM
7200 switch (params->hide_ssid) {
7201 case NO_SSID_HIDING:
b92e08fc 7202 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
97a7a0b5
JM
7203 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7204 NL80211_HIDDEN_SSID_NOT_IN_USE);
7205 break;
7206 case HIDDEN_SSID_ZERO_LEN:
b92e08fc 7207 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
97a7a0b5
JM
7208 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7209 NL80211_HIDDEN_SSID_ZERO_LEN);
7210 break;
7211 case HIDDEN_SSID_ZERO_CONTENTS:
b92e08fc 7212 wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
97a7a0b5
JM
7213 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7214 NL80211_HIDDEN_SSID_ZERO_CONTENTS);
7215 break;
7216 }
b92e08fc 7217 wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
b11d1d64
JM
7218 if (params->privacy)
7219 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
b92e08fc 7220 wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
b11d1d64
JM
7221 if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
7222 (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
7223 /* Leave out the attribute */
7224 } else if (params->auth_algs & WPA_AUTH_ALG_SHARED)
7225 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
7226 NL80211_AUTHTYPE_SHARED_KEY);
7227 else
7228 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
7229 NL80211_AUTHTYPE_OPEN_SYSTEM);
7230
b92e08fc 7231 wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
b11d1d64
JM
7232 ver = 0;
7233 if (params->wpa_version & WPA_PROTO_WPA)
7234 ver |= NL80211_WPA_VERSION_1;
7235 if (params->wpa_version & WPA_PROTO_RSN)
7236 ver |= NL80211_WPA_VERSION_2;
7237 if (ver)
7238 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
7239
b92e08fc
JM
7240 wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
7241 params->key_mgmt_suites);
b11d1d64
JM
7242 num_suites = 0;
7243 if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
7244 suites[num_suites++] = WLAN_AKM_SUITE_8021X;
7245 if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
7246 suites[num_suites++] = WLAN_AKM_SUITE_PSK;
7247 if (num_suites) {
7248 NLA_PUT(msg, NL80211_ATTR_AKM_SUITES,
7249 num_suites * sizeof(u32), suites);
7250 }
7251
9f12614b
JB
7252 if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X &&
7253 params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40))
7254 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT);
7255
b92e08fc
JM
7256 wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
7257 params->pairwise_ciphers);
de4ed4a8
JM
7258 num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
7259 suites, ARRAY_SIZE(suites));
b11d1d64
JM
7260 if (num_suites) {
7261 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
7262 num_suites * sizeof(u32), suites);
7263 }
7264
b92e08fc
JM
7265 wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
7266 params->group_cipher);
de4ed4a8
JM
7267 suite = wpa_cipher_to_cipher_suite(params->group_cipher);
7268 if (suite)
7269 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite);
d2440ba0 7270
fb91db56 7271 if (params->beacon_ies) {
b92e08fc
JM
7272 wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
7273 params->beacon_ies);
fb91db56
JM
7274 NLA_PUT(msg, NL80211_ATTR_IE, wpabuf_len(params->beacon_ies),
7275 wpabuf_head(params->beacon_ies));
7276 }
7277 if (params->proberesp_ies) {
b92e08fc
JM
7278 wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
7279 params->proberesp_ies);
fb91db56
JM
7280 NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
7281 wpabuf_len(params->proberesp_ies),
7282 wpabuf_head(params->proberesp_ies));
7283 }
7284 if (params->assocresp_ies) {
b92e08fc
JM
7285 wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
7286 params->assocresp_ies);
fb91db56
JM
7287 NLA_PUT(msg, NL80211_ATTR_IE_ASSOC_RESP,
7288 wpabuf_len(params->assocresp_ies),
7289 wpabuf_head(params->assocresp_ies));
7290 }
7291
a0133ee1 7292 if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER) {
b92e08fc
JM
7293 wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
7294 params->ap_max_inactivity);
a0133ee1
VT
7295 NLA_PUT_U16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
7296 params->ap_max_inactivity);
7297 }
7298
d2440ba0
JM
7299 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7300 if (ret) {
7301 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
7302 ret, strerror(-ret));
b4fd6fab 7303 } else {
b4fd6fab 7304 bss->beacon_set = 1;
31357268 7305 nl80211_set_bss(bss, params->cts_protect, params->preamble,
d03e8d11 7306 params->short_slot_time, params->ht_opmode,
e5693c47 7307 params->isolate, params->basic_rates);
e87ef751
PX
7308 if (beacon_set && params->freq &&
7309 params->freq->bandwidth != bss->bandwidth) {
7310 wpa_printf(MSG_DEBUG,
7311 "nl80211: Update BSS %s bandwidth: %d -> %d",
7312 bss->ifname, bss->bandwidth,
7313 params->freq->bandwidth);
7314 ret = nl80211_set_channel(bss, params->freq, 1);
7315 if (ret) {
7316 wpa_printf(MSG_DEBUG,
7317 "nl80211: Frequency set failed: %d (%s)",
7318 ret, strerror(-ret));
7319 } else {
7320 wpa_printf(MSG_DEBUG,
7321 "nl80211: Frequency set succeeded for ht2040 coex");
7322 bss->bandwidth = params->freq->bandwidth;
7323 }
7324 } else if (!beacon_set) {
7325 /*
7326 * cfg80211 updates the driver on frequence change in AP
7327 * mode only at the point when beaconing is started, so
7328 * set the initial value here.
7329 */
7330 bss->bandwidth = params->freq->bandwidth;
7331 }
b4fd6fab 7332 }
d2440ba0
JM
7333 return ret;
7334 nla_put_failure:
5883168a 7335 nlmsg_free(msg);
d2440ba0
JM
7336 return -ENOBUFS;
7337}
7338
7339
1c4ffa87
AO
7340static int nl80211_put_freq_params(struct nl_msg *msg,
7341 struct hostapd_freq_params *freq)
1581b38b 7342{
89b800d7
JB
7343 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq);
7344 if (freq->vht_enabled) {
7345 switch (freq->bandwidth) {
7346 case 20:
7347 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7348 NL80211_CHAN_WIDTH_20);
7349 break;
7350 case 40:
7351 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7352 NL80211_CHAN_WIDTH_40);
7353 break;
7354 case 80:
7355 if (freq->center_freq2)
7356 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7357 NL80211_CHAN_WIDTH_80P80);
7358 else
7359 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7360 NL80211_CHAN_WIDTH_80);
7361 break;
7362 case 160:
7363 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7364 NL80211_CHAN_WIDTH_160);
7365 break;
7366 default:
1c4ffa87 7367 return -EINVAL;
89b800d7
JB
7368 }
7369 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1);
7370 if (freq->center_freq2)
7371 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2,
7372 freq->center_freq2);
7373 } else if (freq->ht_enabled) {
7374 switch (freq->sec_channel_offset) {
f019981a
JM
7375 case -1:
7376 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7377 NL80211_CHAN_HT40MINUS);
7378 break;
7379 case 1:
7380 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7381 NL80211_CHAN_HT40PLUS);
7382 break;
7383 default:
7384 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7385 NL80211_CHAN_HT20);
7386 break;
7387 }
7388 }
1c4ffa87
AO
7389 return 0;
7390
7391nla_put_failure:
7392 return -ENOBUFS;
7393}
7394
7395
e87ef751
PX
7396static int nl80211_set_channel(struct i802_bss *bss,
7397 struct hostapd_freq_params *freq, int set_chan)
1c4ffa87
AO
7398{
7399 struct wpa_driver_nl80211_data *drv = bss->drv;
7400 struct nl_msg *msg;
7401 int ret;
7402
7403 wpa_printf(MSG_DEBUG,
7404 "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
7405 freq->freq, freq->ht_enabled, freq->vht_enabled,
7406 freq->bandwidth, freq->center_freq1, freq->center_freq2);
7407 msg = nlmsg_alloc();
7408 if (!msg)
7409 return -1;
7410
e87ef751
PX
7411 nl80211_cmd(drv, msg, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
7412 NL80211_CMD_SET_WIPHY);
1c4ffa87
AO
7413
7414 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7415 if (nl80211_put_freq_params(msg, freq) < 0)
7416 goto nla_put_failure;
1581b38b 7417
d2440ba0 7418 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 7419 msg = NULL;
e4fb2167 7420 if (ret == 0) {
89b800d7 7421 bss->freq = freq->freq;
1581b38b 7422 return 0;
e4fb2167 7423 }
f019981a 7424 wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
89b800d7 7425 "%d (%s)", freq->freq, ret, strerror(-ret));
1581b38b 7426nla_put_failure:
5883168a 7427 nlmsg_free(msg);
1581b38b
JM
7428 return -1;
7429}
7430
0f4e8b4f 7431
95ab6063
AN
7432static u32 sta_flags_nl80211(int flags)
7433{
7434 u32 f = 0;
7435
7436 if (flags & WPA_STA_AUTHORIZED)
7437 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
7438 if (flags & WPA_STA_WMM)
7439 f |= BIT(NL80211_STA_FLAG_WME);
7440 if (flags & WPA_STA_SHORT_PREAMBLE)
7441 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
7442 if (flags & WPA_STA_MFP)
7443 f |= BIT(NL80211_STA_FLAG_MFP);
45b722f1
AN
7444 if (flags & WPA_STA_TDLS_PEER)
7445 f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
95ab6063
AN
7446
7447 return f;
7448}
7449
7450
62847751 7451static int wpa_driver_nl80211_sta_add(void *priv,
0f4e8b4f
JM
7452 struct hostapd_sta_add_params *params)
7453{
a2e40bb6
FF
7454 struct i802_bss *bss = priv;
7455 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8 7456 struct nl_msg *msg;
95ab6063 7457 struct nl80211_sta_flag_update upd;
0f4e8b4f
JM
7458 int ret = -ENOBUFS;
7459
45b722f1
AN
7460 if ((params->flags & WPA_STA_TDLS_PEER) &&
7461 !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
7462 return -EOPNOTSUPP;
7463
0f4e8b4f
JM
7464 msg = nlmsg_alloc();
7465 if (!msg)
7466 return -ENOMEM;
7467
e4dea253
JM
7468 wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
7469 params->set ? "Set" : "Add", MAC2STR(params->addr));
45b722f1
AN
7470 nl80211_cmd(drv, msg, 0, params->set ? NL80211_CMD_SET_STATION :
7471 NL80211_CMD_NEW_STATION);
0f4e8b4f 7472
62847751 7473 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
0f4e8b4f 7474 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
0f4e8b4f
JM
7475 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
7476 params->supp_rates);
e4dea253
JM
7477 wpa_hexdump(MSG_DEBUG, " * supported rates", params->supp_rates,
7478 params->supp_rates_len);
45b722f1 7479 if (!params->set) {
f11b72c3
JM
7480 if (params->aid) {
7481 wpa_printf(MSG_DEBUG, " * aid=%u", params->aid);
7482 NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
7483 } else {
7484 /*
7485 * cfg80211 validates that AID is non-zero, so we have
7486 * to make this a non-zero value for the TDLS case where
7487 * a dummy STA entry is used for now.
7488 */
7489 wpa_printf(MSG_DEBUG, " * aid=1 (TDLS workaround)");
7490 NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, 1);
7491 }
e4dea253
JM
7492 wpa_printf(MSG_DEBUG, " * listen_interval=%u",
7493 params->listen_interval);
45b722f1
AN
7494 NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
7495 params->listen_interval);
e112764e
JM
7496 } else if (params->aid && (params->flags & WPA_STA_TDLS_PEER)) {
7497 wpa_printf(MSG_DEBUG, " * peer_aid=%u", params->aid);
7498 NLA_PUT_U16(msg, NL80211_ATTR_PEER_AID, params->aid);
45b722f1 7499 }
0f4e8b4f 7500 if (params->ht_capabilities) {
e4dea253
JM
7501 wpa_hexdump(MSG_DEBUG, " * ht_capabilities",
7502 (u8 *) params->ht_capabilities,
7503 sizeof(*params->ht_capabilities));
0f4e8b4f 7504 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
fc4e2d95
JM
7505 sizeof(*params->ht_capabilities),
7506 params->ht_capabilities);
0f4e8b4f 7507 }
0f4e8b4f 7508
05a8d422 7509 if (params->vht_capabilities) {
e4dea253
JM
7510 wpa_hexdump(MSG_DEBUG, " * vht_capabilities",
7511 (u8 *) params->vht_capabilities,
7512 sizeof(*params->vht_capabilities));
05a8d422
JB
7513 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY,
7514 sizeof(*params->vht_capabilities),
7515 params->vht_capabilities);
7516 }
7517
8a458116
MK
7518 if (params->vht_opmode_enabled) {
7519 wpa_printf(MSG_DEBUG, " * opmode=%u", params->vht_opmode);
7520 NLA_PUT_U8(msg, NL80211_ATTR_OPMODE_NOTIF,
7521 params->vht_opmode);
7522 }
7523
122d16f2
SD
7524 wpa_printf(MSG_DEBUG, " * capability=0x%x", params->capability);
7525 NLA_PUT_U16(msg, NL80211_ATTR_STA_CAPABILITY, params->capability);
7526
7527 if (params->ext_capab) {
7528 wpa_hexdump(MSG_DEBUG, " * ext_capab",
7529 params->ext_capab, params->ext_capab_len);
7530 NLA_PUT(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
7531 params->ext_capab_len, params->ext_capab);
7532 }
7533
efc64886
SD
7534 if (params->supp_channels) {
7535 wpa_hexdump(MSG_DEBUG, " * supported channels",
7536 params->supp_channels, params->supp_channels_len);
7537 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_CHANNELS,
7538 params->supp_channels_len, params->supp_channels);
7539 }
7540
7541 if (params->supp_oper_classes) {
7542 wpa_hexdump(MSG_DEBUG, " * supported operating classes",
7543 params->supp_oper_classes,
7544 params->supp_oper_classes_len);
7545 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
7546 params->supp_oper_classes_len,
7547 params->supp_oper_classes);
7548 }
7549
95ab6063
AN
7550 os_memset(&upd, 0, sizeof(upd));
7551 upd.mask = sta_flags_nl80211(params->flags);
7552 upd.set = upd.mask;
e4dea253
JM
7553 wpa_printf(MSG_DEBUG, " * flags set=0x%x mask=0x%x",
7554 upd.set, upd.mask);
95ab6063
AN
7555 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
7556
774bfa62 7557 if (params->flags & WPA_STA_WMM) {
8970bae8
JB
7558 struct nlattr *wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
7559
774bfa62
EP
7560 if (!wme)
7561 goto nla_put_failure;
7562
e4dea253 7563 wpa_printf(MSG_DEBUG, " * qosinfo=0x%x", params->qosinfo);
8970bae8 7564 NLA_PUT_U8(msg, NL80211_STA_WME_UAPSD_QUEUES,
5d061637 7565 params->qosinfo & WMM_QOSINFO_STA_AC_MASK);
8970bae8 7566 NLA_PUT_U8(msg, NL80211_STA_WME_MAX_SP,
bdaf1748 7567 (params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
5d061637 7568 WMM_QOSINFO_STA_SP_MASK);
8970bae8 7569 nla_nest_end(msg, wme);
774bfa62
EP
7570 }
7571
0f4e8b4f 7572 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 7573 msg = NULL;
0f4e8b4f 7574 if (ret)
45b722f1
AN
7575 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
7576 "result: %d (%s)", params->set ? "SET" : "NEW", ret,
7577 strerror(-ret));
0f4e8b4f
JM
7578 if (ret == -EEXIST)
7579 ret = 0;
7580 nla_put_failure:
5883168a 7581 nlmsg_free(msg);
0f4e8b4f
JM
7582 return ret;
7583}
7584
7585
9ebce9c5 7586static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr)
0f4e8b4f 7587{
a2e40bb6 7588 struct wpa_driver_nl80211_data *drv = bss->drv;
0f4e8b4f
JM
7589 struct nl_msg *msg;
7590 int ret;
7591
7592 msg = nlmsg_alloc();
7593 if (!msg)
7594 return -ENOMEM;
7595
9fb04070 7596 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
0f4e8b4f
JM
7597
7598 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 7599 if_nametoindex(bss->ifname));
0f4e8b4f
JM
7600 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
7601
7602 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
83e7bb0e
JM
7603 wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
7604 " --> %d (%s)",
7605 bss->ifname, MAC2STR(addr), ret, strerror(-ret));
0f4e8b4f
JM
7606 if (ret == -ENOENT)
7607 return 0;
7608 return ret;
7609 nla_put_failure:
5883168a 7610 nlmsg_free(msg);
0f4e8b4f
JM
7611 return -ENOBUFS;
7612}
7613
1581b38b 7614
0915d02c
JM
7615static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
7616 int ifidx)
7617{
7618 struct nl_msg *msg;
7619
c6e8e8e4
JM
7620 wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
7621
2135f224
JM
7622 /* stop listening for EAPOL on this interface */
7623 del_ifidx(drv, ifidx);
2135f224 7624
0915d02c
JM
7625 msg = nlmsg_alloc();
7626 if (!msg)
7627 goto nla_put_failure;
7628
9fb04070 7629 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
0915d02c
JM
7630 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
7631
7632 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
7633 return;
5883168a 7634 msg = NULL;
0915d02c 7635 nla_put_failure:
5883168a 7636 nlmsg_free(msg);
e748062b 7637 wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
0915d02c
JM
7638}
7639
7640
a1922f93
JM
7641static const char * nl80211_iftype_str(enum nl80211_iftype mode)
7642{
7643 switch (mode) {
7644 case NL80211_IFTYPE_ADHOC:
7645 return "ADHOC";
7646 case NL80211_IFTYPE_STATION:
7647 return "STATION";
7648 case NL80211_IFTYPE_AP:
7649 return "AP";
1045ec36
JM
7650 case NL80211_IFTYPE_AP_VLAN:
7651 return "AP_VLAN";
7652 case NL80211_IFTYPE_WDS:
7653 return "WDS";
a1922f93
JM
7654 case NL80211_IFTYPE_MONITOR:
7655 return "MONITOR";
1045ec36
JM
7656 case NL80211_IFTYPE_MESH_POINT:
7657 return "MESH_POINT";
a1922f93
JM
7658 case NL80211_IFTYPE_P2P_CLIENT:
7659 return "P2P_CLIENT";
7660 case NL80211_IFTYPE_P2P_GO:
7661 return "P2P_GO";
7aad838c
NS
7662 case NL80211_IFTYPE_P2P_DEVICE:
7663 return "P2P_DEVICE";
a1922f93
JM
7664 default:
7665 return "unknown";
7666 }
7667}
7668
7669
a35187e7
KH
7670static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
7671 const char *ifname,
7672 enum nl80211_iftype iftype,
d6dcfcda
DS
7673 const u8 *addr, int wds,
7674 int (*handler)(struct nl_msg *, void *),
7675 void *arg)
0915d02c 7676{
8970bae8 7677 struct nl_msg *msg;
0915d02c
JM
7678 int ifidx;
7679 int ret = -ENOBUFS;
7680
a1922f93
JM
7681 wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
7682 iftype, nl80211_iftype_str(iftype));
7683
0915d02c
JM
7684 msg = nlmsg_alloc();
7685 if (!msg)
7686 return -1;
7687
9fb04070 7688 nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_INTERFACE);
834ee56f 7689 if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
fa93de40 7690 goto nla_put_failure;
0915d02c
JM
7691 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
7692 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
7693
7694 if (iftype == NL80211_IFTYPE_MONITOR) {
8970bae8 7695 struct nlattr *flags;
0915d02c 7696
8970bae8 7697 flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
0915d02c
JM
7698 if (!flags)
7699 goto nla_put_failure;
7700
8970bae8 7701 NLA_PUT_FLAG(msg, NL80211_MNTR_FLAG_COOK_FRAMES);
0915d02c 7702
8970bae8 7703 nla_nest_end(msg, flags);
fbbfcbac
FF
7704 } else if (wds) {
7705 NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
0915d02c
JM
7706 }
7707
d6dcfcda 7708 ret = send_and_recv_msgs(drv, msg, handler, arg);
5883168a 7709 msg = NULL;
0915d02c
JM
7710 if (ret) {
7711 nla_put_failure:
5883168a 7712 nlmsg_free(msg);
a35187e7
KH
7713 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
7714 ifname, ret, strerror(-ret));
0915d02c
JM
7715 return ret;
7716 }
7717
f632e483 7718 if (iftype == NL80211_IFTYPE_P2P_DEVICE)
6bae92e0 7719 return 0;
6bae92e0 7720
0915d02c 7721 ifidx = if_nametoindex(ifname);
c6e8e8e4
JM
7722 wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
7723 ifname, ifidx);
0915d02c
JM
7724
7725 if (ifidx <= 0)
7726 return -1;
7727
2135f224
JM
7728 /* start listening for EAPOL on this interface */
7729 add_ifidx(drv, ifidx);
7730
7bfc47c3 7731 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
c81eff1a 7732 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
41d931ee
JM
7733 nl80211_remove_iface(drv, ifidx);
7734 return -1;
2135f224 7735 }
2135f224 7736
0915d02c
JM
7737 return ifidx;
7738}
22a7c9d7
JM
7739
7740
a35187e7
KH
7741static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
7742 const char *ifname, enum nl80211_iftype iftype,
d6dcfcda
DS
7743 const u8 *addr, int wds,
7744 int (*handler)(struct nl_msg *, void *),
2aec4f3c 7745 void *arg, int use_existing)
a35187e7
KH
7746{
7747 int ret;
7748
d6dcfcda
DS
7749 ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
7750 arg);
a35187e7 7751
ffbf1eaa 7752 /* if error occurred and interface exists already */
a35187e7 7753 if (ret == -ENFILE && if_nametoindex(ifname)) {
2aec4f3c
JM
7754 if (use_existing) {
7755 wpa_printf(MSG_DEBUG, "nl80211: Continue using existing interface %s",
7756 ifname);
6997f8ba
JM
7757 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
7758 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
7759 addr) < 0 &&
7760 (linux_set_iface_flags(drv->global->ioctl_sock,
7761 ifname, 0) < 0 ||
7762 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
7763 addr) < 0 ||
7764 linux_set_iface_flags(drv->global->ioctl_sock,
7765 ifname, 1) < 0))
7766 return -1;
2aec4f3c
JM
7767 return -ENFILE;
7768 }
a35187e7
KH
7769 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
7770
7771 /* Try to remove the interface that was already there. */
7772 nl80211_remove_iface(drv, if_nametoindex(ifname));
7773
7774 /* Try to create the interface again */
fbbfcbac 7775 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
d6dcfcda 7776 wds, handler, arg);
a35187e7
KH
7777 }
7778
6a71413e 7779 if (ret >= 0 && is_p2p_net_interface(iftype))
4e5cb1a3
JM
7780 nl80211_disable_11b_rates(drv, ret, 1);
7781
a35187e7
KH
7782 return ret;
7783}
0915d02c 7784
2135f224 7785
0915d02c
JM
7786static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
7787{
7788 struct ieee80211_hdr *hdr;
f8b1f695
JM
7789 u16 fc;
7790 union wpa_event_data event;
0915d02c
JM
7791
7792 hdr = (struct ieee80211_hdr *) buf;
7793 fc = le_to_host16(hdr->frame_control);
7794
f8b1f695
JM
7795 os_memset(&event, 0, sizeof(event));
7796 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
7797 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
7798 event.tx_status.dst = hdr->addr1;
7799 event.tx_status.data = buf;
7800 event.tx_status.data_len = len;
7801 event.tx_status.ack = ok;
7802 wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event);
0915d02c
JM
7803}
7804
7805
4b9841d3 7806static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
0d9fc3d8 7807 u8 *buf, size_t len)
0915d02c 7808{
9b90955e
JB
7809 struct ieee80211_hdr *hdr = (void *)buf;
7810 u16 fc;
f8b1f695 7811 union wpa_event_data event;
9b90955e
JB
7812
7813 if (len < sizeof(*hdr))
7814 return;
7815
7816 fc = le_to_host16(hdr->frame_control);
7817
f8b1f695 7818 os_memset(&event, 0, sizeof(event));
9b90955e
JB
7819 event.rx_from_unknown.bssid = get_hdr_bssid(hdr, len);
7820 event.rx_from_unknown.addr = hdr->addr2;
7821 event.rx_from_unknown.wds = (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) ==
7822 (WLAN_FC_FROMDS | WLAN_FC_TODS);
f8b1f695 7823 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
4b9841d3 7824}
0915d02c 7825
4b9841d3
JM
7826
7827static void handle_frame(struct wpa_driver_nl80211_data *drv,
2a8b7416 7828 u8 *buf, size_t len, int datarate, int ssi_signal)
4b9841d3
JM
7829{
7830 struct ieee80211_hdr *hdr;
f8b1f695
JM
7831 u16 fc;
7832 union wpa_event_data event;
0915d02c
JM
7833
7834 hdr = (struct ieee80211_hdr *) buf;
7835 fc = le_to_host16(hdr->frame_control);
0915d02c 7836
4b9841d3 7837 switch (WLAN_FC_GET_TYPE(fc)) {
0915d02c 7838 case WLAN_FC_TYPE_MGMT:
f8b1f695
JM
7839 os_memset(&event, 0, sizeof(event));
7840 event.rx_mgmt.frame = buf;
7841 event.rx_mgmt.frame_len = len;
2a8b7416
JM
7842 event.rx_mgmt.datarate = datarate;
7843 event.rx_mgmt.ssi_signal = ssi_signal;
f8b1f695 7844 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
0915d02c
JM
7845 break;
7846 case WLAN_FC_TYPE_CTRL:
7847 /* can only get here with PS-Poll frames */
7848 wpa_printf(MSG_DEBUG, "CTRL");
0d9fc3d8 7849 from_unknown_sta(drv, buf, len);
0915d02c
JM
7850 break;
7851 case WLAN_FC_TYPE_DATA:
0d9fc3d8 7852 from_unknown_sta(drv, buf, len);
0915d02c
JM
7853 break;
7854 }
7855}
7856
7857
7858static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
7859{
7860 struct wpa_driver_nl80211_data *drv = eloop_ctx;
7861 int len;
7862 unsigned char buf[3000];
7863 struct ieee80211_radiotap_iterator iter;
7864 int ret;
2a8b7416 7865 int datarate = 0, ssi_signal = 0;
4b9841d3 7866 int injected = 0, failed = 0, rxflags = 0;
0915d02c
JM
7867
7868 len = recv(sock, buf, sizeof(buf), 0);
7869 if (len < 0) {
7ac3616d
JM
7870 wpa_printf(MSG_ERROR, "nl80211: Monitor socket recv failed: %s",
7871 strerror(errno));
0915d02c
JM
7872 return;
7873 }
7874
0e80ea2c 7875 if (ieee80211_radiotap_iterator_init(&iter, (void *) buf, len, NULL)) {
7ac3616d 7876 wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame");
0915d02c
JM
7877 return;
7878 }
7879
0915d02c
JM
7880 while (1) {
7881 ret = ieee80211_radiotap_iterator_next(&iter);
7882 if (ret == -ENOENT)
7883 break;
7884 if (ret) {
7ac3616d
JM
7885 wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame (%d)",
7886 ret);
0915d02c
JM
7887 return;
7888 }
7889 switch (iter.this_arg_index) {
7890 case IEEE80211_RADIOTAP_FLAGS:
7891 if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
7892 len -= 4;
7893 break;
7894 case IEEE80211_RADIOTAP_RX_FLAGS:
7895 rxflags = 1;
7896 break;
7897 case IEEE80211_RADIOTAP_TX_FLAGS:
7898 injected = 1;
7899 failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
7900 IEEE80211_RADIOTAP_F_TX_FAIL;
7901 break;
7902 case IEEE80211_RADIOTAP_DATA_RETRIES:
7903 break;
7904 case IEEE80211_RADIOTAP_CHANNEL:
2a8b7416 7905 /* TODO: convert from freq/flags to channel number */
0915d02c
JM
7906 break;
7907 case IEEE80211_RADIOTAP_RATE:
2a8b7416 7908 datarate = *iter.this_arg * 5;
0915d02c 7909 break;
baf513d6
JB
7910 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
7911 ssi_signal = (s8) *iter.this_arg;
0915d02c
JM
7912 break;
7913 }
7914 }
7915
7916 if (rxflags && injected)
7917 return;
7918
7919 if (!injected)
bacb984b
JB
7920 handle_frame(drv, buf + iter._max_length,
7921 len - iter._max_length, datarate, ssi_signal);
0915d02c 7922 else
bacb984b
JB
7923 handle_tx_callback(drv->ctx, buf + iter._max_length,
7924 len - iter._max_length, !failed);
0915d02c
JM
7925}
7926
7927
7928/*
7929 * we post-process the filter code later and rewrite
7930 * this to the offset to the last instruction
7931 */
7932#define PASS 0xFF
7933#define FAIL 0xFE
7934
7935static struct sock_filter msock_filter_insns[] = {
7936 /*
7937 * do a little-endian load of the radiotap length field
7938 */
7939 /* load lower byte into A */
7940 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
7941 /* put it into X (== index register) */
7942 BPF_STMT(BPF_MISC| BPF_TAX, 0),
7943 /* load upper byte into A */
7944 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 3),
7945 /* left-shift it by 8 */
7946 BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
7947 /* or with X */
7948 BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
7949 /* put result into X */
7950 BPF_STMT(BPF_MISC| BPF_TAX, 0),
7951
7952 /*
7953 * Allow management frames through, this also gives us those
7954 * management frames that we sent ourselves with status
7955 */
7956 /* load the lower byte of the IEEE 802.11 frame control field */
7957 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
7958 /* mask off frame type and version */
7959 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
7960 /* accept frame if it's both 0, fall through otherwise */
7961 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
7962
7963 /*
7964 * TODO: add a bit to radiotap RX flags that indicates
7965 * that the sending station is not associated, then
7966 * add a filter here that filters on our DA and that flag
7967 * to allow us to deauth frames to that bad station.
7968 *
65ae1afd 7969 * For now allow all To DS data frames through.
0915d02c 7970 */
65ae1afd
HS
7971 /* load the IEEE 802.11 frame control field */
7972 BPF_STMT(BPF_LD | BPF_H | BPF_IND, 0),
7973 /* mask off frame type, version and DS status */
7974 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0F03),
7975 /* accept frame if version 0, type 2 and To DS, fall through otherwise
7976 */
7977 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0801, PASS, 0),
0915d02c
JM
7978
7979#if 0
7980 /*
fbbfcbac 7981 * drop non-data frames
0915d02c
JM
7982 */
7983 /* load the lower byte of the frame control field */
7984 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
7985 /* mask off QoS bit */
7986 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0c),
7987 /* drop non-data frames */
7988 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 8, 0, FAIL),
fbbfcbac 7989#endif
0915d02c 7990 /* load the upper byte of the frame control field */
fbbfcbac 7991 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
0915d02c
JM
7992 /* mask off toDS/fromDS */
7993 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x03),
fbbfcbac
FF
7994 /* accept WDS frames */
7995 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 3, PASS, 0),
0915d02c
JM
7996
7997 /*
7998 * add header length to index
7999 */
8000 /* load the lower byte of the frame control field */
8001 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
8002 /* mask off QoS bit */
8003 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80),
8004 /* right shift it by 6 to give 0 or 2 */
8005 BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 6),
8006 /* add data frame header length */
8007 BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 24),
8008 /* add index, was start of 802.11 header */
8009 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
8010 /* move to index, now start of LL header */
8011 BPF_STMT(BPF_MISC | BPF_TAX, 0),
8012
8013 /*
8014 * Accept empty data frames, we use those for
8015 * polling activity.
8016 */
8017 BPF_STMT(BPF_LD | BPF_W | BPF_LEN, 0),
8018 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
8019
8020 /*
8021 * Accept EAPOL frames
8022 */
8023 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 0),
8024 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
8025 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 4),
8026 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
8027
8028 /* keep these last two statements or change the code below */
8029 /* return 0 == "DROP" */
8030 BPF_STMT(BPF_RET | BPF_K, 0),
8031 /* return ~0 == "keep all" */
8032 BPF_STMT(BPF_RET | BPF_K, ~0),
8033};
8034
8035static struct sock_fprog msock_filter = {
e7ecab4a 8036 .len = ARRAY_SIZE(msock_filter_insns),
0915d02c
JM
8037 .filter = msock_filter_insns,
8038};
8039
8040
8041static int add_monitor_filter(int s)
8042{
8043 int idx;
8044
8045 /* rewrite all PASS/FAIL jump offsets */
8046 for (idx = 0; idx < msock_filter.len; idx++) {
8047 struct sock_filter *insn = &msock_filter_insns[idx];
8048
8049 if (BPF_CLASS(insn->code) == BPF_JMP) {
8050 if (insn->code == (BPF_JMP|BPF_JA)) {
8051 if (insn->k == PASS)
8052 insn->k = msock_filter.len - idx - 2;
8053 else if (insn->k == FAIL)
8054 insn->k = msock_filter.len - idx - 3;
8055 }
8056
8057 if (insn->jt == PASS)
8058 insn->jt = msock_filter.len - idx - 2;
8059 else if (insn->jt == FAIL)
8060 insn->jt = msock_filter.len - idx - 3;
8061
8062 if (insn->jf == PASS)
8063 insn->jf = msock_filter.len - idx - 2;
8064 else if (insn->jf == FAIL)
8065 insn->jf = msock_filter.len - idx - 3;
8066 }
8067 }
8068
8069 if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
8070 &msock_filter, sizeof(msock_filter))) {
7ac3616d
JM
8071 wpa_printf(MSG_ERROR, "nl80211: setsockopt(SO_ATTACH_FILTER) failed: %s",
8072 strerror(errno));
0915d02c
JM
8073 return -1;
8074 }
8075
8076 return 0;
8077}
8078
8079
460456f8
JM
8080static void nl80211_remove_monitor_interface(
8081 struct wpa_driver_nl80211_data *drv)
8082{
748c0ac0
JM
8083 if (drv->monitor_refcount > 0)
8084 drv->monitor_refcount--;
8085 wpa_printf(MSG_DEBUG, "nl80211: Remove monitor interface: refcount=%d",
8086 drv->monitor_refcount);
3fd1cefb
JB
8087 if (drv->monitor_refcount > 0)
8088 return;
8089
460456f8
JM
8090 if (drv->monitor_ifidx >= 0) {
8091 nl80211_remove_iface(drv, drv->monitor_ifidx);
8092 drv->monitor_ifidx = -1;
8093 }
504e905c
JM
8094 if (drv->monitor_sock >= 0) {
8095 eloop_unregister_read_sock(drv->monitor_sock);
8096 close(drv->monitor_sock);
8097 drv->monitor_sock = -1;
8098 }
460456f8
JM
8099}
8100
8101
0915d02c
JM
8102static int
8103nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
8104{
8105 char buf[IFNAMSIZ];
8106 struct sockaddr_ll ll;
8107 int optval;
8108 socklen_t optlen;
0915d02c 8109
3fd1cefb
JB
8110 if (drv->monitor_ifidx >= 0) {
8111 drv->monitor_refcount++;
748c0ac0
JM
8112 wpa_printf(MSG_DEBUG, "nl80211: Re-use existing monitor interface: refcount=%d",
8113 drv->monitor_refcount);
3fd1cefb
JB
8114 return 0;
8115 }
8116
834ee56f 8117 if (os_strncmp(drv->first_bss->ifname, "p2p-", 4) == 0) {
6758b167
JJ
8118 /*
8119 * P2P interface name is of the format p2p-%s-%d. For monitor
8120 * interface name corresponding to P2P GO, replace "p2p-" with
8121 * "mon-" to retain the same interface name length and to
8122 * indicate that it is a monitor interface.
8123 */
834ee56f 8124 snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss->ifname + 4);
6758b167
JJ
8125 } else {
8126 /* Non-P2P interface with AP functionality. */
834ee56f 8127 snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss->ifname);
6758b167
JJ
8128 }
8129
0915d02c
JM
8130 buf[IFNAMSIZ - 1] = '\0';
8131
8132 drv->monitor_ifidx =
fbbfcbac 8133 nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
2aec4f3c 8134 0, NULL, NULL, 0);
0915d02c 8135
866af8b6 8136 if (drv->monitor_ifidx == -EOPNOTSUPP) {
61cbe2ff
JB
8137 /*
8138 * This is backward compatibility for a few versions of
8139 * the kernel only that didn't advertise the right
8140 * attributes for the only driver that then supported
8141 * AP mode w/o monitor -- ath6kl.
8142 */
866af8b6
JM
8143 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support "
8144 "monitor interface type - try to run without it");
61cbe2ff 8145 drv->device_ap_sme = 1;
866af8b6
JM
8146 }
8147
0915d02c
JM
8148 if (drv->monitor_ifidx < 0)
8149 return -1;
8150
c81eff1a 8151 if (linux_set_iface_flags(drv->global->ioctl_sock, buf, 1))
0915d02c 8152 goto error;
0915d02c
JM
8153
8154 memset(&ll, 0, sizeof(ll));
8155 ll.sll_family = AF_PACKET;
8156 ll.sll_ifindex = drv->monitor_ifidx;
8157 drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8158 if (drv->monitor_sock < 0) {
7ac3616d
JM
8159 wpa_printf(MSG_ERROR, "nl80211: socket[PF_PACKET,SOCK_RAW] failed: %s",
8160 strerror(errno));
0915d02c
JM
8161 goto error;
8162 }
8163
8164 if (add_monitor_filter(drv->monitor_sock)) {
8165 wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
8166 "interface; do filtering in user space");
8167 /* This works, but will cost in performance. */
8168 }
8169
2135f224 8170 if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
7ac3616d
JM
8171 wpa_printf(MSG_ERROR, "nl80211: monitor socket bind failed: %s",
8172 strerror(errno));
0915d02c
JM
8173 goto error;
8174 }
8175
8176 optlen = sizeof(optval);
8177 optval = 20;
8178 if (setsockopt
8179 (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
7ac3616d
JM
8180 wpa_printf(MSG_ERROR, "nl80211: Failed to set socket priority: %s",
8181 strerror(errno));
0915d02c
JM
8182 goto error;
8183 }
8184
8185 if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
8186 drv, NULL)) {
7ac3616d 8187 wpa_printf(MSG_INFO, "nl80211: Could not register monitor read socket");
0915d02c
JM
8188 goto error;
8189 }
8190
748c0ac0 8191 drv->monitor_refcount++;
0915d02c
JM
8192 return 0;
8193 error:
460456f8 8194 nl80211_remove_monitor_interface(drv);
0915d02c
JM
8195 return -1;
8196}
8197
db149ac9 8198
3fd1cefb
JB
8199static int nl80211_setup_ap(struct i802_bss *bss)
8200{
8201 struct wpa_driver_nl80211_data *drv = bss->drv;
8202
748c0ac0
JM
8203 wpa_printf(MSG_DEBUG, "nl80211: Setup AP(%s) - device_ap_sme=%d use_monitor=%d",
8204 bss->ifname, drv->device_ap_sme, drv->use_monitor);
36488c05 8205
a11241fa
JB
8206 /*
8207 * Disable Probe Request reporting unless we need it in this way for
8208 * devices that include the AP SME, in the other case (unless using
8209 * monitor iface) we'll get it through the nl_mgmt socket instead.
8210 */
8211 if (!drv->device_ap_sme)
8212 wpa_driver_nl80211_probe_req_report(bss, 0);
8213
8214 if (!drv->device_ap_sme && !drv->use_monitor)
8215 if (nl80211_mgmt_subscribe_ap(bss))
8216 return -1;
8217
a6cc0602
JM
8218 if (drv->device_ap_sme && !drv->use_monitor)
8219 if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
8220 return -1;
8221
a11241fa 8222 if (!drv->device_ap_sme && drv->use_monitor &&
3fd1cefb
JB
8223 nl80211_create_monitor_interface(drv) &&
8224 !drv->device_ap_sme)
8225 return -1;
8226
8227 if (drv->device_ap_sme &&
8228 wpa_driver_nl80211_probe_req_report(bss, 1) < 0) {
8229 wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
8230 "Probe Request frame reporting in AP mode");
8231 /* Try to survive without this */
8232 }
8233
8234 return 0;
8235}
8236
8237
8238static void nl80211_teardown_ap(struct i802_bss *bss)
8239{
8240 struct wpa_driver_nl80211_data *drv = bss->drv;
8241
748c0ac0
JM
8242 wpa_printf(MSG_DEBUG, "nl80211: Teardown AP(%s) - device_ap_sme=%d use_monitor=%d",
8243 bss->ifname, drv->device_ap_sme, drv->use_monitor);
a6cc0602 8244 if (drv->device_ap_sme) {
3fd1cefb 8245 wpa_driver_nl80211_probe_req_report(bss, 0);
a6cc0602
JM
8246 if (!drv->use_monitor)
8247 nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
8248 } else if (drv->use_monitor)
3fd1cefb 8249 nl80211_remove_monitor_interface(drv);
a11241fa 8250 else
36488c05 8251 nl80211_mgmt_unsubscribe(bss, "AP teardown");
a11241fa 8252
3fd1cefb
JB
8253 bss->beacon_set = 0;
8254}
8255
8256
f10bfc9a
JM
8257static int nl80211_send_eapol_data(struct i802_bss *bss,
8258 const u8 *addr, const u8 *data,
d12dab4c 8259 size_t data_len)
f10bfc9a 8260{
d12dab4c
JB
8261 struct sockaddr_ll ll;
8262 int ret;
8263
8264 if (bss->drv->eapol_tx_sock < 0) {
8265 wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
f10bfc9a
JM
8266 return -1;
8267 }
8268
d12dab4c
JB
8269 os_memset(&ll, 0, sizeof(ll));
8270 ll.sll_family = AF_PACKET;
8271 ll.sll_ifindex = bss->ifindex;
8272 ll.sll_protocol = htons(ETH_P_PAE);
8273 ll.sll_halen = ETH_ALEN;
8274 os_memcpy(ll.sll_addr, addr, ETH_ALEN);
8275 ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
8276 (struct sockaddr *) &ll, sizeof(ll));
8277 if (ret < 0)
8278 wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
8279 strerror(errno));
8280
8281 return ret;
f10bfc9a 8282}
5fb1a232 8283
f10bfc9a 8284
db149ac9
JM
8285static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
8286
8287static int wpa_driver_nl80211_hapd_send_eapol(
8288 void *priv, const u8 *addr, const u8 *data,
4378fc14 8289 size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
db149ac9 8290{
a2e40bb6
FF
8291 struct i802_bss *bss = priv;
8292 struct wpa_driver_nl80211_data *drv = bss->drv;
db149ac9
JM
8293 struct ieee80211_hdr *hdr;
8294 size_t len;
8295 u8 *pos;
8296 int res;
4378fc14 8297 int qos = flags & WPA_STA_WMM;
db149ac9 8298
a11241fa 8299 if (drv->device_ap_sme || !drv->use_monitor)
d12dab4c 8300 return nl80211_send_eapol_data(bss, addr, data, data_len);
f10bfc9a 8301
db149ac9
JM
8302 len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
8303 data_len;
8304 hdr = os_zalloc(len);
8305 if (hdr == NULL) {
7ac3616d
JM
8306 wpa_printf(MSG_INFO, "nl80211: Failed to allocate EAPOL buffer(len=%lu)",
8307 (unsigned long) len);
db149ac9
JM
8308 return -1;
8309 }
8310
8311 hdr->frame_control =
8312 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
8313 hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
8314 if (encrypt)
8315 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
db149ac9
JM
8316 if (qos) {
8317 hdr->frame_control |=
8318 host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
8319 }
db149ac9
JM
8320
8321 memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
8322 memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
8323 memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
8324 pos = (u8 *) (hdr + 1);
8325
db149ac9 8326 if (qos) {
92d521d8
FF
8327 /* Set highest priority in QoS header */
8328 pos[0] = 7;
db149ac9
JM
8329 pos[1] = 0;
8330 pos += 2;
8331 }
db149ac9
JM
8332
8333 memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
8334 pos += sizeof(rfc1042_header);
8335 WPA_PUT_BE16(pos, ETH_P_PAE);
8336 pos += 2;
8337 memcpy(pos, data, data_len);
8338
55231068
JM
8339 res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
8340 0, 0, 0, 0);
db149ac9
JM
8341 if (res < 0) {
8342 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
8343 "failed: %d (%s)",
8344 (unsigned long) len, errno, strerror(errno));
8345 }
7bf12757 8346 os_free(hdr);
db149ac9
JM
8347
8348 return res;
8349}
8350
a8d6ffa4 8351
3234cba4
JM
8352static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
8353 int total_flags,
4c32757d 8354 int flags_or, int flags_and)
a8d6ffa4 8355{
a2e40bb6
FF
8356 struct i802_bss *bss = priv;
8357 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8
JB
8358 struct nl_msg *msg;
8359 struct nlattr *flags;
7e76ee9c 8360 struct nl80211_sta_flag_update upd;
a8d6ffa4
JM
8361
8362 msg = nlmsg_alloc();
8363 if (!msg)
8364 return -ENOMEM;
8365
9fb04070 8366 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
a8d6ffa4
JM
8367
8368 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
3234cba4 8369 if_nametoindex(bss->ifname));
a8d6ffa4
JM
8370 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
8371
7e76ee9c
JM
8372 /*
8373 * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
8374 * can be removed eventually.
8375 */
8970bae8
JB
8376 flags = nla_nest_start(msg, NL80211_ATTR_STA_FLAGS);
8377 if (!flags)
8378 goto nla_put_failure;
0de39516 8379 if (total_flags & WPA_STA_AUTHORIZED)
8970bae8 8380 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_AUTHORIZED);
a8d6ffa4 8381
0de39516 8382 if (total_flags & WPA_STA_WMM)
8970bae8 8383 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_WME);
a8d6ffa4 8384
0de39516 8385 if (total_flags & WPA_STA_SHORT_PREAMBLE)
8970bae8 8386 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_SHORT_PREAMBLE);
a8d6ffa4 8387
0de39516 8388 if (total_flags & WPA_STA_MFP)
8970bae8 8389 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_MFP);
a8d6ffa4 8390
45b722f1 8391 if (total_flags & WPA_STA_TDLS_PEER)
8970bae8 8392 NLA_PUT_FLAG(msg, NL80211_STA_FLAG_TDLS_PEER);
45b722f1 8393
8970bae8 8394 nla_nest_end(msg, flags);
a8d6ffa4 8395
7e76ee9c
JM
8396 os_memset(&upd, 0, sizeof(upd));
8397 upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
8398 upd.set = sta_flags_nl80211(flags_or);
8399 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
8400
a8d6ffa4
JM
8401 return send_and_recv_msgs(drv, msg, NULL, NULL);
8402 nla_put_failure:
5883168a 8403 nlmsg_free(msg);
a8d6ffa4
JM
8404 return -ENOBUFS;
8405}
8406
0915d02c 8407
1581b38b
JM
8408static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
8409 struct wpa_driver_associate_params *params)
8410{
708bc8e0 8411 enum nl80211_iftype nlmode, old_mode;
89b800d7
JB
8412 struct hostapd_freq_params freq = {
8413 .freq = params->freq,
8414 };
b1f625e0
EP
8415
8416 if (params->p2p) {
046b26a2
JM
8417 wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
8418 "group (GO)");
b1f625e0
EP
8419 nlmode = NL80211_IFTYPE_P2P_GO;
8420 } else
8421 nlmode = NL80211_IFTYPE_AP;
8422
708bc8e0 8423 old_mode = drv->nlmode;
834ee56f 8424 if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
708bc8e0
JM
8425 nl80211_remove_monitor_interface(drv);
8426 return -1;
8427 }
8428
13a524a3 8429 if (nl80211_set_channel(drv->first_bss, &freq, 0)) {
708bc8e0 8430 if (old_mode != nlmode)
834ee56f 8431 wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
460456f8 8432 nl80211_remove_monitor_interface(drv);
1581b38b 8433 return -1;
0915d02c 8434 }
1581b38b 8435
1581b38b
JM
8436 return 0;
8437}
1581b38b
JM
8438
8439
5cc4d64b
JM
8440static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
8441{
8442 struct nl_msg *msg;
8443 int ret = -1;
8444
8445 msg = nlmsg_alloc();
8446 if (!msg)
8447 return -1;
8448
9fb04070 8449 nl80211_cmd(drv, msg, 0, NL80211_CMD_LEAVE_IBSS);
5cc4d64b
JM
8450 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
8451 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8452 msg = NULL;
8453 if (ret) {
8454 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
8455 "(%s)", ret, strerror(-ret));
8456 goto nla_put_failure;
8457 }
8458
8459 ret = 0;
8460 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
8461
8462nla_put_failure:
834ee56f 8463 if (wpa_driver_nl80211_set_mode(drv->first_bss,
5d4c78fb
JM
8464 NL80211_IFTYPE_STATION)) {
8465 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
8466 "station mode");
8467 }
8468
5cc4d64b
JM
8469 nlmsg_free(msg);
8470 return ret;
8471}
8472
8473
8474static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
8475 struct wpa_driver_associate_params *params)
8476{
8477 struct nl_msg *msg;
8478 int ret = -1;
8479 int count = 0;
8480
8481 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
8482
834ee56f 8483 if (wpa_driver_nl80211_set_mode(drv->first_bss,
b1f625e0 8484 NL80211_IFTYPE_ADHOC)) {
5cc4d64b
JM
8485 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
8486 "IBSS mode");
8487 return -1;
8488 }
8489
8490retry:
8491 msg = nlmsg_alloc();
8492 if (!msg)
8493 return -1;
8494
9fb04070 8495 nl80211_cmd(drv, msg, 0, NL80211_CMD_JOIN_IBSS);
5cc4d64b
JM
8496 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
8497
8498 if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
8499 goto nla_put_failure;
8500
8501 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
8502 params->ssid, params->ssid_len);
8503 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
8504 params->ssid);
8505 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
8506 drv->ssid_len = params->ssid_len;
8507
8508 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
8509 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
8510
8f05577d
JM
8511 if (params->beacon_int > 0) {
8512 wpa_printf(MSG_DEBUG, " * beacon_int=%d", params->beacon_int);
8513 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL,
8514 params->beacon_int);
8515 }
8516
5cc4d64b
JM
8517 ret = nl80211_set_conn_keys(params, msg);
8518 if (ret)
8519 goto nla_put_failure;
8520
913e3cf7
NC
8521 if (params->bssid && params->fixed_bssid) {
8522 wpa_printf(MSG_DEBUG, " * BSSID=" MACSTR,
8523 MAC2STR(params->bssid));
8524 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
8525 }
8526
4848a38d
JM
8527 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
8528 params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
8529 params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
8530 params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
e640888c
AQ
8531 wpa_printf(MSG_DEBUG, " * control port");
8532 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
8533 }
8534
a95795ad
JM
8535 if (params->wpa_ie) {
8536 wpa_hexdump(MSG_DEBUG,
8537 " * Extra IEs for Beacon/Probe Response frames",
8538 params->wpa_ie, params->wpa_ie_len);
8539 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
8540 params->wpa_ie);
8541 }
8542
5cc4d64b
JM
8543 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8544 msg = NULL;
8545 if (ret) {
8546 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
8547 ret, strerror(-ret));
8548 count++;
8549 if (ret == -EALREADY && count == 1) {
8550 wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
8551 "forced leave");
8552 nl80211_leave_ibss(drv);
8553 nlmsg_free(msg);
8554 goto retry;
8555 }
8556
8557 goto nla_put_failure;
8558 }
8559 ret = 0;
8560 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
8561
8562nla_put_failure:
8563 nlmsg_free(msg);
8564 return ret;
8565}
8566
8567
a0bdd191
JM
8568static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
8569 struct wpa_driver_associate_params *params,
8570 struct nl_msg *msg)
cfaab580 8571{
cfaab580 8572 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
a0bdd191 8573
cfaab580
ZY
8574 if (params->bssid) {
8575 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
8576 MAC2STR(params->bssid));
8577 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
8578 }
a0bdd191 8579
7ac7fd43
DS
8580 if (params->bssid_hint) {
8581 wpa_printf(MSG_DEBUG, " * bssid_hint=" MACSTR,
8582 MAC2STR(params->bssid_hint));
8583 NLA_PUT(msg, NL80211_ATTR_MAC_HINT, ETH_ALEN,
8584 params->bssid_hint);
8585 }
8586
cfaab580
ZY
8587 if (params->freq) {
8588 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
8589 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
30158a0d
SD
8590 drv->assoc_freq = params->freq;
8591 } else
8592 drv->assoc_freq = 0;
a0bdd191 8593
7ac7fd43
DS
8594 if (params->freq_hint) {
8595 wpa_printf(MSG_DEBUG, " * freq_hint=%d", params->freq_hint);
8596 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ_HINT,
8597 params->freq_hint);
8598 }
8599
1f6c0ab8
BS
8600 if (params->bg_scan_period >= 0) {
8601 wpa_printf(MSG_DEBUG, " * bg scan period=%d",
8602 params->bg_scan_period);
8603 NLA_PUT_U16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
8604 params->bg_scan_period);
8605 }
a0bdd191 8606
cfaab580
ZY
8607 if (params->ssid) {
8608 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
8609 params->ssid, params->ssid_len);
8610 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
8611 params->ssid);
8612 if (params->ssid_len > sizeof(drv->ssid))
8613 goto nla_put_failure;
8614 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
8615 drv->ssid_len = params->ssid_len;
8616 }
a0bdd191 8617
cfaab580
ZY
8618 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
8619 if (params->wpa_ie)
8620 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
8621 params->wpa_ie);
8622
64fa840a
JM
8623 if (params->wpa_proto) {
8624 enum nl80211_wpa_versions ver = 0;
cfaab580 8625
64fa840a
JM
8626 if (params->wpa_proto & WPA_PROTO_WPA)
8627 ver |= NL80211_WPA_VERSION_1;
8628 if (params->wpa_proto & WPA_PROTO_RSN)
8629 ver |= NL80211_WPA_VERSION_2;
cfaab580 8630
64fa840a 8631 wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
cfaab580
ZY
8632 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
8633 }
8634
4848a38d 8635 if (params->pairwise_suite != WPA_CIPHER_NONE) {
a0bdd191
JM
8636 u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
8637 wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
8638 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
cfaab580
ZY
8639 }
8640
ae6f9272
JM
8641 if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
8642 !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
8643 /*
8644 * This is likely to work even though many drivers do not
8645 * advertise support for operations without GTK.
8646 */
8647 wpa_printf(MSG_DEBUG, " * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
8648 } else if (params->group_suite != WPA_CIPHER_NONE) {
a0bdd191
JM
8649 u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
8650 wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
8651 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
cfaab580
ZY
8652 }
8653
4848a38d
JM
8654 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
8655 params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
8656 params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
8657 params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
163f801e
JM
8658 params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
8659 params->key_mgmt_suite == WPA_KEY_MGMT_OSEN) {
cfaab580
ZY
8660 int mgmt = WLAN_AKM_SUITE_PSK;
8661
8662 switch (params->key_mgmt_suite) {
4848a38d 8663 case WPA_KEY_MGMT_CCKM:
369c8d7b
JM
8664 mgmt = WLAN_AKM_SUITE_CCKM;
8665 break;
4848a38d 8666 case WPA_KEY_MGMT_IEEE8021X:
cfaab580
ZY
8667 mgmt = WLAN_AKM_SUITE_8021X;
8668 break;
4848a38d 8669 case WPA_KEY_MGMT_FT_IEEE8021X:
6a1ce395
DG
8670 mgmt = WLAN_AKM_SUITE_FT_8021X;
8671 break;
4848a38d 8672 case WPA_KEY_MGMT_FT_PSK:
6a1ce395
DG
8673 mgmt = WLAN_AKM_SUITE_FT_PSK;
8674 break;
163f801e
JM
8675 case WPA_KEY_MGMT_OSEN:
8676 mgmt = WLAN_AKM_SUITE_OSEN;
8677 break;
4848a38d 8678 case WPA_KEY_MGMT_PSK:
cfaab580
ZY
8679 default:
8680 mgmt = WLAN_AKM_SUITE_PSK;
8681 break;
8682 }
163f801e 8683 wpa_printf(MSG_DEBUG, " * akm=0x%x", mgmt);
cfaab580
ZY
8684 NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
8685 }
8686
a0bdd191
JM
8687 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
8688
8b706a99
JM
8689 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
8690 NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
a565084f 8691
80e8a5ee
BG
8692 if (params->disable_ht)
8693 NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
8694
8695 if (params->htcaps && params->htcaps_mask) {
8696 int sz = sizeof(struct ieee80211_ht_capabilities);
6d99bd80 8697 wpa_hexdump(MSG_DEBUG, " * htcaps", params->htcaps, sz);
80e8a5ee 8698 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
6d99bd80
JM
8699 wpa_hexdump(MSG_DEBUG, " * htcaps_mask",
8700 params->htcaps_mask, sz);
80e8a5ee
BG
8701 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
8702 params->htcaps_mask);
8703 }
8704
e9ee8dc3
JB
8705#ifdef CONFIG_VHT_OVERRIDES
8706 if (params->disable_vht) {
8707 wpa_printf(MSG_DEBUG, " * VHT disabled");
8708 NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
8709 }
8710
8711 if (params->vhtcaps && params->vhtcaps_mask) {
8712 int sz = sizeof(struct ieee80211_vht_capabilities);
6d99bd80 8713 wpa_hexdump(MSG_DEBUG, " * vhtcaps", params->vhtcaps, sz);
e9ee8dc3 8714 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
6d99bd80
JM
8715 wpa_hexdump(MSG_DEBUG, " * vhtcaps_mask",
8716 params->vhtcaps_mask, sz);
e9ee8dc3
JB
8717 NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
8718 params->vhtcaps_mask);
8719 }
8720#endif /* CONFIG_VHT_OVERRIDES */
8721
a0bdd191
JM
8722 if (params->p2p)
8723 wpa_printf(MSG_DEBUG, " * P2P group");
8724
8725 return 0;
8726nla_put_failure:
8727 return -1;
8728}
8729
8730
8731static int wpa_driver_nl80211_try_connect(
8732 struct wpa_driver_nl80211_data *drv,
8733 struct wpa_driver_associate_params *params)
8734{
8735 struct nl_msg *msg;
8736 enum nl80211_auth_type type;
8737 int ret;
8738 int algs;
8739
8740 msg = nlmsg_alloc();
8741 if (!msg)
8742 return -1;
8743
8744 wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
8745 nl80211_cmd(drv, msg, 0, NL80211_CMD_CONNECT);
8746
8747 ret = nl80211_connect_common(drv, params, msg);
8748 if (ret)
8749 goto nla_put_failure;
8750
8751 algs = 0;
8752 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
8753 algs++;
8754 if (params->auth_alg & WPA_AUTH_ALG_SHARED)
8755 algs++;
8756 if (params->auth_alg & WPA_AUTH_ALG_LEAP)
8757 algs++;
8758 if (algs > 1) {
8759 wpa_printf(MSG_DEBUG, " * Leave out Auth Type for automatic "
8760 "selection");
8761 goto skip_auth_type;
8762 }
8763
8764 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
8765 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
8766 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
8767 type = NL80211_AUTHTYPE_SHARED_KEY;
8768 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
8769 type = NL80211_AUTHTYPE_NETWORK_EAP;
8770 else if (params->auth_alg & WPA_AUTH_ALG_FT)
8771 type = NL80211_AUTHTYPE_FT;
8772 else
8773 goto nla_put_failure;
8774
8775 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
8776 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
8777
8778skip_auth_type:
cfaab580
ZY
8779 ret = nl80211_set_conn_keys(params, msg);
8780 if (ret)
8781 goto nla_put_failure;
8782
8783 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8784 msg = NULL;
8785 if (ret) {
8786 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
8787 "(%s)", ret, strerror(-ret));
8788 goto nla_put_failure;
8789 }
8790 ret = 0;
8791 wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
8792
8793nla_put_failure:
8794 nlmsg_free(msg);
8795 return ret;
8796
8797}
8798
8799
a8c5b43a
CW
8800static int wpa_driver_nl80211_connect(
8801 struct wpa_driver_nl80211_data *drv,
8802 struct wpa_driver_associate_params *params)
8803{
8804 int ret = wpa_driver_nl80211_try_connect(drv, params);
8805 if (ret == -EALREADY) {
8806 /*
8807 * cfg80211 does not currently accept new connections if
8808 * we are already connected. As a workaround, force
8809 * disconnection and try again.
8810 */
8811 wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
8812 "disconnecting before reassociation "
8813 "attempt");
8814 if (wpa_driver_nl80211_disconnect(
8815 drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
8816 return -1;
a8c5b43a
CW
8817 ret = wpa_driver_nl80211_try_connect(drv, params);
8818 }
8819 return ret;
8820}
8821
8822
c2a04078
JM
8823static int wpa_driver_nl80211_associate(
8824 void *priv, struct wpa_driver_associate_params *params)
8825{
a2e40bb6
FF
8826 struct i802_bss *bss = priv;
8827 struct wpa_driver_nl80211_data *drv = bss->drv;
a0bdd191 8828 int ret;
c2a04078
JM
8829 struct nl_msg *msg;
8830
5cc4d64b 8831 if (params->mode == IEEE80211_MODE_AP)
1581b38b 8832 return wpa_driver_nl80211_ap(drv, params);
1581b38b 8833
5cc4d64b
JM
8834 if (params->mode == IEEE80211_MODE_IBSS)
8835 return wpa_driver_nl80211_ibss(drv, params);
8836
4a867032 8837 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
b1f625e0
EP
8838 enum nl80211_iftype nlmode = params->p2p ?
8839 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
8840
8841 if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
4a867032 8842 return -1;
cfaab580 8843 return wpa_driver_nl80211_connect(drv, params);
4a867032 8844 }
cfaab580 8845
add9b7a4 8846 nl80211_mark_disconnected(drv);
c2a04078
JM
8847
8848 msg = nlmsg_alloc();
8849 if (!msg)
8850 return -1;
8851
8852 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
8853 drv->ifindex);
9fb04070 8854 nl80211_cmd(drv, msg, 0, NL80211_CMD_ASSOCIATE);
c2a04078 8855
a0bdd191
JM
8856 ret = nl80211_connect_common(drv, params, msg);
8857 if (ret)
8858 goto nla_put_failure;
01652550 8859
62fa124c
JM
8860 if (params->prev_bssid) {
8861 wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
8862 MAC2STR(params->prev_bssid));
8863 NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
8864 params->prev_bssid);
8865 }
8866
c2a04078
JM
8867 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8868 msg = NULL;
8869 if (ret) {
3b7ea880
BG
8870 wpa_dbg(drv->ctx, MSG_DEBUG,
8871 "nl80211: MLME command failed (assoc): ret=%d (%s)",
8872 ret, strerror(-ret));
8856462d 8873 nl80211_dump_scan(drv);
c2a04078
JM
8874 goto nla_put_failure;
8875 }
8876 ret = 0;
8877 wpa_printf(MSG_DEBUG, "nl80211: Association request send "
8878 "successfully");
8879
8880nla_put_failure:
8881 nlmsg_free(msg);
8882 return ret;
8883}
3f5285e8
JM
8884
8885
ad1e68e6 8886static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
a1922f93 8887 int ifindex, enum nl80211_iftype mode)
3f5285e8 8888{
3f5285e8 8889 struct nl_msg *msg;
ad1e68e6
JM
8890 int ret = -ENOBUFS;
8891
a1922f93
JM
8892 wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
8893 ifindex, mode, nl80211_iftype_str(mode));
8894
ad1e68e6
JM
8895 msg = nlmsg_alloc();
8896 if (!msg)
8897 return -ENOMEM;
8898
9fb04070 8899 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_INTERFACE);
834ee56f 8900 if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
f632e483 8901 goto nla_put_failure;
ad1e68e6
JM
8902 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
8903
8904 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 8905 msg = NULL;
ad1e68e6
JM
8906 if (!ret)
8907 return 0;
8908nla_put_failure:
5883168a 8909 nlmsg_free(msg);
ad1e68e6
JM
8910 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
8911 " %d (%s)", ifindex, mode, ret, strerror(-ret));
8912 return ret;
8913}
8914
8915
b1f625e0
EP
8916static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
8917 enum nl80211_iftype nlmode)
ad1e68e6 8918{
a2e40bb6 8919 struct wpa_driver_nl80211_data *drv = bss->drv;
ad1e68e6 8920 int ret = -1;
26af9dca 8921 int i;
86957e62 8922 int was_ap = is_ap_interface(drv->nlmode);
671a5039 8923 int res;
1581b38b 8924
671a5039 8925 res = nl80211_set_mode(drv, drv->ifindex, nlmode);
8e12685c
AS
8926 if (res && nlmode == nl80211_get_ifmode(bss))
8927 res = 0;
8928
671a5039 8929 if (res == 0) {
ad1e68e6 8930 drv->nlmode = nlmode;
460456f8
JM
8931 ret = 0;
8932 goto done;
ad1e68e6 8933 }
3f5285e8 8934
671a5039
JM
8935 if (res == -ENODEV)
8936 return -1;
8937
460456f8 8938 if (nlmode == drv->nlmode) {
c6e8e8e4
JM
8939 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
8940 "requested mode - ignore error");
460456f8
JM
8941 ret = 0;
8942 goto done; /* Already in the requested mode */
8943 }
3f5285e8 8944
3f5285e8
JM
8945 /* mac80211 doesn't allow mode changes while the device is up, so
8946 * take the device down, try to set the mode again, and bring the
8947 * device back up.
8948 */
26af9dca
JM
8949 wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
8950 "interface down");
8951 for (i = 0; i < 10; i++) {
91724d6f 8952 res = i802_set_iface_flags(bss, 0);
6e8183d7
JM
8953 if (res == -EACCES || res == -ENODEV)
8954 break;
8955 if (res == 0) {
26af9dca
JM
8956 /* Try to set the mode again while the interface is
8957 * down */
8958 ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
6e8183d7
JM
8959 if (ret == -EACCES)
8960 break;
91724d6f 8961 res = i802_set_iface_flags(bss, 1);
6e8183d7 8962 if (res && !ret)
26af9dca 8963 ret = -1;
6e8183d7 8964 else if (ret != -EBUSY)
26af9dca
JM
8965 break;
8966 } else
8967 wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
8968 "interface down");
8969 os_sleep(0, 100000);
3f5285e8
JM
8970 }
8971
c6e8e8e4
JM
8972 if (!ret) {
8973 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
8974 "interface is down");
ad1e68e6 8975 drv->nlmode = nlmode;
7d9c3698 8976 drv->ignore_if_down_event = 1;
c6e8e8e4 8977 }
ad1e68e6 8978
460456f8 8979done:
3fd1cefb
JB
8980 if (ret) {
8981 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
8982 "from %d failed", nlmode, drv->nlmode);
8983 return ret;
8984 }
8985
6a71413e 8986 if (is_p2p_net_interface(nlmode))
edb9bfba 8987 nl80211_disable_11b_rates(drv, drv->ifindex, 1);
1d0c6fb1
JM
8988 else if (drv->disabled_11b_rates)
8989 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
edb9bfba 8990
3fd1cefb 8991 if (is_ap_interface(nlmode)) {
36488c05 8992 nl80211_mgmt_unsubscribe(bss, "start AP");
460456f8 8993 /* Setup additional AP mode functionality if needed */
3fd1cefb 8994 if (nl80211_setup_ap(bss))
460456f8 8995 return -1;
3fd1cefb 8996 } else if (was_ap) {
460456f8 8997 /* Remove additional AP mode functionality */
3fd1cefb 8998 nl80211_teardown_ap(bss);
a11241fa 8999 } else {
36488c05 9000 nl80211_mgmt_unsubscribe(bss, "mode change");
460456f8 9001 }
460456f8 9002
873d0fcf 9003 if (!bss->in_deinit && !is_ap_interface(nlmode) &&
a11241fa
JB
9004 nl80211_mgmt_subscribe_non_ap(bss) < 0)
9005 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
9006 "frame processing - ignore for now");
08359050 9007
3fd1cefb 9008 return 0;
3f5285e8
JM
9009}
9010
9011
65d645ce
AS
9012static int dfs_info_handler(struct nl_msg *msg, void *arg)
9013{
9014 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9015 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9016 int *dfs_capability_ptr = arg;
9017
9018 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9019 genlmsg_attrlen(gnlh, 0), NULL);
9020
9021 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9022 struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
9023 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
9024
9025 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
9026 nla_data(nl_vend), nla_len(nl_vend), NULL);
9027
9028 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
9029 u32 val;
9030 val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
9031 wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
9032 val);
9033 *dfs_capability_ptr = val;
9034 }
9035 }
9036
9037 return NL_SKIP;
9038}
9039
9040
3f5285e8
JM
9041static int wpa_driver_nl80211_get_capa(void *priv,
9042 struct wpa_driver_capa *capa)
9043{
a2e40bb6
FF
9044 struct i802_bss *bss = priv;
9045 struct wpa_driver_nl80211_data *drv = bss->drv;
65d645ce
AS
9046 struct nl_msg *msg;
9047 int dfs_capability = 0;
9048 int ret = 0;
9049
3f5285e8
JM
9050 if (!drv->has_capability)
9051 return -1;
9052 os_memcpy(capa, &drv->capa, sizeof(*capa));
8cd6b7bc
JB
9053 if (drv->extended_capa && drv->extended_capa_mask) {
9054 capa->extended_capa = drv->extended_capa;
9055 capa->extended_capa_mask = drv->extended_capa_mask;
9056 capa->extended_capa_len = drv->extended_capa_len;
9057 }
851b0c55
JM
9058
9059 if ((capa->flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
9060 !drv->allow_p2p_device) {
9061 wpa_printf(MSG_DEBUG, "nl80211: Do not indicate P2P_DEVICE support (p2p_device=1 driver param not specified)");
9062 capa->flags &= ~WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
9063 }
9064
65d645ce
AS
9065 if (drv->dfs_vendor_cmd_avail == 1) {
9066 msg = nlmsg_alloc();
9067 if (!msg)
9068 return -ENOMEM;
9069
9070 nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
9071
9072 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9073 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
9074 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9075 QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY);
9076
9077 ret = send_and_recv_msgs(drv, msg, dfs_info_handler,
9078 &dfs_capability);
9079 if (!ret) {
9080 if (dfs_capability)
9081 capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
9082 }
9083 }
9084
9085 return ret;
9086
9087 nla_put_failure:
9088 nlmsg_free(msg);
9089 return -ENOBUFS;
3f5285e8
JM
9090}
9091
9092
9093static int wpa_driver_nl80211_set_operstate(void *priv, int state)
9094{
a2e40bb6
FF
9095 struct i802_bss *bss = priv;
9096 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 9097
90a545cc
JM
9098 wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
9099 bss->ifname, drv->operstate, state,
9100 state ? "UP" : "DORMANT");
3f5285e8 9101 drv->operstate = state;
36d84860 9102 return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
e2d02c29 9103 state ? IF_OPER_UP : IF_OPER_DORMANT);
3f5285e8
JM
9104}
9105
01652550
JM
9106
9107static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
9108{
a2e40bb6
FF
9109 struct i802_bss *bss = priv;
9110 struct wpa_driver_nl80211_data *drv = bss->drv;
01652550
JM
9111 struct nl_msg *msg;
9112 struct nl80211_sta_flag_update upd;
2eef5177
JM
9113 int ret = -ENOBUFS;
9114
9115 if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
9116 wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
9117 return 0;
9118 }
01652550 9119
1ba51ec0
JM
9120 wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
9121 MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
9122
01652550
JM
9123 msg = nlmsg_alloc();
9124 if (!msg)
9125 return -ENOMEM;
9126
9fb04070 9127 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
01652550
JM
9128
9129 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 9130 if_nametoindex(bss->ifname));
01652550
JM
9131 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
9132
9133 os_memset(&upd, 0, sizeof(upd));
9134 upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
9135 if (authorized)
9136 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
9137 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
9138
2eef5177
JM
9139 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9140 msg = NULL;
9141 if (!ret)
9142 return 0;
01652550 9143 nla_put_failure:
5883168a 9144 nlmsg_free(msg);
2eef5177
JM
9145 wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
9146 ret, strerror(-ret));
9147 return ret;
01652550
JM
9148}
9149
3f5285e8 9150
f07ead6a
JM
9151/* Set kernel driver on given frequency (MHz) */
9152static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
c5121837 9153{
f07ead6a 9154 struct i802_bss *bss = priv;
13a524a3 9155 return nl80211_set_channel(bss, freq, 0);
c5121837
JM
9156}
9157
f7b3920c 9158
c5121837
JM
9159static inline int min_int(int a, int b)
9160{
9161 if (a < b)
9162 return a;
9163 return b;
9164}
9165
9166
9167static int get_key_handler(struct nl_msg *msg, void *arg)
9168{
9169 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9170 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9171
9172 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9173 genlmsg_attrlen(gnlh, 0), NULL);
9174
9175 /*
9176 * TODO: validate the key index and mac address!
9177 * Otherwise, there's a race condition as soon as
9178 * the kernel starts sending key notifications.
9179 */
9180
9181 if (tb[NL80211_ATTR_KEY_SEQ])
9182 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
9183 min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
9184 return NL_SKIP;
9185}
9186
9187
9188static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
9189 int idx, u8 *seq)
9190{
a2e40bb6
FF
9191 struct i802_bss *bss = priv;
9192 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9193 struct nl_msg *msg;
9194
9195 msg = nlmsg_alloc();
9196 if (!msg)
9197 return -ENOMEM;
9198
9fb04070 9199 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_KEY);
c5121837
JM
9200
9201 if (addr)
9202 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
9203 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
9204 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
9205
9206 memset(seq, 0, 6);
9207
9208 return send_and_recv_msgs(drv, msg, get_key_handler, seq);
9209 nla_put_failure:
9e088e74 9210 nlmsg_free(msg);
c5121837
JM
9211 return -ENOBUFS;
9212}
9213
9214
c5121837
JM
9215static int i802_set_rts(void *priv, int rts)
9216{
a2e40bb6
FF
9217 struct i802_bss *bss = priv;
9218 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
9219 struct nl_msg *msg;
9220 int ret = -ENOBUFS;
9221 u32 val;
c5121837 9222
ad649451
JM
9223 msg = nlmsg_alloc();
9224 if (!msg)
9225 return -ENOMEM;
c5121837 9226
ad649451
JM
9227 if (rts >= 2347)
9228 val = (u32) -1;
9229 else
9230 val = rts;
c5121837 9231
9fb04070 9232 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
ad649451
JM
9233 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9234 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
9235
9236 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 9237 msg = NULL;
ad649451
JM
9238 if (!ret)
9239 return 0;
9240nla_put_failure:
5883168a 9241 nlmsg_free(msg);
ad649451
JM
9242 wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
9243 "%d (%s)", rts, ret, strerror(-ret));
9244 return ret;
c5121837
JM
9245}
9246
9247
9248static int i802_set_frag(void *priv, int frag)
9249{
a2e40bb6
FF
9250 struct i802_bss *bss = priv;
9251 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
9252 struct nl_msg *msg;
9253 int ret = -ENOBUFS;
9254 u32 val;
c5121837 9255
ad649451
JM
9256 msg = nlmsg_alloc();
9257 if (!msg)
9258 return -ENOMEM;
c5121837 9259
ad649451
JM
9260 if (frag >= 2346)
9261 val = (u32) -1;
9262 else
9263 val = frag;
c5121837 9264
9fb04070 9265 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
ad649451
JM
9266 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9267 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
9268
9269 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 9270 msg = NULL;
ad649451
JM
9271 if (!ret)
9272 return 0;
9273nla_put_failure:
5883168a 9274 nlmsg_free(msg);
ad649451
JM
9275 wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
9276 "%d: %d (%s)", frag, ret, strerror(-ret));
9277 return ret;
c5121837
JM
9278}
9279
9280
c5121837
JM
9281static int i802_flush(void *priv)
9282{
a2e40bb6
FF
9283 struct i802_bss *bss = priv;
9284 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 9285 struct nl_msg *msg;
82554b10 9286 int res;
c5121837
JM
9287
9288 msg = nlmsg_alloc();
9289 if (!msg)
9290 return -1;
9291
83e7bb0e
JM
9292 wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
9293 bss->ifname);
9fb04070 9294 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
c5121837
JM
9295
9296 /*
9297 * XXX: FIX! this needs to flush all VLANs too
9298 */
9299 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 9300 if_nametoindex(bss->ifname));
c5121837 9301
82554b10
JM
9302 res = send_and_recv_msgs(drv, msg, NULL, NULL);
9303 if (res) {
9304 wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
9305 "(%s)", res, strerror(-res));
9306 }
9307 return res;
c5121837 9308 nla_put_failure:
9e088e74 9309 nlmsg_free(msg);
c5121837
JM
9310 return -ENOBUFS;
9311}
9312
9313
9314static int get_sta_handler(struct nl_msg *msg, void *arg)
9315{
9316 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9317 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9318 struct hostap_sta_driver_data *data = arg;
9319 struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
9320 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
9321 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
9322 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
9323 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
9324 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
9325 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
dc7785f8 9326 [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
c5121837
JM
9327 };
9328
9329 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9330 genlmsg_attrlen(gnlh, 0), NULL);
9331
9332 /*
9333 * TODO: validate the interface and mac address!
9334 * Otherwise, there's a race condition as soon as
9335 * the kernel starts sending station notifications.
9336 */
9337
9338 if (!tb[NL80211_ATTR_STA_INFO]) {
9339 wpa_printf(MSG_DEBUG, "sta stats missing!");
9340 return NL_SKIP;
9341 }
9342 if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
9343 tb[NL80211_ATTR_STA_INFO],
9344 stats_policy)) {
9345 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
9346 return NL_SKIP;
9347 }
9348
9349 if (stats[NL80211_STA_INFO_INACTIVE_TIME])
9350 data->inactive_msec =
9351 nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
9352 if (stats[NL80211_STA_INFO_RX_BYTES])
9353 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
9354 if (stats[NL80211_STA_INFO_TX_BYTES])
9355 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
9356 if (stats[NL80211_STA_INFO_RX_PACKETS])
9357 data->rx_packets =
9358 nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
9359 if (stats[NL80211_STA_INFO_TX_PACKETS])
9360 data->tx_packets =
9361 nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
dc7785f8
YZ
9362 if (stats[NL80211_STA_INFO_TX_FAILED])
9363 data->tx_retry_failed =
9364 nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
c5121837
JM
9365
9366 return NL_SKIP;
9367}
9368
9ebce9c5
JM
9369static int i802_read_sta_data(struct i802_bss *bss,
9370 struct hostap_sta_driver_data *data,
c5121837
JM
9371 const u8 *addr)
9372{
a2e40bb6 9373 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9374 struct nl_msg *msg;
9375
9376 os_memset(data, 0, sizeof(*data));
9377 msg = nlmsg_alloc();
9378 if (!msg)
9379 return -ENOMEM;
9380
9fb04070 9381 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
c5121837
JM
9382
9383 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
a2e40bb6 9384 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
9385
9386 return send_and_recv_msgs(drv, msg, get_sta_handler, data);
9387 nla_put_failure:
9e088e74 9388 nlmsg_free(msg);
c5121837
JM
9389 return -ENOBUFS;
9390}
9391
9392
c5121837
JM
9393static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
9394 int cw_min, int cw_max, int burst_time)
9395{
a2e40bb6
FF
9396 struct i802_bss *bss = priv;
9397 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9398 struct nl_msg *msg;
9399 struct nlattr *txq, *params;
9400
9401 msg = nlmsg_alloc();
9402 if (!msg)
9403 return -1;
9404
9fb04070 9405 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
c5121837 9406
a2e40bb6 9407 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
9408
9409 txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
9410 if (!txq)
9411 goto nla_put_failure;
9412
9413 /* We are only sending parameters for a single TXQ at a time */
9414 params = nla_nest_start(msg, 1);
9415 if (!params)
9416 goto nla_put_failure;
9417
7e3c1781
JM
9418 switch (queue) {
9419 case 0:
9420 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO);
9421 break;
9422 case 1:
9423 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI);
9424 break;
9425 case 2:
9426 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE);
9427 break;
9428 case 3:
9429 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK);
9430 break;
9431 }
c5121837
JM
9432 /* Burst time is configured in units of 0.1 msec and TXOP parameter in
9433 * 32 usec, so need to convert the value here. */
9434 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
9435 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
9436 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
9437 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
9438
9439 nla_nest_end(msg, params);
9440
9441 nla_nest_end(msg, txq);
9442
9443 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
9444 return 0;
9e088e74 9445 msg = NULL;
c5121837 9446 nla_put_failure:
9e088e74 9447 nlmsg_free(msg);
c5121837
JM
9448 return -1;
9449}
9450
9451
9ebce9c5 9452static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
c5121837
JM
9453 const char *ifname, int vlan_id)
9454{
a2e40bb6 9455 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 9456 struct nl_msg *msg;
cd1d72c1 9457 int ret = -ENOBUFS;
c5121837
JM
9458
9459 msg = nlmsg_alloc();
9460 if (!msg)
9461 return -ENOMEM;
9462
bbc706a3
JM
9463 wpa_printf(MSG_DEBUG, "nl80211: %s[%d]: set_sta_vlan(" MACSTR
9464 ", ifname=%s[%d], vlan_id=%d)",
9465 bss->ifname, if_nametoindex(bss->ifname),
9466 MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
9fb04070 9467 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
c5121837
JM
9468
9469 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 9470 if_nametoindex(bss->ifname));
c5121837 9471 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1c766b09 9472 NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
c5121837
JM
9473 if_nametoindex(ifname));
9474
cd1d72c1 9475 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9e088e74 9476 msg = NULL;
cd1d72c1
JM
9477 if (ret < 0) {
9478 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
9479 MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
9480 MAC2STR(addr), ifname, vlan_id, ret,
9481 strerror(-ret));
9482 }
c5121837 9483 nla_put_failure:
9e088e74 9484 nlmsg_free(msg);
cd1d72c1 9485 return ret;
c5121837
JM
9486}
9487
fbbfcbac 9488
c5121837
JM
9489static int i802_get_inact_sec(void *priv, const u8 *addr)
9490{
9491 struct hostap_sta_driver_data data;
9492 int ret;
9493
9494 data.inactive_msec = (unsigned long) -1;
9495 ret = i802_read_sta_data(priv, &data, addr);
9496 if (ret || data.inactive_msec == (unsigned long) -1)
9497 return -1;
9498 return data.inactive_msec / 1000;
9499}
9500
9501
9502static int i802_sta_clear_stats(void *priv, const u8 *addr)
9503{
9504#if 0
9505 /* TODO */
9506#endif
9507 return 0;
9508}
9509
9510
731723a5
JM
9511static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
9512 int reason)
c5121837 9513{
a2e40bb6 9514 struct i802_bss *bss = priv;
e1bd4e19 9515 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9516 struct ieee80211_mgmt mgmt;
9517
e1bd4e19
AT
9518 if (drv->device_ap_sme)
9519 return wpa_driver_nl80211_sta_remove(bss, addr);
9520
c5121837
JM
9521 memset(&mgmt, 0, sizeof(mgmt));
9522 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
9523 WLAN_FC_STYPE_DEAUTH);
9524 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
9525 memcpy(mgmt.sa, own_addr, ETH_ALEN);
9526 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 9527 mgmt.u.deauth.reason_code = host_to_le16(reason);
a2e40bb6 9528 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 9529 IEEE80211_HDRLEN +
9ebce9c5
JM
9530 sizeof(mgmt.u.deauth), 0, 0, 0, 0,
9531 0);
c5121837
JM
9532}
9533
9534
731723a5
JM
9535static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
9536 int reason)
c5121837 9537{
a2e40bb6 9538 struct i802_bss *bss = priv;
e1bd4e19 9539 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
9540 struct ieee80211_mgmt mgmt;
9541
e1bd4e19
AT
9542 if (drv->device_ap_sme)
9543 return wpa_driver_nl80211_sta_remove(bss, addr);
9544
c5121837
JM
9545 memset(&mgmt, 0, sizeof(mgmt));
9546 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
9547 WLAN_FC_STYPE_DISASSOC);
9548 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
9549 memcpy(mgmt.sa, own_addr, ETH_ALEN);
9550 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 9551 mgmt.u.disassoc.reason_code = host_to_le16(reason);
a2e40bb6 9552 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 9553 IEEE80211_HDRLEN +
9ebce9c5
JM
9554 sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
9555 0);
c5121837
JM
9556}
9557
9558
9b4d9c8b
JM
9559static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
9560{
9561 char buf[200], *pos, *end;
9562 int i, res;
9563
9564 pos = buf;
9565 end = pos + sizeof(buf);
9566
9567 for (i = 0; i < drv->num_if_indices; i++) {
9568 if (!drv->if_indices[i])
9569 continue;
9570 res = os_snprintf(pos, end - pos, " %d", drv->if_indices[i]);
9571 if (res < 0 || res >= end - pos)
9572 break;
9573 pos += res;
9574 }
9575 *pos = '\0';
9576
9577 wpa_printf(MSG_DEBUG, "nl80211: if_indices[%d]:%s",
9578 drv->num_if_indices, buf);
9579}
9580
9581
f07ead6a
JM
9582static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9583{
9584 int i;
9585 int *old;
9586
9587 wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
9588 ifidx);
b36935be
MB
9589 if (have_ifidx(drv, ifidx)) {
9590 wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
9591 ifidx);
9592 return;
9593 }
f07ead6a
JM
9594 for (i = 0; i < drv->num_if_indices; i++) {
9595 if (drv->if_indices[i] == 0) {
9596 drv->if_indices[i] = ifidx;
9b4d9c8b 9597 dump_ifidx(drv);
f07ead6a
JM
9598 return;
9599 }
9600 }
9601
9602 if (drv->if_indices != drv->default_if_indices)
9603 old = drv->if_indices;
9604 else
9605 old = NULL;
9606
067ffa26
JM
9607 drv->if_indices = os_realloc_array(old, drv->num_if_indices + 1,
9608 sizeof(int));
f07ead6a
JM
9609 if (!drv->if_indices) {
9610 if (!old)
9611 drv->if_indices = drv->default_if_indices;
9612 else
9613 drv->if_indices = old;
9614 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
9615 "interfaces");
9616 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
9617 return;
9618 } else if (!old)
9619 os_memcpy(drv->if_indices, drv->default_if_indices,
9620 sizeof(drv->default_if_indices));
9621 drv->if_indices[drv->num_if_indices] = ifidx;
9622 drv->num_if_indices++;
9b4d9c8b 9623 dump_ifidx(drv);
f07ead6a
JM
9624}
9625
9626
9627static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9628{
9629 int i;
9630
9631 for (i = 0; i < drv->num_if_indices; i++) {
9632 if (drv->if_indices[i] == ifidx) {
9633 drv->if_indices[i] = 0;
9634 break;
9635 }
9636 }
9b4d9c8b 9637 dump_ifidx(drv);
f07ead6a
JM
9638}
9639
9640
9641static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9642{
9643 int i;
9644
9645 for (i = 0; i < drv->num_if_indices; i++)
9646 if (drv->if_indices[i] == ifidx)
9647 return 1;
9648
9649 return 0;
9650}
9651
9652
9653static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
0e80ea2c 9654 const char *bridge_ifname, char *ifname_wds)
f07ead6a
JM
9655{
9656 struct i802_bss *bss = priv;
9657 struct wpa_driver_nl80211_data *drv = bss->drv;
9658 char name[IFNAMSIZ + 1];
9659
9660 os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
69dd2967
SM
9661 if (ifname_wds)
9662 os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
9663
f07ead6a
JM
9664 wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
9665 " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
9666 if (val) {
9667 if (!if_nametoindex(name)) {
9668 if (nl80211_create_iface(drv, name,
9669 NL80211_IFTYPE_AP_VLAN,
2aec4f3c
JM
9670 bss->addr, 1, NULL, NULL, 0) <
9671 0)
f07ead6a
JM
9672 return -1;
9673 if (bridge_ifname &&
c81eff1a
BG
9674 linux_br_add_if(drv->global->ioctl_sock,
9675 bridge_ifname, name) < 0)
f07ead6a
JM
9676 return -1;
9677 }
75227f3a
JM
9678 if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
9679 wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
9680 "interface %s up", name);
9681 }
f07ead6a
JM
9682 return i802_set_sta_vlan(priv, addr, name, 0);
9683 } else {
c34e618d
FF
9684 if (bridge_ifname)
9685 linux_br_del_if(drv->global->ioctl_sock, bridge_ifname,
9686 name);
9687
f07ead6a 9688 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
d0595b25
FF
9689 nl80211_remove_iface(drv, if_nametoindex(name));
9690 return 0;
f07ead6a
JM
9691 }
9692}
9693
9694
9695static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
9696{
9697 struct wpa_driver_nl80211_data *drv = eloop_ctx;
9698 struct sockaddr_ll lladdr;
9699 unsigned char buf[3000];
9700 int len;
9701 socklen_t fromlen = sizeof(lladdr);
9702
9703 len = recvfrom(sock, buf, sizeof(buf), 0,
9704 (struct sockaddr *)&lladdr, &fromlen);
9705 if (len < 0) {
7ac3616d
JM
9706 wpa_printf(MSG_ERROR, "nl80211: EAPOL recv failed: %s",
9707 strerror(errno));
f07ead6a
JM
9708 return;
9709 }
9710
9711 if (have_ifidx(drv, lladdr.sll_ifindex))
9712 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
9713}
9714
9715
94627f6c 9716static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
e17a2477 9717 struct i802_bss *bss,
94627f6c
JM
9718 const char *brname, const char *ifname)
9719{
9720 int ifindex;
9721 char in_br[IFNAMSIZ];
9722
e17a2477 9723 os_strlcpy(bss->brname, brname, IFNAMSIZ);
94627f6c
JM
9724 ifindex = if_nametoindex(brname);
9725 if (ifindex == 0) {
9726 /*
9727 * Bridge was configured, but the bridge device does
9728 * not exist. Try to add it now.
9729 */
c81eff1a 9730 if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
94627f6c
JM
9731 wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
9732 "bridge interface %s: %s",
9733 brname, strerror(errno));
9734 return -1;
9735 }
e17a2477 9736 bss->added_bridge = 1;
94627f6c
JM
9737 add_ifidx(drv, if_nametoindex(brname));
9738 }
9739
9740 if (linux_br_get(in_br, ifname) == 0) {
9741 if (os_strcmp(in_br, brname) == 0)
9742 return 0; /* already in the bridge */
9743
9744 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
9745 "bridge %s", ifname, in_br);
c81eff1a
BG
9746 if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
9747 0) {
94627f6c
JM
9748 wpa_printf(MSG_ERROR, "nl80211: Failed to "
9749 "remove interface %s from bridge "
9750 "%s: %s",
9751 ifname, brname, strerror(errno));
9752 return -1;
9753 }
9754 }
9755
9756 wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
9757 ifname, brname);
c81eff1a 9758 if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
94627f6c
JM
9759 wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
9760 "into bridge %s: %s",
9761 ifname, brname, strerror(errno));
9762 return -1;
9763 }
e17a2477 9764 bss->added_if_into_bridge = 1;
94627f6c
JM
9765
9766 return 0;
9767}
9768
9769
92f475b4
JM
9770static void *i802_init(struct hostapd_data *hapd,
9771 struct wpa_init_params *params)
c5121837
JM
9772{
9773 struct wpa_driver_nl80211_data *drv;
a2e40bb6 9774 struct i802_bss *bss;
c5121837 9775 size_t i;
94627f6c
JM
9776 char brname[IFNAMSIZ];
9777 int ifindex, br_ifindex;
9778 int br_added = 0;
c5121837 9779
0d547d5f
JM
9780 bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
9781 params->global_priv, 1,
9782 params->bssid);
a2e40bb6 9783 if (bss == NULL)
c5121837 9784 return NULL;
c5121837 9785
a2e40bb6 9786 drv = bss->drv;
7635bfb0 9787
94627f6c
JM
9788 if (linux_br_get(brname, params->ifname) == 0) {
9789 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
9790 params->ifname, brname);
9791 br_ifindex = if_nametoindex(brname);
9792 } else {
9793 brname[0] = '\0';
9794 br_ifindex = 0;
9795 }
9796
92f475b4 9797 for (i = 0; i < params->num_bridge; i++) {
94627f6c
JM
9798 if (params->bridge[i]) {
9799 ifindex = if_nametoindex(params->bridge[i]);
9800 if (ifindex)
9801 add_ifidx(drv, ifindex);
9802 if (ifindex == br_ifindex)
9803 br_added = 1;
9804 }
c5121837 9805 }
94627f6c
JM
9806 if (!br_added && br_ifindex &&
9807 (params->num_bridge == 0 || !params->bridge[0]))
9808 add_ifidx(drv, br_ifindex);
c5121837 9809
ad1e68e6
JM
9810 /* start listening for EAPOL on the default AP interface */
9811 add_ifidx(drv, drv->ifindex);
9812
94627f6c 9813 if (params->num_bridge && params->bridge[0] &&
e17a2477 9814 i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
94627f6c
JM
9815 goto failed;
9816
ad1e68e6
JM
9817 drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
9818 if (drv->eapol_sock < 0) {
7ac3616d
JM
9819 wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
9820 strerror(errno));
bbaf0837 9821 goto failed;
ad1e68e6
JM
9822 }
9823
9824 if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
9825 {
7ac3616d 9826 wpa_printf(MSG_INFO, "nl80211: Could not register read socket for eapol");
c5121837 9827 goto failed;
ad1e68e6
JM
9828 }
9829
c81eff1a
BG
9830 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
9831 params->own_addr))
bbaf0837 9832 goto failed;
c5121837 9833
341eebee
JB
9834 memcpy(bss->addr, params->own_addr, ETH_ALEN);
9835
a2e40bb6 9836 return bss;
c5121837
JM
9837
9838failed:
7635bfb0 9839 wpa_driver_nl80211_deinit(bss);
bbaf0837
JM
9840 return NULL;
9841}
c5121837 9842
c5121837 9843
bbaf0837
JM
9844static void i802_deinit(void *priv)
9845{
9ebce9c5
JM
9846 struct i802_bss *bss = priv;
9847 wpa_driver_nl80211_deinit(bss);
c5121837
JM
9848}
9849
c5121837 9850
22a7c9d7
JM
9851static enum nl80211_iftype wpa_driver_nl80211_if_type(
9852 enum wpa_driver_if_type type)
9853{
9854 switch (type) {
9855 case WPA_IF_STATION:
9f51b113 9856 return NL80211_IFTYPE_STATION;
75bde05d
JM
9857 case WPA_IF_P2P_CLIENT:
9858 case WPA_IF_P2P_GROUP:
9f51b113 9859 return NL80211_IFTYPE_P2P_CLIENT;
22a7c9d7
JM
9860 case WPA_IF_AP_VLAN:
9861 return NL80211_IFTYPE_AP_VLAN;
9862 case WPA_IF_AP_BSS:
9863 return NL80211_IFTYPE_AP;
9f51b113
JB
9864 case WPA_IF_P2P_GO:
9865 return NL80211_IFTYPE_P2P_GO;
7aad838c
NS
9866 case WPA_IF_P2P_DEVICE:
9867 return NL80211_IFTYPE_P2P_DEVICE;
22a7c9d7
JM
9868 }
9869 return -1;
9870}
9871
9872
482856c8
JM
9873#ifdef CONFIG_P2P
9874
f2ed8023
JM
9875static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
9876{
9877 struct wpa_driver_nl80211_data *drv;
9878 dl_list_for_each(drv, &global->interfaces,
9879 struct wpa_driver_nl80211_data, list) {
834ee56f 9880 if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
f2ed8023
JM
9881 return 1;
9882 }
9883 return 0;
9884}
9885
9886
9887static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data *drv,
9888 u8 *new_addr)
9889{
9890 unsigned int idx;
9891
9892 if (!drv->global)
9893 return -1;
9894
834ee56f 9895 os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
f2ed8023 9896 for (idx = 0; idx < 64; idx++) {
834ee56f 9897 new_addr[0] = drv->first_bss->addr[0] | 0x02;
f2ed8023
JM
9898 new_addr[0] ^= idx << 2;
9899 if (!nl80211_addr_in_use(drv->global, new_addr))
9900 break;
9901 }
9902 if (idx == 64)
9903 return -1;
9904
9905 wpa_printf(MSG_DEBUG, "nl80211: Assigned new P2P Interface Address "
9906 MACSTR, MAC2STR(new_addr));
9907
9908 return 0;
9909}
9910
482856c8
JM
9911#endif /* CONFIG_P2P */
9912
f2ed8023 9913
f632e483
AS
9914struct wdev_info {
9915 u64 wdev_id;
9916 int wdev_id_set;
9917 u8 macaddr[ETH_ALEN];
9918};
9919
9920static int nl80211_wdev_handler(struct nl_msg *msg, void *arg)
e472e1b4
AS
9921{
9922 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9923 struct nlattr *tb[NL80211_ATTR_MAX + 1];
f632e483 9924 struct wdev_info *wi = arg;
e472e1b4
AS
9925
9926 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9927 genlmsg_attrlen(gnlh, 0), NULL);
9928 if (tb[NL80211_ATTR_WDEV]) {
f632e483
AS
9929 wi->wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
9930 wi->wdev_id_set = 1;
e472e1b4
AS
9931 }
9932
9933 if (tb[NL80211_ATTR_MAC])
f632e483 9934 os_memcpy(wi->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
e472e1b4
AS
9935 ETH_ALEN);
9936
9937 return NL_SKIP;
9938}
9939
9940
7ab68865 9941static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
8043e725 9942 const char *ifname, const u8 *addr,
f3585c8a 9943 void *bss_ctx, void **drv_priv,
e17a2477 9944 char *force_ifname, u8 *if_addr,
2aec4f3c 9945 const char *bridge, int use_existing)
22a7c9d7 9946{
e472e1b4 9947 enum nl80211_iftype nlmode;
a2e40bb6
FF
9948 struct i802_bss *bss = priv;
9949 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7 9950 int ifidx;
2aec4f3c 9951 int added = 1;
22a7c9d7 9952
f3585c8a
JM
9953 if (addr)
9954 os_memcpy(if_addr, addr, ETH_ALEN);
e472e1b4
AS
9955 nlmode = wpa_driver_nl80211_if_type(type);
9956 if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
f632e483
AS
9957 struct wdev_info p2pdev_info;
9958
9959 os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
e472e1b4 9960 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
f632e483 9961 0, nl80211_wdev_handler,
2aec4f3c 9962 &p2pdev_info, use_existing);
f632e483 9963 if (!p2pdev_info.wdev_id_set || ifidx != 0) {
e472e1b4
AS
9964 wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
9965 ifname);
e472e1b4
AS
9966 return -1;
9967 }
f632e483
AS
9968
9969 drv->global->if_add_wdevid = p2pdev_info.wdev_id;
9970 drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
9971 if (!is_zero_ether_addr(p2pdev_info.macaddr))
9972 os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
9973 wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
9974 ifname,
9975 (long long unsigned int) p2pdev_info.wdev_id);
e472e1b4
AS
9976 } else {
9977 ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
2aec4f3c
JM
9978 0, NULL, NULL, use_existing);
9979 if (use_existing && ifidx == -ENFILE) {
9980 added = 0;
9981 ifidx = if_nametoindex(ifname);
9982 } else if (ifidx < 0) {
e472e1b4
AS
9983 return -1;
9984 }
22a7c9d7
JM
9985 }
9986
ab7a1add
AS
9987 if (!addr) {
9988 if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
9989 os_memcpy(if_addr, bss->addr, ETH_ALEN);
9990 else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
9991 bss->ifname, if_addr) < 0) {
2aec4f3c
JM
9992 if (added)
9993 nl80211_remove_iface(drv, ifidx);
ab7a1add
AS
9994 return -1;
9995 }
c55f774d
JM
9996 }
9997
9998#ifdef CONFIG_P2P
9999 if (!addr &&
10000 (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
10001 type == WPA_IF_P2P_GO)) {
10002 /* Enforce unique P2P Interface Address */
ab7a1add 10003 u8 new_addr[ETH_ALEN];
c55f774d 10004
ab7a1add 10005 if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
c81eff1a 10006 new_addr) < 0) {
c55f774d
JM
10007 nl80211_remove_iface(drv, ifidx);
10008 return -1;
10009 }
f608081c 10010 if (nl80211_addr_in_use(drv->global, new_addr)) {
c55f774d
JM
10011 wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
10012 "for P2P group interface");
f2ed8023 10013 if (nl80211_p2p_interface_addr(drv, new_addr) < 0) {
c55f774d
JM
10014 nl80211_remove_iface(drv, ifidx);
10015 return -1;
10016 }
c81eff1a 10017 if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
c55f774d
JM
10018 new_addr) < 0) {
10019 nl80211_remove_iface(drv, ifidx);
10020 return -1;
10021 }
c55f774d 10022 }
f67eeb5c 10023 os_memcpy(if_addr, new_addr, ETH_ALEN);
c55f774d
JM
10024 }
10025#endif /* CONFIG_P2P */
f3585c8a 10026
22a7c9d7 10027 if (type == WPA_IF_AP_BSS) {
f5eb9da3
JM
10028 struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
10029 if (new_bss == NULL) {
2aec4f3c
JM
10030 if (added)
10031 nl80211_remove_iface(drv, ifidx);
f5eb9da3
JM
10032 return -1;
10033 }
10034
10035 if (bridge &&
10036 i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
10037 wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
10038 "interface %s to a bridge %s",
10039 ifname, bridge);
2aec4f3c
JM
10040 if (added)
10041 nl80211_remove_iface(drv, ifidx);
f5eb9da3
JM
10042 os_free(new_bss);
10043 return -1;
10044 }
10045
c81eff1a
BG
10046 if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
10047 {
34f2f814 10048 nl80211_remove_iface(drv, ifidx);
07179987 10049 os_free(new_bss);
22a7c9d7
JM
10050 return -1;
10051 }
a2e40bb6 10052 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
341eebee 10053 os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
a2e40bb6
FF
10054 new_bss->ifindex = ifidx;
10055 new_bss->drv = drv;
834ee56f
KP
10056 new_bss->next = drv->first_bss->next;
10057 new_bss->freq = drv->first_bss->freq;
a5e1eb20 10058 new_bss->ctx = bss_ctx;
2aec4f3c 10059 new_bss->added_if = added;
834ee56f 10060 drv->first_bss->next = new_bss;
a2e40bb6
FF
10061 if (drv_priv)
10062 *drv_priv = new_bss;
cc7a48d1 10063 nl80211_init_bss(new_bss);
3dd1d890
YAP
10064
10065 /* Subscribe management frames for this WPA_IF_AP_BSS */
10066 if (nl80211_setup_ap(new_bss))
10067 return -1;
22a7c9d7 10068 }
22a7c9d7 10069
ff6a158b
JM
10070 if (drv->global)
10071 drv->global->if_add_ifindex = ifidx;
10072
b36935be
MB
10073 if (ifidx > 0)
10074 add_ifidx(drv, ifidx);
10075
22a7c9d7
JM
10076 return 0;
10077}
10078
10079
9ebce9c5 10080static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
22a7c9d7
JM
10081 enum wpa_driver_if_type type,
10082 const char *ifname)
10083{
a2e40bb6 10084 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7
JM
10085 int ifindex = if_nametoindex(ifname);
10086
2aec4f3c
JM
10087 wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d",
10088 __func__, type, ifname, ifindex, bss->added_if);
158b090c 10089 if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex))
2b72df63 10090 nl80211_remove_iface(drv, ifindex);
b36935be
MB
10091 else if (ifindex > 0 && !bss->added_if)
10092 del_ifidx(drv, ifindex);
c34e618d 10093
c34e618d
FF
10094 if (type != WPA_IF_AP_BSS)
10095 return 0;
10096
e17a2477 10097 if (bss->added_if_into_bridge) {
c81eff1a
BG
10098 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
10099 bss->ifname) < 0)
e17a2477
JM
10100 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
10101 "interface %s from bridge %s: %s",
10102 bss->ifname, bss->brname, strerror(errno));
10103 }
10104 if (bss->added_bridge) {
c81eff1a 10105 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
e17a2477
JM
10106 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
10107 "bridge %s: %s",
10108 bss->brname, strerror(errno));
10109 }
a2e40bb6 10110
834ee56f 10111 if (bss != drv->first_bss) {
8546ea19 10112 struct i802_bss *tbss;
a2e40bb6 10113
2aec4f3c 10114 wpa_printf(MSG_DEBUG, "nl80211: Not the first BSS - remove it");
834ee56f 10115 for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
8546ea19
JM
10116 if (tbss->next == bss) {
10117 tbss->next = bss->next;
3dd1d890
YAP
10118 /* Unsubscribe management frames */
10119 nl80211_teardown_ap(bss);
cc7a48d1 10120 nl80211_destroy_bss(bss);
5c9da160
MB
10121 if (!bss->added_if)
10122 i802_set_iface_flags(bss, 0);
8546ea19
JM
10123 os_free(bss);
10124 bss = NULL;
10125 break;
10126 }
22a7c9d7 10127 }
8546ea19
JM
10128 if (bss)
10129 wpa_printf(MSG_INFO, "nl80211: %s - could not find "
10130 "BSS %p in the list", __func__, bss);
390e489c 10131 } else {
2aec4f3c 10132 wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
390e489c 10133 nl80211_teardown_ap(bss);
2aec4f3c
JM
10134 if (!bss->added_if && !drv->first_bss->next)
10135 wpa_driver_nl80211_del_beacon(drv);
390e489c 10136 nl80211_destroy_bss(bss);
2aec4f3c
JM
10137 if (!bss->added_if)
10138 i802_set_iface_flags(bss, 0);
390e489c
KP
10139 if (drv->first_bss->next) {
10140 drv->first_bss = drv->first_bss->next;
10141 drv->ctx = drv->first_bss->ctx;
10142 os_free(bss);
10143 } else {
10144 wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
10145 }
22a7c9d7 10146 }
22a7c9d7
JM
10147
10148 return 0;
10149}
10150
10151
55777702
JM
10152static int cookie_handler(struct nl_msg *msg, void *arg)
10153{
10154 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10155 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10156 u64 *cookie = arg;
10157 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10158 genlmsg_attrlen(gnlh, 0), NULL);
10159 if (tb[NL80211_ATTR_COOKIE])
10160 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
10161 return NL_SKIP;
10162}
10163
10164
88df0ef7 10165static int nl80211_send_frame_cmd(struct i802_bss *bss,
5dfca53f
JB
10166 unsigned int freq, unsigned int wait,
10167 const u8 *buf, size_t buf_len,
88df0ef7
JB
10168 u64 *cookie_out, int no_cck, int no_ack,
10169 int offchanok)
9884f9cc 10170{
88df0ef7 10171 struct wpa_driver_nl80211_data *drv = bss->drv;
9884f9cc
JB
10172 struct nl_msg *msg;
10173 u64 cookie;
10174 int ret = -1;
10175
10176 msg = nlmsg_alloc();
10177 if (!msg)
10178 return -1;
10179
cc2ada86 10180 wpa_printf(MSG_MSGDUMP, "nl80211: CMD_FRAME freq=%u wait=%u no_cck=%d "
2e3e4566
JM
10181 "no_ack=%d offchanok=%d",
10182 freq, wait, no_cck, no_ack, offchanok);
c91f796f 10183 wpa_hexdump(MSG_MSGDUMP, "CMD_FRAME", buf, buf_len);
9fb04070 10184 nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME);
9884f9cc 10185
f632e483 10186 if (nl80211_set_iface_id(msg, bss) < 0)
d3aaef80 10187 goto nla_put_failure;
c91f796f
NC
10188 if (freq)
10189 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
9db931ed
JM
10190 if (wait)
10191 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
64abb725
JM
10192 if (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
10193 drv->test_use_roc_tx))
88df0ef7 10194 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
b106173a
JM
10195 if (no_cck)
10196 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
ddc53271
JM
10197 if (no_ack)
10198 NLA_PUT_FLAG(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK);
970fa12e 10199
9884f9cc
JB
10200 NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
10201
10202 cookie = 0;
10203 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
10204 msg = NULL;
10205 if (ret) {
10206 wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
a05225c8
JM
10207 "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
10208 freq, wait);
9884f9cc
JB
10209 goto nla_put_failure;
10210 }
cc2ada86 10211 wpa_printf(MSG_MSGDUMP, "nl80211: Frame TX command accepted%s; "
ddc53271
JM
10212 "cookie 0x%llx", no_ack ? " (no ACK)" : "",
10213 (long long unsigned int) cookie);
9884f9cc
JB
10214
10215 if (cookie_out)
ddc53271 10216 *cookie_out = no_ack ? (u64) -1 : cookie;
9884f9cc
JB
10217
10218nla_put_failure:
10219 nlmsg_free(msg);
10220 return ret;
10221}
10222
10223
9ebce9c5
JM
10224static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
10225 unsigned int freq,
190b9062 10226 unsigned int wait_time,
58f6fbe0
JM
10227 const u8 *dst, const u8 *src,
10228 const u8 *bssid,
b106173a
JM
10229 const u8 *data, size_t data_len,
10230 int no_cck)
58f6fbe0 10231{
a2e40bb6 10232 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0 10233 int ret = -1;
58f6fbe0
JM
10234 u8 *buf;
10235 struct ieee80211_hdr *hdr;
58f6fbe0 10236
5dfca53f 10237 wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
55231068
JM
10238 "freq=%u MHz wait=%d ms no_cck=%d)",
10239 drv->ifindex, freq, wait_time, no_cck);
58f6fbe0
JM
10240
10241 buf = os_zalloc(24 + data_len);
10242 if (buf == NULL)
10243 return ret;
10244 os_memcpy(buf + 24, data, data_len);
10245 hdr = (struct ieee80211_hdr *) buf;
10246 hdr->frame_control =
10247 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
10248 os_memcpy(hdr->addr1, dst, ETH_ALEN);
10249 os_memcpy(hdr->addr2, src, ETH_ALEN);
10250 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
10251
f78f2785
JM
10252 if (is_ap_interface(drv->nlmode) &&
10253 (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
10254 (int) freq == bss->freq || drv->device_ap_sme ||
10255 !drv->use_monitor))
9ebce9c5
JM
10256 ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
10257 0, freq, no_cck, 1,
10258 wait_time);
9884f9cc 10259 else
88df0ef7 10260 ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
5dfca53f 10261 24 + data_len,
b106173a 10262 &drv->send_action_cookie,
88df0ef7 10263 no_cck, 0, 1);
58f6fbe0 10264
f8bf1421 10265 os_free(buf);
58f6fbe0
JM
10266 return ret;
10267}
10268
10269
5dfca53f
JB
10270static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
10271{
10272 struct i802_bss *bss = priv;
10273 struct wpa_driver_nl80211_data *drv = bss->drv;
10274 struct nl_msg *msg;
10275 int ret;
10276
10277 msg = nlmsg_alloc();
10278 if (!msg)
10279 return;
10280
316a9e4d
JM
10281 wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
10282 (long long unsigned int) drv->send_action_cookie);
9fb04070 10283 nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME_WAIT_CANCEL);
5dfca53f 10284
7940c790
AS
10285 if (nl80211_set_iface_id(msg, bss) < 0)
10286 goto nla_put_failure;
5dfca53f
JB
10287 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie);
10288
10289 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10290 msg = NULL;
10291 if (ret)
10292 wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
10293 "(%s)", ret, strerror(-ret));
10294
10295 nla_put_failure:
10296 nlmsg_free(msg);
10297}
10298
10299
55777702
JM
10300static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
10301 unsigned int duration)
10302{
a2e40bb6
FF
10303 struct i802_bss *bss = priv;
10304 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
10305 struct nl_msg *msg;
10306 int ret;
10307 u64 cookie;
10308
10309 msg = nlmsg_alloc();
10310 if (!msg)
10311 return -1;
10312
9fb04070 10313 nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL);
55777702 10314
f632e483 10315 if (nl80211_set_iface_id(msg, bss) < 0)
d3aaef80
DS
10316 goto nla_put_failure;
10317
55777702
JM
10318 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
10319 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
10320
10321 cookie = 0;
10322 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
5883168a 10323 msg = NULL;
55777702
JM
10324 if (ret == 0) {
10325 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
10326 "0x%llx for freq=%u MHz duration=%u",
10327 (long long unsigned int) cookie, freq, duration);
10328 drv->remain_on_chan_cookie = cookie;
531f0331 10329 drv->pending_remain_on_chan = 1;
55777702
JM
10330 return 0;
10331 }
10332 wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
15ed5535
JM
10333 "(freq=%d duration=%u): %d (%s)",
10334 freq, duration, ret, strerror(-ret));
55777702 10335nla_put_failure:
5883168a 10336 nlmsg_free(msg);
55777702
JM
10337 return -1;
10338}
10339
10340
10341static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
10342{
a2e40bb6
FF
10343 struct i802_bss *bss = priv;
10344 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
10345 struct nl_msg *msg;
10346 int ret;
10347
10348 if (!drv->pending_remain_on_chan) {
10349 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
10350 "to cancel");
10351 return -1;
10352 }
10353
10354 wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
10355 "0x%llx",
10356 (long long unsigned int) drv->remain_on_chan_cookie);
10357
10358 msg = nlmsg_alloc();
10359 if (!msg)
10360 return -1;
10361
9fb04070 10362 nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
55777702 10363
f632e483 10364 if (nl80211_set_iface_id(msg, bss) < 0)
d3aaef80
DS
10365 goto nla_put_failure;
10366
55777702
JM
10367 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
10368
10369 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5883168a 10370 msg = NULL;
55777702
JM
10371 if (ret == 0)
10372 return 0;
10373 wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
10374 "%d (%s)", ret, strerror(-ret));
10375nla_put_failure:
5883168a 10376 nlmsg_free(msg);
55777702
JM
10377 return -1;
10378}
10379
10380
9ebce9c5 10381static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
504e905c 10382{
a2e40bb6 10383 struct wpa_driver_nl80211_data *drv = bss->drv;
504e905c 10384
5582a5d1 10385 if (!report) {
0d891981
JM
10386 if (bss->nl_preq && drv->device_ap_sme &&
10387 is_ap_interface(drv->nlmode)) {
10388 /*
10389 * Do not disable Probe Request reporting that was
10390 * enabled in nl80211_setup_ap().
10391 */
10392 wpa_printf(MSG_DEBUG, "nl80211: Skip disabling of "
10393 "Probe Request reporting nl_preq=%p while "
10394 "in AP mode", bss->nl_preq);
10395 } else if (bss->nl_preq) {
36488c05
JM
10396 wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
10397 "reporting nl_preq=%p", bss->nl_preq);
5f65e9f7 10398 nl80211_destroy_eloop_handle(&bss->nl_preq);
5582a5d1
JB
10399 }
10400 return 0;
10401 }
10402
481234cf 10403 if (bss->nl_preq) {
5582a5d1 10404 wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
36488c05 10405 "already on! nl_preq=%p", bss->nl_preq);
5582a5d1
JB
10406 return 0;
10407 }
10408
481234cf
JM
10409 bss->nl_preq = nl_create_handle(drv->global->nl_cb, "preq");
10410 if (bss->nl_preq == NULL)
5582a5d1 10411 return -1;
36488c05
JM
10412 wpa_printf(MSG_DEBUG, "nl80211: Enable Probe Request "
10413 "reporting nl_preq=%p", bss->nl_preq);
5582a5d1 10414
481234cf 10415 if (nl80211_register_frame(bss, bss->nl_preq,
5582a5d1
JB
10416 (WLAN_FC_TYPE_MGMT << 2) |
10417 (WLAN_FC_STYPE_PROBE_REQ << 4),
a92dfde8
JB
10418 NULL, 0) < 0)
10419 goto out_err;
5582a5d1 10420
5f65e9f7
JB
10421 nl80211_register_eloop_read(&bss->nl_preq,
10422 wpa_driver_nl80211_event_receive,
10423 bss->nl_cb);
5582a5d1 10424
504e905c 10425 return 0;
5582a5d1 10426
a92dfde8 10427 out_err:
221a59c9 10428 nl_destroy_handles(&bss->nl_preq);
5582a5d1 10429 return -1;
504e905c
JM
10430}
10431
10432
4e5cb1a3
JM
10433static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
10434 int ifindex, int disabled)
10435{
10436 struct nl_msg *msg;
10437 struct nlattr *bands, *band;
10438 int ret;
10439
10440 msg = nlmsg_alloc();
10441 if (!msg)
10442 return -1;
10443
9fb04070 10444 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_TX_BITRATE_MASK);
4e5cb1a3
JM
10445 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
10446
10447 bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
10448 if (!bands)
10449 goto nla_put_failure;
10450
10451 /*
10452 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
10453 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
10454 * rates. All 5 GHz rates are left enabled.
10455 */
10456 band = nla_nest_start(msg, NL80211_BAND_2GHZ);
10457 if (!band)
10458 goto nla_put_failure;
1dea5882
JM
10459 if (disabled) {
10460 NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
10461 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
10462 }
4e5cb1a3
JM
10463 nla_nest_end(msg, band);
10464
10465 nla_nest_end(msg, bands);
10466
10467 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10468 msg = NULL;
10469 if (ret) {
10470 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
10471 "(%s)", ret, strerror(-ret));
1d0c6fb1
JM
10472 } else
10473 drv->disabled_11b_rates = disabled;
4e5cb1a3
JM
10474
10475 return ret;
10476
10477nla_put_failure:
10478 nlmsg_free(msg);
10479 return -1;
10480}
10481
10482
af473088
JM
10483static int wpa_driver_nl80211_deinit_ap(void *priv)
10484{
a2e40bb6
FF
10485 struct i802_bss *bss = priv;
10486 struct wpa_driver_nl80211_data *drv = bss->drv;
b1f625e0 10487 if (!is_ap_interface(drv->nlmode))
af473088
JM
10488 return -1;
10489 wpa_driver_nl80211_del_beacon(drv);
60b13c20
IP
10490
10491 /*
10492 * If the P2P GO interface was dynamically added, then it is
10493 * possible that the interface change to station is not possible.
10494 */
10495 if (drv->nlmode == NL80211_IFTYPE_P2P_GO && bss->if_dynamic)
10496 return 0;
10497
b1f625e0 10498 return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
af473088
JM
10499}
10500
10501
695c7038
SW
10502static int wpa_driver_nl80211_stop_ap(void *priv)
10503{
10504 struct i802_bss *bss = priv;
10505 struct wpa_driver_nl80211_data *drv = bss->drv;
10506 if (!is_ap_interface(drv->nlmode))
10507 return -1;
10508 wpa_driver_nl80211_del_beacon(drv);
10509 bss->beacon_set = 0;
10510 return 0;
10511}
10512
10513
3c29244e
EP
10514static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
10515{
10516 struct i802_bss *bss = priv;
10517 struct wpa_driver_nl80211_data *drv = bss->drv;
10518 if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
10519 return -1;
60b13c20
IP
10520
10521 /*
10522 * If the P2P Client interface was dynamically added, then it is
10523 * possible that the interface change to station is not possible.
10524 */
10525 if (bss->if_dynamic)
10526 return 0;
10527
3c29244e
EP
10528 return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
10529}
10530
10531
207ef3fb
JM
10532static void wpa_driver_nl80211_resume(void *priv)
10533{
a2e40bb6 10534 struct i802_bss *bss = priv;
91724d6f
AS
10535
10536 if (i802_set_iface_flags(bss, 1))
10537 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on resume event");
207ef3fb
JM
10538}
10539
10540
7b90c16a
JM
10541static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
10542 const u8 *ies, size_t ies_len)
10543{
10544 struct i802_bss *bss = priv;
10545 struct wpa_driver_nl80211_data *drv = bss->drv;
10546 int ret;
10547 u8 *data, *pos;
10548 size_t data_len;
341eebee 10549 const u8 *own_addr = bss->addr;
7b90c16a
JM
10550
10551 if (action != 1) {
10552 wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
10553 "action %d", action);
10554 return -1;
10555 }
10556
10557 /*
10558 * Action frame payload:
10559 * Category[1] = 6 (Fast BSS Transition)
10560 * Action[1] = 1 (Fast BSS Transition Request)
10561 * STA Address
10562 * Target AP Address
10563 * FT IEs
10564 */
10565
73fc617d
JM
10566 data_len = 2 + 2 * ETH_ALEN + ies_len;
10567 data = os_malloc(data_len);
7b90c16a
JM
10568 if (data == NULL)
10569 return -1;
10570 pos = data;
10571 *pos++ = 0x06; /* FT Action category */
10572 *pos++ = action;
10573 os_memcpy(pos, own_addr, ETH_ALEN);
10574 pos += ETH_ALEN;
10575 os_memcpy(pos, target_ap, ETH_ALEN);
10576 pos += ETH_ALEN;
10577 os_memcpy(pos, ies, ies_len);
10578
190b9062
JB
10579 ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, 0,
10580 drv->bssid, own_addr, drv->bssid,
b106173a 10581 data, data_len, 0);
7b90c16a
JM
10582 os_free(data);
10583
10584 return ret;
10585}
10586
10587
b625473c
JM
10588static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
10589{
10590 struct i802_bss *bss = priv;
10591 struct wpa_driver_nl80211_data *drv = bss->drv;
8970bae8
JB
10592 struct nl_msg *msg;
10593 struct nlattr *cqm;
f0494d0f 10594 int ret = -1;
b625473c
JM
10595
10596 wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
10597 "hysteresis=%d", threshold, hysteresis);
10598
10599 msg = nlmsg_alloc();
10600 if (!msg)
10601 return -1;
10602
9fb04070 10603 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_CQM);
b625473c
JM
10604
10605 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
10606
8970bae8 10607 cqm = nla_nest_start(msg, NL80211_ATTR_CQM);
b625473c 10608 if (cqm == NULL)
21270bb4 10609 goto nla_put_failure;
b625473c 10610
8970bae8
JB
10611 NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
10612 NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
10613 nla_nest_end(msg, cqm);
21270bb4 10614
f0494d0f 10615 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
b625473c
JM
10616 msg = NULL;
10617
10618nla_put_failure:
b625473c 10619 nlmsg_free(msg);
f0494d0f 10620 return ret;
b625473c
JM
10621}
10622
10623
2cc8d8f4
AO
10624static int get_channel_width(struct nl_msg *msg, void *arg)
10625{
10626 struct nlattr *tb[NL80211_ATTR_MAX + 1];
10627 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10628 struct wpa_signal_info *sig_change = arg;
10629
10630 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10631 genlmsg_attrlen(gnlh, 0), NULL);
10632
10633 sig_change->center_frq1 = -1;
10634 sig_change->center_frq2 = -1;
10635 sig_change->chanwidth = CHAN_WIDTH_UNKNOWN;
10636
10637 if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
10638 sig_change->chanwidth = convert2width(
10639 nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
10640 if (tb[NL80211_ATTR_CENTER_FREQ1])
10641 sig_change->center_frq1 =
10642 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
10643 if (tb[NL80211_ATTR_CENTER_FREQ2])
10644 sig_change->center_frq2 =
10645 nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
10646 }
10647
10648 return NL_SKIP;
10649}
10650
10651
10652static int nl80211_get_channel_width(struct wpa_driver_nl80211_data *drv,
10653 struct wpa_signal_info *sig)
10654{
10655 struct nl_msg *msg;
10656
10657 msg = nlmsg_alloc();
10658 if (!msg)
10659 return -ENOMEM;
10660
10661 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_INTERFACE);
10662 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
10663
10664 return send_and_recv_msgs(drv, msg, get_channel_width, sig);
10665
10666nla_put_failure:
10667 nlmsg_free(msg);
10668 return -ENOBUFS;
10669}
10670
10671
1c5c7273
PS
10672static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
10673{
10674 struct i802_bss *bss = priv;
10675 struct wpa_driver_nl80211_data *drv = bss->drv;
10676 int res;
10677
10678 os_memset(si, 0, sizeof(*si));
10679 res = nl80211_get_link_signal(drv, si);
10680 if (res != 0)
10681 return res;
10682
2cc8d8f4
AO
10683 res = nl80211_get_channel_width(drv, si);
10684 if (res != 0)
10685 return res;
10686
1c5c7273
PS
10687 return nl80211_get_link_noise(drv, si);
10688}
10689
10690
57ebba59
JJ
10691static int wpa_driver_nl80211_shared_freq(void *priv)
10692{
10693 struct i802_bss *bss = priv;
10694 struct wpa_driver_nl80211_data *drv = bss->drv;
10695 struct wpa_driver_nl80211_data *driver;
10696 int freq = 0;
10697
10698 /*
10699 * If the same PHY is in connected state with some other interface,
10700 * then retrieve the assoc freq.
10701 */
10702 wpa_printf(MSG_DEBUG, "nl80211: Get shared freq for PHY %s",
10703 drv->phyname);
10704
10705 dl_list_for_each(driver, &drv->global->interfaces,
10706 struct wpa_driver_nl80211_data, list) {
10707 if (drv == driver ||
10708 os_strcmp(drv->phyname, driver->phyname) != 0 ||
10709 !driver->associated)
10710 continue;
10711
10712 wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s "
10713 MACSTR,
834ee56f
KP
10714 driver->phyname, driver->first_bss->ifname,
10715 MAC2STR(driver->first_bss->addr));
d3bd0f05 10716 if (is_ap_interface(driver->nlmode))
834ee56f 10717 freq = driver->first_bss->freq;
d3bd0f05
JJ
10718 else
10719 freq = nl80211_get_assoc_freq(driver);
57ebba59
JJ
10720 wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",
10721 drv->phyname, freq);
10722 }
10723
10724 if (!freq)
10725 wpa_printf(MSG_DEBUG, "nl80211: No shared interface for "
10726 "PHY (%s) in associated state", drv->phyname);
10727
10728 return freq;
10729}
10730
10731
b91ab76e
JM
10732static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
10733 int encrypt)
10734{
10735 struct i802_bss *bss = priv;
55231068
JM
10736 return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
10737 0, 0, 0, 0);
b91ab76e
JM
10738}
10739
10740
c55f774d
JM
10741static int nl80211_set_param(void *priv, const char *param)
10742{
c55f774d
JM
10743 wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
10744 if (param == NULL)
10745 return 0;
10746
10747#ifdef CONFIG_P2P
10748 if (os_strstr(param, "use_p2p_group_interface=1")) {
482856c8
JM
10749 struct i802_bss *bss = priv;
10750 struct wpa_driver_nl80211_data *drv = bss->drv;
10751
c55f774d
JM
10752 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
10753 "interface");
10754 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
10755 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
10756 }
851b0c55
JM
10757
10758 if (os_strstr(param, "p2p_device=1")) {
10759 struct i802_bss *bss = priv;
10760 struct wpa_driver_nl80211_data *drv = bss->drv;
10761 drv->allow_p2p_device = 1;
10762 }
c55f774d
JM
10763#endif /* CONFIG_P2P */
10764
327b01d3
JM
10765 if (os_strstr(param, "use_monitor=1")) {
10766 struct i802_bss *bss = priv;
10767 struct wpa_driver_nl80211_data *drv = bss->drv;
10768 drv->use_monitor = 1;
10769 }
10770
10771 if (os_strstr(param, "force_connect_cmd=1")) {
10772 struct i802_bss *bss = priv;
10773 struct wpa_driver_nl80211_data *drv = bss->drv;
10774 drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
10775 }
10776
64abb725
JM
10777 if (os_strstr(param, "no_offchannel_tx=1")) {
10778 struct i802_bss *bss = priv;
10779 struct wpa_driver_nl80211_data *drv = bss->drv;
10780 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
10781 drv->test_use_roc_tx = 1;
10782 }
10783
c55f774d
JM
10784 return 0;
10785}
10786
10787
f2ed8023
JM
10788static void * nl80211_global_init(void)
10789{
10790 struct nl80211_global *global;
36d84860
BG
10791 struct netlink_config *cfg;
10792
f2ed8023
JM
10793 global = os_zalloc(sizeof(*global));
10794 if (global == NULL)
10795 return NULL;
c81eff1a 10796 global->ioctl_sock = -1;
f2ed8023 10797 dl_list_init(&global->interfaces);
ff6a158b 10798 global->if_add_ifindex = -1;
36d84860
BG
10799
10800 cfg = os_zalloc(sizeof(*cfg));
10801 if (cfg == NULL)
10802 goto err;
10803
10804 cfg->ctx = global;
10805 cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
10806 cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
10807 global->netlink = netlink_init(cfg);
10808 if (global->netlink == NULL) {
10809 os_free(cfg);
10810 goto err;
10811 }
10812
2a7b66f5
BG
10813 if (wpa_driver_nl80211_init_nl_global(global) < 0)
10814 goto err;
10815
c81eff1a
BG
10816 global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
10817 if (global->ioctl_sock < 0) {
7ac3616d
JM
10818 wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
10819 strerror(errno));
c81eff1a
BG
10820 goto err;
10821 }
10822
f2ed8023 10823 return global;
36d84860
BG
10824
10825err:
10826 nl80211_global_deinit(global);
10827 return NULL;
f2ed8023
JM
10828}
10829
10830
10831static void nl80211_global_deinit(void *priv)
10832{
10833 struct nl80211_global *global = priv;
10834 if (global == NULL)
10835 return;
10836 if (!dl_list_empty(&global->interfaces)) {
10837 wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
10838 "nl80211_global_deinit",
10839 dl_list_len(&global->interfaces));
10840 }
36d84860
BG
10841
10842 if (global->netlink)
10843 netlink_deinit(global->netlink);
10844
276e2d67
BG
10845 nl_destroy_handles(&global->nl);
10846
5f65e9f7
JB
10847 if (global->nl_event)
10848 nl80211_destroy_eloop_handle(&global->nl_event);
d6c9aab8
JB
10849
10850 nl_cb_put(global->nl_cb);
2a7b66f5 10851
c81eff1a
BG
10852 if (global->ioctl_sock >= 0)
10853 close(global->ioctl_sock);
10854
f2ed8023
JM
10855 os_free(global);
10856}
10857
10858
6859f1cb
BG
10859static const char * nl80211_get_radio_name(void *priv)
10860{
10861 struct i802_bss *bss = priv;
10862 struct wpa_driver_nl80211_data *drv = bss->drv;
10863 return drv->phyname;
10864}
10865
10866
a6efc65d
JM
10867static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
10868 const u8 *pmkid)
10869{
10870 struct nl_msg *msg;
10871
10872 msg = nlmsg_alloc();
10873 if (!msg)
10874 return -ENOMEM;
10875
9fb04070 10876 nl80211_cmd(bss->drv, msg, 0, cmd);
a6efc65d
JM
10877
10878 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
10879 if (pmkid)
10880 NLA_PUT(msg, NL80211_ATTR_PMKID, 16, pmkid);
10881 if (bssid)
10882 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
10883
10884 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
10885 nla_put_failure:
9e088e74 10886 nlmsg_free(msg);
a6efc65d
JM
10887 return -ENOBUFS;
10888}
10889
10890
10891static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
10892{
10893 struct i802_bss *bss = priv;
10894 wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
10895 return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
10896}
10897
10898
10899static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
10900{
10901 struct i802_bss *bss = priv;
10902 wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
10903 MAC2STR(bssid));
10904 return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
10905}
10906
10907
10908static int nl80211_flush_pmkid(void *priv)
10909{
10910 struct i802_bss *bss = priv;
10911 wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
10912 return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
10913}
10914
10915
0185007c
MK
10916static void clean_survey_results(struct survey_results *survey_results)
10917{
10918 struct freq_survey *survey, *tmp;
10919
10920 if (dl_list_empty(&survey_results->survey_list))
10921 return;
10922
10923 dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
10924 struct freq_survey, list) {
10925 dl_list_del(&survey->list);
10926 os_free(survey);
10927 }
10928}
10929
10930
10931static void add_survey(struct nlattr **sinfo, u32 ifidx,
10932 struct dl_list *survey_list)
10933{
10934 struct freq_survey *survey;
10935
10936 survey = os_zalloc(sizeof(struct freq_survey));
10937 if (!survey)
10938 return;
10939
10940 survey->ifidx = ifidx;
10941 survey->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
10942 survey->filled = 0;
10943
10944 if (sinfo[NL80211_SURVEY_INFO_NOISE]) {
10945 survey->nf = (int8_t)
10946 nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
10947 survey->filled |= SURVEY_HAS_NF;
10948 }
10949
10950 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) {
10951 survey->channel_time =
10952 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
10953 survey->filled |= SURVEY_HAS_CHAN_TIME;
10954 }
10955
10956 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {
10957 survey->channel_time_busy =
10958 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);
10959 survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
10960 }
10961
10962 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) {
10963 survey->channel_time_rx =
10964 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);
10965 survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
10966 }
10967
10968 if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) {
10969 survey->channel_time_tx =
10970 nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);
10971 survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
10972 }
10973
10974 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)",
10975 survey->freq,
10976 survey->nf,
10977 (unsigned long int) survey->channel_time,
10978 (unsigned long int) survey->channel_time_busy,
10979 (unsigned long int) survey->channel_time_tx,
10980 (unsigned long int) survey->channel_time_rx,
10981 survey->filled);
10982
10983 dl_list_add_tail(survey_list, &survey->list);
10984}
10985
10986
10987static int check_survey_ok(struct nlattr **sinfo, u32 surveyed_freq,
10988 unsigned int freq_filter)
10989{
10990 if (!freq_filter)
10991 return 1;
10992
10993 return freq_filter == surveyed_freq;
10994}
10995
10996
10997static int survey_handler(struct nl_msg *msg, void *arg)
10998{
10999 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11000 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11001 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
11002 struct survey_results *survey_results;
11003 u32 surveyed_freq = 0;
11004 u32 ifidx;
11005
11006 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
11007 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
11008 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
11009 };
11010
11011 survey_results = (struct survey_results *) arg;
11012
11013 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
11014 genlmsg_attrlen(gnlh, 0), NULL);
11015
e28f39b7
SJ
11016 if (!tb[NL80211_ATTR_IFINDEX])
11017 return NL_SKIP;
11018
0185007c
MK
11019 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
11020
11021 if (!tb[NL80211_ATTR_SURVEY_INFO])
11022 return NL_SKIP;
11023
11024 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
11025 tb[NL80211_ATTR_SURVEY_INFO],
11026 survey_policy))
11027 return NL_SKIP;
11028
11029 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) {
11030 wpa_printf(MSG_ERROR, "nl80211: Invalid survey data");
11031 return NL_SKIP;
11032 }
11033
11034 surveyed_freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
11035
11036 if (!check_survey_ok(sinfo, surveyed_freq,
11037 survey_results->freq_filter))
11038 return NL_SKIP;
11039
11040 if (survey_results->freq_filter &&
11041 survey_results->freq_filter != surveyed_freq) {
11042 wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
11043 surveyed_freq);
11044 return NL_SKIP;
11045 }
11046
11047 add_survey(sinfo, ifidx, &survey_results->survey_list);
11048
11049 return NL_SKIP;
11050}
11051
11052
11053static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
11054{
11055 struct i802_bss *bss = priv;
11056 struct wpa_driver_nl80211_data *drv = bss->drv;
11057 struct nl_msg *msg;
11058 int err = -ENOBUFS;
11059 union wpa_event_data data;
11060 struct survey_results *survey_results;
11061
11062 os_memset(&data, 0, sizeof(data));
11063 survey_results = &data.survey_results;
11064
11065 dl_list_init(&survey_results->survey_list);
11066
11067 msg = nlmsg_alloc();
11068 if (!msg)
11069 goto nla_put_failure;
11070
11071 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
11072
11073 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11074
11075 if (freq)
11076 data.survey_results.freq_filter = freq;
11077
11078 do {
11079 wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
11080 err = send_and_recv_msgs(drv, msg, survey_handler,
11081 survey_results);
11082 } while (err > 0);
11083
11084 if (err) {
11085 wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
11086 goto out_clean;
11087 }
11088
11089 wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
11090
11091out_clean:
11092 clean_survey_results(survey_results);
11093nla_put_failure:
11094 return err;
11095}
11096
11097
b14a210c
JB
11098static void nl80211_set_rekey_info(void *priv, const u8 *kek, const u8 *kck,
11099 const u8 *replay_ctr)
11100{
11101 struct i802_bss *bss = priv;
11102 struct wpa_driver_nl80211_data *drv = bss->drv;
11103 struct nlattr *replay_nested;
11104 struct nl_msg *msg;
11105
11106 msg = nlmsg_alloc();
11107 if (!msg)
11108 return;
11109
9fb04070 11110 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
b14a210c
JB
11111
11112 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11113
11114 replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
11115 if (!replay_nested)
11116 goto nla_put_failure;
11117
11118 NLA_PUT(msg, NL80211_REKEY_DATA_KEK, NL80211_KEK_LEN, kek);
11119 NLA_PUT(msg, NL80211_REKEY_DATA_KCK, NL80211_KCK_LEN, kck);
11120 NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
11121 replay_ctr);
11122
11123 nla_nest_end(msg, replay_nested);
11124
11125 send_and_recv_msgs(drv, msg, NULL, NULL);
11126 return;
11127 nla_put_failure:
11128 nlmsg_free(msg);
11129}
11130
11131
39718852
JB
11132static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
11133 const u8 *addr, int qos)
bcf24348 11134{
39718852
JB
11135 /* send data frame to poll STA and check whether
11136 * this frame is ACKed */
bcf24348
JB
11137 struct {
11138 struct ieee80211_hdr hdr;
11139 u16 qos_ctl;
11140 } STRUCT_PACKED nulldata;
11141 size_t size;
11142
11143 /* Send data frame to poll STA and check whether this frame is ACKed */
11144
11145 os_memset(&nulldata, 0, sizeof(nulldata));
11146
11147 if (qos) {
11148 nulldata.hdr.frame_control =
11149 IEEE80211_FC(WLAN_FC_TYPE_DATA,
11150 WLAN_FC_STYPE_QOS_NULL);
11151 size = sizeof(nulldata);
11152 } else {
11153 nulldata.hdr.frame_control =
11154 IEEE80211_FC(WLAN_FC_TYPE_DATA,
11155 WLAN_FC_STYPE_NULLFUNC);
11156 size = sizeof(struct ieee80211_hdr);
11157 }
11158
11159 nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
11160 os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
11161 os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
11162 os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
11163
9ebce9c5
JM
11164 if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
11165 0, 0) < 0)
bcf24348
JB
11166 wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
11167 "send poll frame");
11168}
11169
39718852
JB
11170static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
11171 int qos)
11172{
11173 struct i802_bss *bss = priv;
11174 struct wpa_driver_nl80211_data *drv = bss->drv;
11175 struct nl_msg *msg;
11176
11177 if (!drv->poll_command_supported) {
11178 nl80211_send_null_frame(bss, own_addr, addr, qos);
11179 return;
11180 }
11181
11182 msg = nlmsg_alloc();
11183 if (!msg)
11184 return;
11185
11186 nl80211_cmd(drv, msg, 0, NL80211_CMD_PROBE_CLIENT);
11187
11188 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11189 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
11190
11191 send_and_recv_msgs(drv, msg, NULL, NULL);
11192 return;
11193 nla_put_failure:
11194 nlmsg_free(msg);
11195}
11196
bcf24348 11197
29f338af
JM
11198static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
11199{
11200 struct nl_msg *msg;
11201
11202 msg = nlmsg_alloc();
11203 if (!msg)
11204 return -ENOMEM;
11205
11206 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_SET_POWER_SAVE);
11207 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11208 NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE,
11209 enabled ? NL80211_PS_ENABLED : NL80211_PS_DISABLED);
11210 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
11211nla_put_failure:
11212 nlmsg_free(msg);
11213 return -ENOBUFS;
11214}
11215
11216
11217static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps,
11218 int ctwindow)
11219{
11220 struct i802_bss *bss = priv;
11221
11222 wpa_printf(MSG_DEBUG, "nl80211: set_p2p_powersave (legacy_ps=%d "
11223 "opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
11224
0de38036
JM
11225 if (opp_ps != -1 || ctwindow != -1) {
11226#ifdef ANDROID_P2P
11227 wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
11228#else /* ANDROID_P2P */
29f338af 11229 return -1; /* Not yet supported */
0de38036
JM
11230#endif /* ANDROID_P2P */
11231 }
29f338af
JM
11232
11233 if (legacy_ps == -1)
11234 return 0;
11235 if (legacy_ps != 0 && legacy_ps != 1)
11236 return -1; /* Not yet supported */
11237
11238 return nl80211_set_power_save(bss, legacy_ps);
11239}
11240
11241
04e8003c
JD
11242static int nl80211_start_radar_detection(void *priv,
11243 struct hostapd_freq_params *freq)
f90e9c1c
SW
11244{
11245 struct i802_bss *bss = priv;
11246 struct wpa_driver_nl80211_data *drv = bss->drv;
11247 struct nl_msg *msg;
11248 int ret;
11249
04e8003c
JD
11250 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)",
11251 freq->freq, freq->ht_enabled, freq->vht_enabled,
11252 freq->bandwidth, freq->center_freq1, freq->center_freq2);
11253
f90e9c1c
SW
11254 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) {
11255 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar "
11256 "detection");
11257 return -1;
11258 }
11259
11260 msg = nlmsg_alloc();
11261 if (!msg)
11262 return -1;
11263
11264 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_RADAR_DETECT);
11265 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
04e8003c 11266 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq);
f90e9c1c 11267
04e8003c
JD
11268 if (freq->vht_enabled) {
11269 switch (freq->bandwidth) {
11270 case 20:
11271 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11272 NL80211_CHAN_WIDTH_20);
11273 break;
11274 case 40:
11275 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11276 NL80211_CHAN_WIDTH_40);
11277 break;
11278 case 80:
11279 if (freq->center_freq2)
11280 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11281 NL80211_CHAN_WIDTH_80P80);
11282 else
11283 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11284 NL80211_CHAN_WIDTH_80);
11285 break;
11286 case 160:
11287 NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11288 NL80211_CHAN_WIDTH_160);
11289 break;
11290 default:
11291 return -1;
11292 }
11293 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1);
11294 if (freq->center_freq2)
11295 NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2,
11296 freq->center_freq2);
11297 } else if (freq->ht_enabled) {
11298 switch (freq->sec_channel_offset) {
11299 case -1:
11300 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11301 NL80211_CHAN_HT40MINUS);
11302 break;
11303 case 1:
11304 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11305 NL80211_CHAN_HT40PLUS);
11306 break;
11307 default:
11308 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11309 NL80211_CHAN_HT20);
11310 break;
11311 }
11312 }
f90e9c1c
SW
11313
11314 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11315 if (ret == 0)
11316 return 0;
11317 wpa_printf(MSG_DEBUG, "nl80211: Failed to start radar detection: "
11318 "%d (%s)", ret, strerror(-ret));
11319nla_put_failure:
11320 return -1;
11321}
11322
03ea1786
AN
11323#ifdef CONFIG_TDLS
11324
11325static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
11326 u8 dialog_token, u16 status_code,
96ecea5e 11327 u32 peer_capab, const u8 *buf, size_t len)
03ea1786
AN
11328{
11329 struct i802_bss *bss = priv;
11330 struct wpa_driver_nl80211_data *drv = bss->drv;
11331 struct nl_msg *msg;
11332
11333 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
11334 return -EOPNOTSUPP;
11335
11336 if (!dst)
11337 return -EINVAL;
11338
11339 msg = nlmsg_alloc();
11340 if (!msg)
11341 return -ENOMEM;
11342
11343 nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_MGMT);
11344 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11345 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
11346 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_ACTION, action_code);
11347 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token);
11348 NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status_code);
96ecea5e
SD
11349 if (peer_capab) {
11350 /*
11351 * The internal enum tdls_peer_capability definition is
11352 * currently identical with the nl80211 enum
11353 * nl80211_tdls_peer_capability, so no conversion is needed
11354 * here.
11355 */
11356 NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY, peer_capab);
11357 }
03ea1786
AN
11358 NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
11359
11360 return send_and_recv_msgs(drv, msg, NULL, NULL);
11361
11362nla_put_failure:
11363 nlmsg_free(msg);
11364 return -ENOBUFS;
11365}
11366
11367
11368static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
11369{
11370 struct i802_bss *bss = priv;
11371 struct wpa_driver_nl80211_data *drv = bss->drv;
11372 struct nl_msg *msg;
11373 enum nl80211_tdls_operation nl80211_oper;
11374
11375 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
11376 return -EOPNOTSUPP;
11377
11378 switch (oper) {
11379 case TDLS_DISCOVERY_REQ:
11380 nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
11381 break;
11382 case TDLS_SETUP:
11383 nl80211_oper = NL80211_TDLS_SETUP;
11384 break;
11385 case TDLS_TEARDOWN:
11386 nl80211_oper = NL80211_TDLS_TEARDOWN;
11387 break;
11388 case TDLS_ENABLE_LINK:
11389 nl80211_oper = NL80211_TDLS_ENABLE_LINK;
11390 break;
11391 case TDLS_DISABLE_LINK:
11392 nl80211_oper = NL80211_TDLS_DISABLE_LINK;
11393 break;
11394 case TDLS_ENABLE:
11395 return 0;
11396 case TDLS_DISABLE:
11397 return 0;
11398 default:
11399 return -EINVAL;
11400 }
11401
11402 msg = nlmsg_alloc();
11403 if (!msg)
11404 return -ENOMEM;
11405
11406 nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_OPER);
11407 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper);
11408 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11409 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
11410
11411 return send_and_recv_msgs(drv, msg, NULL, NULL);
11412
11413nla_put_failure:
11414 nlmsg_free(msg);
11415 return -ENOBUFS;
11416}
11417
11418#endif /* CONFIG TDLS */
11419
11420
216eede8
DS
11421#ifdef ANDROID
11422
11423typedef struct android_wifi_priv_cmd {
11424 char *buf;
11425 int used_len;
11426 int total_len;
11427} android_wifi_priv_cmd;
11428
11429static int drv_errors = 0;
11430
11431static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
11432{
11433 drv_errors++;
11434 if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
11435 drv_errors = 0;
11436 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
11437 }
11438}
11439
11440
11441static int android_priv_cmd(struct i802_bss *bss, const char *cmd)
11442{
11443 struct wpa_driver_nl80211_data *drv = bss->drv;
11444 struct ifreq ifr;
11445 android_wifi_priv_cmd priv_cmd;
11446 char buf[MAX_DRV_CMD_SIZE];
11447 int ret;
11448
11449 os_memset(&ifr, 0, sizeof(ifr));
11450 os_memset(&priv_cmd, 0, sizeof(priv_cmd));
11451 os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
11452
11453 os_memset(buf, 0, sizeof(buf));
11454 os_strlcpy(buf, cmd, sizeof(buf));
11455
11456 priv_cmd.buf = buf;
11457 priv_cmd.used_len = sizeof(buf);
11458 priv_cmd.total_len = sizeof(buf);
11459 ifr.ifr_data = &priv_cmd;
11460
11461 ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
11462 if (ret < 0) {
11463 wpa_printf(MSG_ERROR, "%s: failed to issue private commands",
11464 __func__);
11465 wpa_driver_send_hang_msg(drv);
11466 return ret;
11467 }
11468
11469 drv_errors = 0;
11470 return 0;
11471}
11472
11473
11474static int android_pno_start(struct i802_bss *bss,
11475 struct wpa_driver_scan_params *params)
11476{
11477 struct wpa_driver_nl80211_data *drv = bss->drv;
11478 struct ifreq ifr;
11479 android_wifi_priv_cmd priv_cmd;
11480 int ret = 0, i = 0, bp;
11481 char buf[WEXT_PNO_MAX_COMMAND_SIZE];
11482
11483 bp = WEXT_PNOSETUP_HEADER_SIZE;
11484 os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
11485 buf[bp++] = WEXT_PNO_TLV_PREFIX;
11486 buf[bp++] = WEXT_PNO_TLV_VERSION;
11487 buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
11488 buf[bp++] = WEXT_PNO_TLV_RESERVED;
11489
11490 while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) {
11491 /* Check that there is enough space needed for 1 more SSID, the
11492 * other sections and null termination */
11493 if ((bp + WEXT_PNO_SSID_HEADER_SIZE + MAX_SSID_LEN +
11494 WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf))
11495 break;
11496 wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan",
a97bde0a
JM
11497 params->ssids[i].ssid,
11498 params->ssids[i].ssid_len);
216eede8
DS
11499 buf[bp++] = WEXT_PNO_SSID_SECTION;
11500 buf[bp++] = params->ssids[i].ssid_len;
11501 os_memcpy(&buf[bp], params->ssids[i].ssid,
11502 params->ssids[i].ssid_len);
11503 bp += params->ssids[i].ssid_len;
11504 i++;
11505 }
11506
11507 buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
11508 os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x",
11509 WEXT_PNO_SCAN_INTERVAL);
11510 bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
11511
11512 buf[bp++] = WEXT_PNO_REPEAT_SECTION;
11513 os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x",
11514 WEXT_PNO_REPEAT);
11515 bp += WEXT_PNO_REPEAT_LENGTH;
11516
11517 buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
11518 os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x",
11519 WEXT_PNO_MAX_REPEAT);
11520 bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
11521
11522 memset(&ifr, 0, sizeof(ifr));
11523 memset(&priv_cmd, 0, sizeof(priv_cmd));
24f051eb 11524 os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
216eede8
DS
11525
11526 priv_cmd.buf = buf;
11527 priv_cmd.used_len = bp;
11528 priv_cmd.total_len = bp;
11529 ifr.ifr_data = &priv_cmd;
11530
11531 ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
11532
11533 if (ret < 0) {
11534 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
11535 ret);
11536 wpa_driver_send_hang_msg(drv);
11537 return ret;
11538 }
11539
11540 drv_errors = 0;
11541
11542 return android_priv_cmd(bss, "PNOFORCE 1");
11543}
11544
11545
11546static int android_pno_stop(struct i802_bss *bss)
11547{
11548 return android_priv_cmd(bss, "PNOFORCE 0");
11549}
11550
11551#endif /* ANDROID */
11552
11553
9ebce9c5
JM
11554static int driver_nl80211_set_key(const char *ifname, void *priv,
11555 enum wpa_alg alg, const u8 *addr,
11556 int key_idx, int set_tx,
11557 const u8 *seq, size_t seq_len,
11558 const u8 *key, size_t key_len)
11559{
11560 struct i802_bss *bss = priv;
11561 return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
11562 set_tx, seq, seq_len, key, key_len);
11563}
11564
11565
11566static int driver_nl80211_scan2(void *priv,
11567 struct wpa_driver_scan_params *params)
11568{
11569 struct i802_bss *bss = priv;
11570 return wpa_driver_nl80211_scan(bss, params);
11571}
11572
11573
11574static int driver_nl80211_deauthenticate(void *priv, const u8 *addr,
11575 int reason_code)
11576{
11577 struct i802_bss *bss = priv;
11578 return wpa_driver_nl80211_deauthenticate(bss, addr, reason_code);
11579}
11580
11581
11582static int driver_nl80211_authenticate(void *priv,
11583 struct wpa_driver_auth_params *params)
11584{
11585 struct i802_bss *bss = priv;
11586 return wpa_driver_nl80211_authenticate(bss, params);
11587}
11588
11589
11590static void driver_nl80211_deinit(void *priv)
11591{
11592 struct i802_bss *bss = priv;
11593 wpa_driver_nl80211_deinit(bss);
11594}
11595
11596
11597static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
11598 const char *ifname)
11599{
11600 struct i802_bss *bss = priv;
11601 return wpa_driver_nl80211_if_remove(bss, type, ifname);
11602}
11603
11604
11605static int driver_nl80211_send_mlme(void *priv, const u8 *data,
11606 size_t data_len, int noack)
11607{
11608 struct i802_bss *bss = priv;
11609 return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
11610 0, 0, 0, 0);
11611}
11612
11613
11614static int driver_nl80211_sta_remove(void *priv, const u8 *addr)
11615{
11616 struct i802_bss *bss = priv;
11617 return wpa_driver_nl80211_sta_remove(bss, addr);
11618}
11619
11620
9ebce9c5
JM
11621static int driver_nl80211_set_sta_vlan(void *priv, const u8 *addr,
11622 const char *ifname, int vlan_id)
11623{
11624 struct i802_bss *bss = priv;
11625 return i802_set_sta_vlan(bss, addr, ifname, vlan_id);
11626}
9ebce9c5
JM
11627
11628
11629static int driver_nl80211_read_sta_data(void *priv,
11630 struct hostap_sta_driver_data *data,
11631 const u8 *addr)
11632{
11633 struct i802_bss *bss = priv;
11634 return i802_read_sta_data(bss, data, addr);
11635}
11636
11637
11638static int driver_nl80211_send_action(void *priv, unsigned int freq,
11639 unsigned int wait_time,
11640 const u8 *dst, const u8 *src,
11641 const u8 *bssid,
11642 const u8 *data, size_t data_len,
11643 int no_cck)
11644{
11645 struct i802_bss *bss = priv;
11646 return wpa_driver_nl80211_send_action(bss, freq, wait_time, dst, src,
11647 bssid, data, data_len, no_cck);
11648}
11649
11650
11651static int driver_nl80211_probe_req_report(void *priv, int report)
11652{
11653 struct i802_bss *bss = priv;
11654 return wpa_driver_nl80211_probe_req_report(bss, report);
11655}
11656
11657
6a1ce395
DG
11658static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
11659 const u8 *ies, size_t ies_len)
11660{
11661 int ret;
11662 struct nl_msg *msg;
11663 struct i802_bss *bss = priv;
11664 struct wpa_driver_nl80211_data *drv = bss->drv;
11665 u16 mdid = WPA_GET_LE16(md);
11666
11667 msg = nlmsg_alloc();
11668 if (!msg)
11669 return -ENOMEM;
11670
11671 wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
11672 nl80211_cmd(drv, msg, 0, NL80211_CMD_UPDATE_FT_IES);
11673 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11674 NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies);
11675 NLA_PUT_U16(msg, NL80211_ATTR_MDID, mdid);
11676
11677 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11678 if (ret) {
11679 wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
11680 "err=%d (%s)", ret, strerror(-ret));
11681 }
11682
11683 return ret;
11684
11685nla_put_failure:
11686 nlmsg_free(msg);
11687 return -ENOBUFS;
11688}
11689
11690
597b94f5
AS
11691const u8 * wpa_driver_nl80211_get_macaddr(void *priv)
11692{
11693 struct i802_bss *bss = priv;
11694 struct wpa_driver_nl80211_data *drv = bss->drv;
11695
11696 if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE)
11697 return NULL;
11698
11699 return bss->addr;
11700}
11701
11702
a771c07d
JM
11703static const char * scan_state_str(enum scan_states scan_state)
11704{
11705 switch (scan_state) {
11706 case NO_SCAN:
11707 return "NO_SCAN";
11708 case SCAN_REQUESTED:
11709 return "SCAN_REQUESTED";
11710 case SCAN_STARTED:
11711 return "SCAN_STARTED";
11712 case SCAN_COMPLETED:
11713 return "SCAN_COMPLETED";
11714 case SCAN_ABORTED:
11715 return "SCAN_ABORTED";
11716 case SCHED_SCAN_STARTED:
11717 return "SCHED_SCAN_STARTED";
11718 case SCHED_SCAN_STOPPED:
11719 return "SCHED_SCAN_STOPPED";
11720 case SCHED_SCAN_RESULTS:
11721 return "SCHED_SCAN_RESULTS";
11722 }
11723
11724 return "??";
11725}
11726
11727
11728static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
11729{
11730 struct i802_bss *bss = priv;
11731 struct wpa_driver_nl80211_data *drv = bss->drv;
11732 int res;
11733 char *pos, *end;
11734
11735 pos = buf;
11736 end = buf + buflen;
11737
11738 res = os_snprintf(pos, end - pos,
11739 "ifindex=%d\n"
11740 "ifname=%s\n"
11741 "brname=%s\n"
11742 "addr=" MACSTR "\n"
11743 "freq=%d\n"
11744 "%s%s%s%s%s",
11745 bss->ifindex,
11746 bss->ifname,
11747 bss->brname,
11748 MAC2STR(bss->addr),
11749 bss->freq,
11750 bss->beacon_set ? "beacon_set=1\n" : "",
11751 bss->added_if_into_bridge ?
11752 "added_if_into_bridge=1\n" : "",
11753 bss->added_bridge ? "added_bridge=1\n" : "",
11754 bss->in_deinit ? "in_deinit=1\n" : "",
11755 bss->if_dynamic ? "if_dynamic=1\n" : "");
11756 if (res < 0 || res >= end - pos)
11757 return pos - buf;
11758 pos += res;
11759
11760 if (bss->wdev_id_set) {
11761 res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
11762 (unsigned long long) bss->wdev_id);
11763 if (res < 0 || res >= end - pos)
11764 return pos - buf;
11765 pos += res;
11766 }
11767
11768 res = os_snprintf(pos, end - pos,
11769 "phyname=%s\n"
11770 "drv_ifindex=%d\n"
11771 "operstate=%d\n"
11772 "scan_state=%s\n"
11773 "auth_bssid=" MACSTR "\n"
11774 "auth_attempt_bssid=" MACSTR "\n"
11775 "bssid=" MACSTR "\n"
11776 "prev_bssid=" MACSTR "\n"
11777 "associated=%d\n"
11778 "assoc_freq=%u\n"
11779 "monitor_sock=%d\n"
11780 "monitor_ifidx=%d\n"
11781 "monitor_refcount=%d\n"
11782 "last_mgmt_freq=%u\n"
11783 "eapol_tx_sock=%d\n"
d6a36f39 11784 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
a771c07d
JM
11785 drv->phyname,
11786 drv->ifindex,
11787 drv->operstate,
11788 scan_state_str(drv->scan_state),
11789 MAC2STR(drv->auth_bssid),
11790 MAC2STR(drv->auth_attempt_bssid),
11791 MAC2STR(drv->bssid),
11792 MAC2STR(drv->prev_bssid),
11793 drv->associated,
11794 drv->assoc_freq,
11795 drv->monitor_sock,
11796 drv->monitor_ifidx,
11797 drv->monitor_refcount,
11798 drv->last_mgmt_freq,
11799 drv->eapol_tx_sock,
11800 drv->ignore_if_down_event ?
11801 "ignore_if_down_event=1\n" : "",
11802 drv->scan_complete_events ?
11803 "scan_complete_events=1\n" : "",
11804 drv->disabled_11b_rates ?
11805 "disabled_11b_rates=1\n" : "",
11806 drv->pending_remain_on_chan ?
11807 "pending_remain_on_chan=1\n" : "",
11808 drv->in_interface_list ? "in_interface_list=1\n" : "",
11809 drv->device_ap_sme ? "device_ap_sme=1\n" : "",
11810 drv->poll_command_supported ?
11811 "poll_command_supported=1\n" : "",
11812 drv->data_tx_status ? "data_tx_status=1\n" : "",
11813 drv->scan_for_auth ? "scan_for_auth=1\n" : "",
11814 drv->retry_auth ? "retry_auth=1\n" : "",
11815 drv->use_monitor ? "use_monitor=1\n" : "",
11816 drv->ignore_next_local_disconnect ?
11817 "ignore_next_local_disconnect=1\n" : "",
d6a36f39
JM
11818 drv->ignore_next_local_deauth ?
11819 "ignore_next_local_deauth=1\n" : "",
a771c07d
JM
11820 drv->allow_p2p_device ? "allow_p2p_device=1\n" : "");
11821 if (res < 0 || res >= end - pos)
11822 return pos - buf;
11823 pos += res;
11824
11825 if (drv->has_capability) {
11826 res = os_snprintf(pos, end - pos,
11827 "capa.key_mgmt=0x%x\n"
11828 "capa.enc=0x%x\n"
11829 "capa.auth=0x%x\n"
11830 "capa.flags=0x%x\n"
11831 "capa.max_scan_ssids=%d\n"
11832 "capa.max_sched_scan_ssids=%d\n"
11833 "capa.sched_scan_supported=%d\n"
11834 "capa.max_match_sets=%d\n"
11835 "capa.max_remain_on_chan=%u\n"
11836 "capa.max_stations=%u\n"
11837 "capa.probe_resp_offloads=0x%x\n"
11838 "capa.max_acl_mac_addrs=%u\n"
11839 "capa.num_multichan_concurrent=%u\n",
11840 drv->capa.key_mgmt,
11841 drv->capa.enc,
11842 drv->capa.auth,
11843 drv->capa.flags,
11844 drv->capa.max_scan_ssids,
11845 drv->capa.max_sched_scan_ssids,
11846 drv->capa.sched_scan_supported,
11847 drv->capa.max_match_sets,
11848 drv->capa.max_remain_on_chan,
11849 drv->capa.max_stations,
11850 drv->capa.probe_resp_offloads,
11851 drv->capa.max_acl_mac_addrs,
11852 drv->capa.num_multichan_concurrent);
11853 if (res < 0 || res >= end - pos)
11854 return pos - buf;
11855 pos += res;
11856 }
11857
11858 return pos - buf;
11859}
11860
11861
1c4ffa87
AO
11862static int set_beacon_data(struct nl_msg *msg, struct beacon_data *settings)
11863{
11864 if (settings->head)
11865 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD,
11866 settings->head_len, settings->head);
11867
11868 if (settings->tail)
11869 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL,
11870 settings->tail_len, settings->tail);
11871
11872 if (settings->beacon_ies)
11873 NLA_PUT(msg, NL80211_ATTR_IE,
11874 settings->beacon_ies_len, settings->beacon_ies);
11875
11876 if (settings->proberesp_ies)
11877 NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
11878 settings->proberesp_ies_len, settings->proberesp_ies);
11879
11880 if (settings->assocresp_ies)
11881 NLA_PUT(msg,
11882 NL80211_ATTR_IE_ASSOC_RESP,
11883 settings->assocresp_ies_len, settings->assocresp_ies);
11884
11885 if (settings->probe_resp)
11886 NLA_PUT(msg, NL80211_ATTR_PROBE_RESP,
11887 settings->probe_resp_len, settings->probe_resp);
11888
11889 return 0;
11890
11891nla_put_failure:
11892 return -ENOBUFS;
11893}
11894
11895
11896static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
11897{
11898 struct nl_msg *msg;
11899 struct i802_bss *bss = priv;
11900 struct wpa_driver_nl80211_data *drv = bss->drv;
11901 struct nlattr *beacon_csa;
11902 int ret = -ENOBUFS;
11903
8d1fdde7 11904 wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
1c4ffa87 11905 settings->cs_count, settings->block_tx,
8d1fdde7
JD
11906 settings->freq_params.freq, settings->freq_params.bandwidth,
11907 settings->freq_params.center_freq1,
11908 settings->freq_params.center_freq2);
1c4ffa87 11909
991aa9c7 11910 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
1c4ffa87
AO
11911 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
11912 return -EOPNOTSUPP;
11913 }
11914
11915 if ((drv->nlmode != NL80211_IFTYPE_AP) &&
11916 (drv->nlmode != NL80211_IFTYPE_P2P_GO))
11917 return -EOPNOTSUPP;
11918
11919 /* check settings validity */
11920 if (!settings->beacon_csa.tail ||
11921 ((settings->beacon_csa.tail_len <=
11922 settings->counter_offset_beacon) ||
11923 (settings->beacon_csa.tail[settings->counter_offset_beacon] !=
11924 settings->cs_count)))
11925 return -EINVAL;
11926
11927 if (settings->beacon_csa.probe_resp &&
11928 ((settings->beacon_csa.probe_resp_len <=
11929 settings->counter_offset_presp) ||
11930 (settings->beacon_csa.probe_resp[settings->counter_offset_presp] !=
11931 settings->cs_count)))
11932 return -EINVAL;
11933
11934 msg = nlmsg_alloc();
11935 if (!msg)
11936 return -ENOMEM;
11937
11938 nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
11939 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11940 NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count);
11941 ret = nl80211_put_freq_params(msg, &settings->freq_params);
11942 if (ret)
11943 goto error;
11944
11945 if (settings->block_tx)
11946 NLA_PUT_FLAG(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX);
11947
11948 /* beacon_after params */
11949 ret = set_beacon_data(msg, &settings->beacon_after);
11950 if (ret)
11951 goto error;
11952
11953 /* beacon_csa params */
11954 beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES);
11955 if (!beacon_csa)
11956 goto nla_put_failure;
11957
11958 ret = set_beacon_data(msg, &settings->beacon_csa);
11959 if (ret)
11960 goto error;
11961
11962 NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_BEACON,
11963 settings->counter_offset_beacon);
11964
11965 if (settings->beacon_csa.probe_resp)
11966 NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_PRESP,
11967 settings->counter_offset_presp);
11968
11969 nla_nest_end(msg, beacon_csa);
11970 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11971 if (ret) {
11972 wpa_printf(MSG_DEBUG, "nl80211: switch_channel failed err=%d (%s)",
11973 ret, strerror(-ret));
11974 }
11975 return ret;
11976
11977nla_put_failure:
11978 ret = -ENOBUFS;
11979error:
11980 nlmsg_free(msg);
11981 wpa_printf(MSG_DEBUG, "nl80211: Could not build channel switch request");
11982 return ret;
11983}
11984
11985
6b9f7af6
JM
11986#ifdef CONFIG_TESTING_OPTIONS
11987static int cmd_reply_handler(struct nl_msg *msg, void *arg)
11988{
11989 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11990 struct wpabuf *buf = arg;
11991
11992 if (!buf)
11993 return NL_SKIP;
11994
11995 if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
11996 wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
11997 return NL_SKIP;
11998 }
11999
12000 wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
12001 genlmsg_attrlen(gnlh, 0));
12002
12003 return NL_SKIP;
12004}
12005#endif /* CONFIG_TESTING_OPTIONS */
12006
12007
adef8948
BL
12008static int vendor_reply_handler(struct nl_msg *msg, void *arg)
12009{
12010 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12011 struct nlattr *nl_vendor_reply, *nl;
12012 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12013 struct wpabuf *buf = arg;
12014 int rem;
12015
12016 if (!buf)
12017 return NL_SKIP;
12018
12019 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
12020 genlmsg_attrlen(gnlh, 0), NULL);
12021 nl_vendor_reply = tb[NL80211_ATTR_VENDOR_DATA];
12022
12023 if (!nl_vendor_reply)
12024 return NL_SKIP;
12025
12026 if ((size_t) nla_len(nl_vendor_reply) > wpabuf_tailroom(buf)) {
12027 wpa_printf(MSG_INFO, "nl80211: Vendor command: insufficient buffer space for reply");
12028 return NL_SKIP;
12029 }
12030
12031 nla_for_each_nested(nl, nl_vendor_reply, rem) {
12032 wpabuf_put_data(buf, nla_data(nl), nla_len(nl));
12033 }
12034
12035 return NL_SKIP;
12036}
12037
12038
12039static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
12040 unsigned int subcmd, const u8 *data,
12041 size_t data_len, struct wpabuf *buf)
12042{
12043 struct i802_bss *bss = priv;
12044 struct wpa_driver_nl80211_data *drv = bss->drv;
12045 struct nl_msg *msg;
12046 int ret;
12047
12048 msg = nlmsg_alloc();
12049 if (!msg)
12050 return -ENOMEM;
12051
6b9f7af6
JM
12052#ifdef CONFIG_TESTING_OPTIONS
12053 if (vendor_id == 0xffffffff) {
12054 nl80211_cmd(drv, msg, 0, subcmd);
12055 if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
12056 0)
12057 goto nla_put_failure;
12058 ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
12059 if (ret)
12060 wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
12061 ret);
12062 return ret;
12063 }
12064#endif /* CONFIG_TESTING_OPTIONS */
12065
adef8948
BL
12066 nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
12067 if (nl80211_set_iface_id(msg, bss) < 0)
12068 goto nla_put_failure;
12069 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, vendor_id);
12070 NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd);
12071 if (data)
12072 NLA_PUT(msg, NL80211_ATTR_VENDOR_DATA, data_len, data);
12073
12074 ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, buf);
12075 if (ret)
12076 wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d",
12077 ret);
12078 return ret;
12079
12080nla_put_failure:
12081 nlmsg_free(msg);
12082 return -ENOBUFS;
12083}
12084
12085
049105b4
KP
12086static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
12087 u8 qos_map_set_len)
12088{
12089 struct i802_bss *bss = priv;
12090 struct wpa_driver_nl80211_data *drv = bss->drv;
12091 struct nl_msg *msg;
12092 int ret;
12093
12094 msg = nlmsg_alloc();
12095 if (!msg)
12096 return -ENOMEM;
12097
12098 wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
12099 qos_map_set, qos_map_set_len);
12100
12101 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_QOS_MAP);
12102 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
12103 NLA_PUT(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set);
12104
12105 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
12106 if (ret)
12107 wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
12108
12109 return ret;
12110
12111nla_put_failure:
12112 nlmsg_free(msg);
12113 return -ENOBUFS;
12114}
12115
12116
3f5285e8
JM
12117const struct wpa_driver_ops wpa_driver_nl80211_ops = {
12118 .name = "nl80211",
12119 .desc = "Linux nl80211/cfg80211",
12120 .get_bssid = wpa_driver_nl80211_get_bssid,
12121 .get_ssid = wpa_driver_nl80211_get_ssid,
9ebce9c5
JM
12122 .set_key = driver_nl80211_set_key,
12123 .scan2 = driver_nl80211_scan2,
d21c63b9
LC
12124 .sched_scan = wpa_driver_nl80211_sched_scan,
12125 .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
3f5285e8 12126 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
9ebce9c5
JM
12127 .deauthenticate = driver_nl80211_deauthenticate,
12128 .authenticate = driver_nl80211_authenticate,
3f5285e8 12129 .associate = wpa_driver_nl80211_associate,
f2ed8023
JM
12130 .global_init = nl80211_global_init,
12131 .global_deinit = nl80211_global_deinit,
12132 .init2 = wpa_driver_nl80211_init,
9ebce9c5 12133 .deinit = driver_nl80211_deinit,
3f5285e8
JM
12134 .get_capa = wpa_driver_nl80211_get_capa,
12135 .set_operstate = wpa_driver_nl80211_set_operstate,
01652550 12136 .set_supp_port = wpa_driver_nl80211_set_supp_port,
6d158490 12137 .set_country = wpa_driver_nl80211_set_country,
f0793bf1 12138 .get_country = wpa_driver_nl80211_get_country,
19c3b566 12139 .set_ap = wpa_driver_nl80211_set_ap,
3c4ca363 12140 .set_acl = wpa_driver_nl80211_set_acl,
22a7c9d7 12141 .if_add = wpa_driver_nl80211_if_add,
9ebce9c5
JM
12142 .if_remove = driver_nl80211_if_remove,
12143 .send_mlme = driver_nl80211_send_mlme,
c3965310 12144 .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
0f4e8b4f 12145 .sta_add = wpa_driver_nl80211_sta_add,
9ebce9c5 12146 .sta_remove = driver_nl80211_sta_remove,
db149ac9 12147 .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
a8d6ffa4 12148 .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
c5121837 12149 .hapd_init = i802_init,
c5121837 12150 .hapd_deinit = i802_deinit,
f7b3920c 12151 .set_wds_sta = i802_set_wds_sta,
c5121837
JM
12152 .get_seqnum = i802_get_seqnum,
12153 .flush = i802_flush,
c5121837
JM
12154 .get_inact_sec = i802_get_inact_sec,
12155 .sta_clear_stats = i802_sta_clear_stats,
c5121837
JM
12156 .set_rts = i802_set_rts,
12157 .set_frag = i802_set_frag,
c5121837 12158 .set_tx_queue_params = i802_set_tx_queue_params,
9ebce9c5 12159 .set_sta_vlan = driver_nl80211_set_sta_vlan,
ee7ab173
JB
12160 .sta_deauth = i802_sta_deauth,
12161 .sta_disassoc = i802_sta_disassoc,
9ebce9c5 12162 .read_sta_data = driver_nl80211_read_sta_data,
e3802622 12163 .set_freq = i802_set_freq,
9ebce9c5 12164 .send_action = driver_nl80211_send_action,
5dfca53f 12165 .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
55777702
JM
12166 .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
12167 .cancel_remain_on_channel =
12168 wpa_driver_nl80211_cancel_remain_on_channel,
9ebce9c5 12169 .probe_req_report = driver_nl80211_probe_req_report,
af473088 12170 .deinit_ap = wpa_driver_nl80211_deinit_ap,
3c29244e 12171 .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
207ef3fb 12172 .resume = wpa_driver_nl80211_resume,
7b90c16a 12173 .send_ft_action = nl80211_send_ft_action,
b625473c 12174 .signal_monitor = nl80211_signal_monitor,
1c5c7273 12175 .signal_poll = nl80211_signal_poll,
b91ab76e 12176 .send_frame = nl80211_send_frame,
57ebba59 12177 .shared_freq = wpa_driver_nl80211_shared_freq,
c55f774d 12178 .set_param = nl80211_set_param,
6859f1cb 12179 .get_radio_name = nl80211_get_radio_name,
a6efc65d
JM
12180 .add_pmkid = nl80211_add_pmkid,
12181 .remove_pmkid = nl80211_remove_pmkid,
12182 .flush_pmkid = nl80211_flush_pmkid,
b14a210c 12183 .set_rekey_info = nl80211_set_rekey_info,
bcf24348 12184 .poll_client = nl80211_poll_client,
29f338af 12185 .set_p2p_powersave = nl80211_set_p2p_powersave,
f90e9c1c 12186 .start_dfs_cac = nl80211_start_radar_detection,
695c7038 12187 .stop_ap = wpa_driver_nl80211_stop_ap,
03ea1786
AN
12188#ifdef CONFIG_TDLS
12189 .send_tdls_mgmt = nl80211_send_tdls_mgmt,
12190 .tdls_oper = nl80211_tdls_oper,
12191#endif /* CONFIG_TDLS */
6a1ce395 12192 .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
597b94f5 12193 .get_mac_addr = wpa_driver_nl80211_get_macaddr,
0185007c 12194 .get_survey = wpa_driver_nl80211_get_survey,
a771c07d 12195 .status = wpa_driver_nl80211_status,
1c4ffa87 12196 .switch_channel = nl80211_switch_channel,
0de38036
JM
12197#ifdef ANDROID_P2P
12198 .set_noa = wpa_driver_set_p2p_noa,
12199 .get_noa = wpa_driver_get_p2p_noa,
12200 .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
12201#endif /* ANDROID_P2P */
5e2c3490
JM
12202#ifdef ANDROID
12203 .driver_cmd = wpa_driver_nl80211_driver_cmd,
12204#endif /* ANDROID */
adef8948 12205 .vendor_cmd = nl80211_vendor_cmd,
049105b4 12206 .set_qos_map = nl80211_set_qos_map,
3f5285e8 12207};