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