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