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