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