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