]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/drivers/driver_nl80211.c
Use wpa_key_mgmt_*() helpers
[thirdparty/hostap.git] / src / drivers / driver_nl80211.c
CommitLineData
3f5285e8 1/*
c5121837 2 * Driver interaction with Linux nl80211/cfg80211
8d923a4a 3 * Copyright (c) 2002-2010, 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
JM
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Alternatively, this software may be distributed under the terms of BSD
14 * license.
15 *
16 * See README and COPYING for more details.
17 */
18
19#include "includes.h"
20#include <sys/ioctl.h>
6859f1cb
BG
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <fcntl.h>
37b7d082 24#include <net/if.h>
3f5285e8
JM
25#include <netlink/genl/genl.h>
26#include <netlink/genl/family.h>
27#include <netlink/genl/ctrl.h>
8602b0f2 28#include <linux/rtnetlink.h>
1b648c7e
JM
29#include <netpacket/packet.h>
30#include <linux/filter.h>
7e45830a 31#include "nl80211_copy.h"
625f587b 32
3f5285e8 33#include "common.h"
1b648c7e 34#include "eloop.h"
f2ed8023 35#include "utils/list.h"
1b648c7e 36#include "common/ieee802_11_defs.h"
9b90955e 37#include "common/ieee802_11_common.h"
f10bfc9a 38#include "l2_packet/l2_packet.h"
e2d02c29 39#include "netlink.h"
34f2f814 40#include "linux_ioctl.h"
e2d02c29
JM
41#include "radiotap.h"
42#include "radiotap_iter.h"
8401a6b0 43#include "rfkill.h"
1b648c7e 44#include "driver.h"
0915d02c 45
c5121837
JM
46#ifdef CONFIG_LIBNL20
47/* libnl 2.0 compatibility code */
2e8eac2d 48#define nl_handle nl_sock
a65a9aed
JB
49#define nl80211_handle_alloc nl_socket_alloc_cb
50#define nl80211_handle_destroy nl_socket_free
51#else
52/*
53 * libnl 1.1 has a bug, it tries to allocate socket numbers densely
54 * but when you free a socket again it will mess up its bitmap and
55 * and use the wrong number the next time it needs a socket ID.
56 * Therefore, we wrap the handle alloc/destroy and add our own pid
57 * accounting.
58 */
59static uint32_t port_bitmap[32] = { 0 };
60
61static struct nl_handle *nl80211_handle_alloc(void *cb)
62{
63 struct nl_handle *handle;
64 uint32_t pid = getpid() & 0x3FFFFF;
65 int i;
66
67 handle = nl_handle_alloc_cb(cb);
68
69 for (i = 0; i < 1024; i++) {
70 if (port_bitmap[i / 32] & (1 << (i % 32)))
71 continue;
72 port_bitmap[i / 32] |= 1 << (i % 32);
73 pid += i << 22;
74 break;
75 }
76
77 nl_socket_set_local_port(handle, pid);
78
79 return handle;
80}
81
82static void nl80211_handle_destroy(struct nl_handle *handle)
83{
84 uint32_t port = nl_socket_get_local_port(handle);
85
86 port >>= 22;
87 port_bitmap[port / 32] &= ~(1 << (port % 32));
88
89 nl_handle_destroy(handle);
90}
c5121837
JM
91#endif /* CONFIG_LIBNL20 */
92
c5121837 93
a92dfde8
JB
94struct nl80211_handles {
95 struct nl_handle *handle;
a92dfde8
JB
96};
97
98
99static int nl_create_handles(struct nl80211_handles *handles, struct nl_cb *cb,
100 const char *dbg)
101{
102 if (!handles)
103 return -1;
104
105 handles->handle = nl80211_handle_alloc(cb);
106 if (handles->handle == NULL) {
107 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
108 "callbacks (%s)", dbg);
109 return -1;
110 }
111
112 if (genl_connect(handles->handle)) {
113 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
114 "netlink (%s)", dbg);
115 goto err;
116 }
117
a92dfde8
JB
118 return 0;
119err:
120 nl80211_handle_destroy(handles->handle);
121 return -1;
122}
123
124
125static void nl_destroy_handles(struct nl80211_handles *handles)
126{
127 if (handles->handle == NULL)
128 return;
a92dfde8
JB
129 nl80211_handle_destroy(handles->handle);
130 handles->handle = NULL;
131}
132
133
3f5285e8
JM
134#ifndef IFF_LOWER_UP
135#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
136#endif
137#ifndef IFF_DORMANT
138#define IFF_DORMANT 0x20000 /* driver signals dormant */
139#endif
140
141#ifndef IF_OPER_DORMANT
142#define IF_OPER_DORMANT 5
143#endif
144#ifndef IF_OPER_UP
145#define IF_OPER_UP 6
146#endif
147
f2ed8023
JM
148struct nl80211_global {
149 struct dl_list interfaces;
ff6a158b 150 int if_add_ifindex;
36d84860 151 struct netlink_data *netlink;
2a7b66f5 152 struct nl_cb *nl_cb;
276e2d67 153 struct nl80211_handles nl;
335d42b1 154 int nl80211_id;
c81eff1a 155 int ioctl_sock; /* socket for ioctl() use */
f2ed8023
JM
156};
157
36d84860 158static void nl80211_global_deinit(void *priv);
dac12351 159static void wpa_driver_nl80211_deinit(void *priv);
36d84860 160
c5121837 161struct i802_bss {
a2e40bb6 162 struct wpa_driver_nl80211_data *drv;
c5121837 163 struct i802_bss *next;
b4fd6fab 164 int ifindex;
a2e40bb6 165 char ifname[IFNAMSIZ + 1];
e17a2477 166 char brname[IFNAMSIZ];
c5121837 167 unsigned int beacon_set:1;
e17a2477
JM
168 unsigned int added_if_into_bridge:1;
169 unsigned int added_bridge:1;
221a59c9
JB
170
171 struct nl80211_handles nl_preq;
c5121837 172};
3f5285e8
JM
173
174struct wpa_driver_nl80211_data {
f2ed8023
JM
175 struct nl80211_global *global;
176 struct dl_list list;
177 u8 addr[ETH_ALEN];
6859f1cb 178 char phyname[32];
3f5285e8 179 void *ctx;
3f5285e8 180 int ifindex;
7524cfb1 181 int if_removed;
a63063b4 182 int if_disabled;
7d9c3698 183 int ignore_if_down_event;
8401a6b0 184 struct rfkill_data *rfkill;
c2a04078
JM
185 struct wpa_driver_capa capa;
186 int has_capability;
c2a04078 187
3f5285e8
JM
188 int operstate;
189
3f5285e8
JM
190 int scan_complete_events;
191
221a59c9 192 struct nl80211_handles nl_event;
1c873584 193
e6b8efeb 194 u8 auth_bssid[ETH_ALEN];
c2a04078
JM
195 u8 bssid[ETH_ALEN];
196 int associated;
fd05d64e
JM
197 u8 ssid[32];
198 size_t ssid_len;
b1f625e0
EP
199 enum nl80211_iftype nlmode;
200 enum nl80211_iftype ap_scan_as_station;
4832ecd7 201 unsigned int assoc_freq;
d2440ba0 202
0915d02c
JM
203 int monitor_sock;
204 int monitor_ifidx;
7da3abe7 205
b3af99d2 206 unsigned int disabled_11b_rates:1;
55777702 207 unsigned int pending_remain_on_chan:1;
dac12351 208 unsigned int in_interface_list:1;
61cbe2ff 209 unsigned int device_ap_sme:1;
39718852 210 unsigned int poll_command_supported:1;
55777702
JM
211
212 u64 remain_on_chan_cookie;
58f6fbe0 213 u64 send_action_cookie;
c5121837 214
5582a5d1 215 unsigned int last_mgmt_freq;
86957e62 216 unsigned int ap_oper_freq;
5582a5d1 217
3812464c
JM
218 struct wpa_driver_scan_filter *filter_ssids;
219 size_t num_filter_ssids;
220
a2e40bb6
FF
221 struct i802_bss first_bss;
222
f10bfc9a 223#ifdef CONFIG_AP
d12dab4c 224 int eapol_tx_sock;
f10bfc9a
JM
225#endif /* CONFIG_AP */
226
c5121837 227#ifdef HOSTAPD
c5121837 228 int eapol_sock; /* socket for EAPOL frames */
c5121837
JM
229
230 int default_if_indices[16];
231 int *if_indices;
232 int num_if_indices;
233
c5121837
JM
234 int last_freq;
235 int last_freq_ht;
c5121837 236#endif /* HOSTAPD */
3f5285e8
JM
237};
238
239
240static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
241 void *timeout_ctx);
b1f625e0
EP
242static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
243 enum nl80211_iftype nlmode);
362f781e 244static int
7524cfb1 245wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
d72aad94 246static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
77339912
JM
247 const u8 *addr, int cmd, u16 reason_code,
248 int local_state_change);
460456f8
JM
249static void nl80211_remove_monitor_interface(
250 struct wpa_driver_nl80211_data *drv);
88df0ef7 251static int nl80211_send_frame_cmd(struct i802_bss *bss,
5dfca53f 252 unsigned int freq, unsigned int wait,
b106173a 253 const u8 *buf, size_t buf_len, u64 *cookie,
88df0ef7 254 int no_cck, int no_ack, int offchanok);
5582a5d1 255static int wpa_driver_nl80211_probe_req_report(void *priv, int report);
0915d02c 256
072ad14c 257#ifdef HOSTAPD
2135f224
JM
258static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
259static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
97cfcf64 260static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
fbbfcbac
FF
261static int wpa_driver_nl80211_if_remove(void *priv,
262 enum wpa_driver_if_type type,
263 const char *ifname);
37eb8da9 264#else /* HOSTAPD */
bd2df892
JM
265static inline void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
266{
267}
268
269static inline void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
270{
271}
272
273static inline int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
37eb8da9
JM
274{
275 return 0;
276}
072ad14c
JM
277#endif /* HOSTAPD */
278
e3802622 279static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
4e5cb1a3
JM
280static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
281 int ifindex, int disabled);
504e905c 282
21bdbe38
JM
283static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
284
3f5285e8 285
b1f625e0
EP
286static int is_ap_interface(enum nl80211_iftype nlmode)
287{
288 return (nlmode == NL80211_IFTYPE_AP ||
289 nlmode == NL80211_IFTYPE_P2P_GO);
290}
291
292
293static int is_sta_interface(enum nl80211_iftype nlmode)
294{
295 return (nlmode == NL80211_IFTYPE_STATION ||
296 nlmode == NL80211_IFTYPE_P2P_CLIENT);
297}
298
299
b3af99d2
JM
300static int is_p2p_interface(enum nl80211_iftype nlmode)
301{
302 return (nlmode == NL80211_IFTYPE_P2P_CLIENT ||
303 nlmode == NL80211_IFTYPE_P2P_GO);
304}
305
306
f5a8d422
JM
307struct nl80211_bss_info_arg {
308 struct wpa_driver_nl80211_data *drv;
309 struct wpa_scan_results *res;
310 unsigned int assoc_freq;
20f5a4c2 311 u8 assoc_bssid[ETH_ALEN];
f5a8d422
JM
312};
313
314static int bss_info_handler(struct nl_msg *msg, void *arg);
315
316
6241fcb1
JM
317/* nl80211 code */
318static int ack_handler(struct nl_msg *msg, void *arg)
319{
320 int *err = arg;
321 *err = 0;
322 return NL_STOP;
323}
324
325static int finish_handler(struct nl_msg *msg, void *arg)
326{
8e8df255
JM
327 int *ret = arg;
328 *ret = 0;
6241fcb1
JM
329 return NL_SKIP;
330}
331
332static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
333 void *arg)
334{
335 int *ret = arg;
336 *ret = err->error;
337 return NL_SKIP;
338}
339
5b7b85f6
JM
340
341static int no_seq_check(struct nl_msg *msg, void *arg)
342{
343 return NL_OK;
344}
345
346
58f6fbe0
JM
347static int send_and_recv(struct wpa_driver_nl80211_data *drv,
348 struct nl_handle *nl_handle, struct nl_msg *msg,
349 int (*valid_handler)(struct nl_msg *, void *),
350 void *valid_data)
6241fcb1
JM
351{
352 struct nl_cb *cb;
353 int err = -ENOMEM;
354
2a7b66f5 355 cb = nl_cb_clone(drv->global->nl_cb);
6241fcb1
JM
356 if (!cb)
357 goto out;
358
58f6fbe0 359 err = nl_send_auto_complete(nl_handle, msg);
6241fcb1
JM
360 if (err < 0)
361 goto out;
362
363 err = 1;
364
365 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
8e8df255 366 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
6241fcb1
JM
367 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
368
369 if (valid_handler)
370 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
371 valid_handler, valid_data);
372
373 while (err > 0)
58f6fbe0 374 nl_recvmsgs(nl_handle, cb);
6241fcb1
JM
375 out:
376 nl_cb_put(cb);
377 nlmsg_free(msg);
378 return err;
379}
380
381
58f6fbe0
JM
382static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
383 struct nl_msg *msg,
384 int (*valid_handler)(struct nl_msg *, void *),
385 void *valid_data)
386{
276e2d67 387 return send_and_recv(drv, drv->global->nl.handle, msg, valid_handler,
58f6fbe0
JM
388 valid_data);
389}
390
391
97865538
JM
392struct family_data {
393 const char *group;
394 int id;
395};
396
397
398static int family_handler(struct nl_msg *msg, void *arg)
399{
400 struct family_data *res = arg;
401 struct nlattr *tb[CTRL_ATTR_MAX + 1];
402 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
403 struct nlattr *mcgrp;
404 int i;
405
406 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
407 genlmsg_attrlen(gnlh, 0), NULL);
408 if (!tb[CTRL_ATTR_MCAST_GROUPS])
409 return NL_SKIP;
410
411 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
412 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
413 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
414 nla_len(mcgrp), NULL);
415 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
416 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
417 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
418 res->group,
419 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
420 continue;
421 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
422 break;
423 };
424
425 return NL_SKIP;
426}
427
428
429static int nl_get_multicast_id(struct wpa_driver_nl80211_data *drv,
430 const char *family, const char *group)
431{
432 struct nl_msg *msg;
433 int ret = -1;
434 struct family_data res = { group, -ENOENT };
435
436 msg = nlmsg_alloc();
437 if (!msg)
438 return -ENOMEM;
276e2d67
BG
439 genlmsg_put(msg, 0, 0,
440 genl_ctrl_resolve(drv->global->nl.handle, "nlctrl"),
97865538
JM
441 0, 0, CTRL_CMD_GETFAMILY, 0);
442 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
443
444 ret = send_and_recv_msgs(drv, msg, family_handler, &res);
445 msg = NULL;
446 if (ret == 0)
447 ret = res.id;
448
449nla_put_failure:
450 nlmsg_free(msg);
451 return ret;
452}
453
454
9fb04070
JM
455static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
456 struct nl_msg *msg, int flags, uint8_t cmd)
457{
335d42b1 458 return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
276e2d67 459 0, flags, cmd, 0);
9fb04070
JM
460}
461
462
3f5285e8
JM
463static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
464{
a2e40bb6
FF
465 struct i802_bss *bss = priv;
466 struct wpa_driver_nl80211_data *drv = bss->drv;
c2a04078
JM
467 if (!drv->associated)
468 return -1;
469 os_memcpy(bssid, drv->bssid, ETH_ALEN);
470 return 0;
3f5285e8
JM
471}
472
473
3f5285e8
JM
474static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
475{
a2e40bb6
FF
476 struct i802_bss *bss = priv;
477 struct wpa_driver_nl80211_data *drv = bss->drv;
fd05d64e
JM
478 if (!drv->associated)
479 return -1;
480 os_memcpy(ssid, drv->ssid, drv->ssid_len);
481 return drv->ssid_len;
3f5285e8
JM
482}
483
484
7524cfb1 485static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
08063178 486 char *buf, size_t len, int del)
3f5285e8
JM
487{
488 union wpa_event_data event;
489
490 os_memset(&event, 0, sizeof(event));
491 if (len > sizeof(event.interface_status.ifname))
492 len = sizeof(event.interface_status.ifname) - 1;
493 os_memcpy(event.interface_status.ifname, buf, len);
494 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
495 EVENT_INTERFACE_ADDED;
496
497 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
498 del ? "DEL" : "NEW",
499 event.interface_status.ifname,
500 del ? "removed" : "added");
501
a2e40bb6 502 if (os_strcmp(drv->first_bss.ifname, event.interface_status.ifname) == 0) {
7524cfb1
JM
503 if (del)
504 drv->if_removed = 1;
505 else
506 drv->if_removed = 0;
507 }
508
08063178 509 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
3f5285e8
JM
510}
511
512
7524cfb1 513static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
62d680c3 514 u8 *buf, size_t len)
7524cfb1 515{
62d680c3 516 int attrlen, rta_len;
7524cfb1
JM
517 struct rtattr *attr;
518
62d680c3
JM
519 attrlen = len;
520 attr = (struct rtattr *) buf;
7524cfb1
JM
521
522 rta_len = RTA_ALIGN(sizeof(struct rtattr));
523 while (RTA_OK(attr, attrlen)) {
524 if (attr->rta_type == IFLA_IFNAME) {
a2e40bb6 525 if (os_strcmp(((char *) attr) + rta_len, drv->first_bss.ifname)
7524cfb1
JM
526 == 0)
527 return 1;
528 else
529 break;
530 }
531 attr = RTA_NEXT(attr, attrlen);
532 }
533
534 return 0;
535}
536
537
538static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
62d680c3 539 int ifindex, u8 *buf, size_t len)
7524cfb1
JM
540{
541 if (drv->ifindex == ifindex)
542 return 1;
543
62d680c3 544 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
a2e40bb6 545 drv->first_bss.ifindex = if_nametoindex(drv->first_bss.ifname);
7524cfb1
JM
546 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
547 "interface");
548 wpa_driver_nl80211_finish_drv_init(drv);
549 return 1;
550 }
551
552 return 0;
553}
554
555
36d84860
BG
556static struct wpa_driver_nl80211_data *
557nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
558{
559 struct wpa_driver_nl80211_data *drv;
560 dl_list_for_each(drv, &global->interfaces,
561 struct wpa_driver_nl80211_data, list) {
562 if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
563 have_ifidx(drv, idx))
564 return drv;
565 }
566 return NULL;
567}
568
569
62d680c3
JM
570static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
571 struct ifinfomsg *ifi,
572 u8 *buf, size_t len)
3f5285e8 573{
36d84860
BG
574 struct nl80211_global *global = ctx;
575 struct wpa_driver_nl80211_data *drv;
62d680c3
JM
576 int attrlen, rta_len;
577 struct rtattr *attr;
97cfcf64 578 u32 brid = 0;
3f5285e8 579
36d84860
BG
580 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
581 if (!drv) {
97cfcf64
B
582 wpa_printf(MSG_DEBUG, "nl80211: Ignore event for foreign "
583 "ifindex %d", ifi->ifi_index);
3f5285e8
JM
584 return;
585 }
586
587 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
588 "(%s%s%s%s)",
589 drv->operstate, ifi->ifi_flags,
590 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
591 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
592 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
593 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
a63063b4
JM
594
595 if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
59d24925
JM
596 char namebuf[IFNAMSIZ];
597 if (if_indextoname(ifi->ifi_index, namebuf) &&
598 linux_iface_up(drv->global->ioctl_sock,
599 drv->first_bss.ifname) > 0) {
600 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
601 "event since interface %s is up", namebuf);
602 return;
603 }
a63063b4 604 wpa_printf(MSG_DEBUG, "nl80211: Interface down");
7d9c3698
JM
605 if (drv->ignore_if_down_event) {
606 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
607 "event generated by mode change");
608 drv->ignore_if_down_event = 0;
609 } else {
610 drv->if_disabled = 1;
611 wpa_supplicant_event(drv->ctx,
612 EVENT_INTERFACE_DISABLED, NULL);
613 }
a63063b4
JM
614 }
615
616 if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
617 wpa_printf(MSG_DEBUG, "nl80211: Interface up");
618 drv->if_disabled = 0;
619 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
620 }
621
3f5285e8
JM
622 /*
623 * Some drivers send the association event before the operup event--in
624 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
625 * fails. This will hit us when wpa_supplicant does not need to do
626 * IEEE 802.1X authentication
627 */
628 if (drv->operstate == 1 &&
629 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
630 !(ifi->ifi_flags & IFF_RUNNING))
36d84860 631 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
e2d02c29 632 -1, IF_OPER_UP);
3f5285e8 633
62d680c3
JM
634 attrlen = len;
635 attr = (struct rtattr *) buf;
3f5285e8
JM
636 rta_len = RTA_ALIGN(sizeof(struct rtattr));
637 while (RTA_OK(attr, attrlen)) {
d8816397 638 if (attr->rta_type == IFLA_IFNAME) {
7524cfb1 639 wpa_driver_nl80211_event_link(
08063178 640 drv,
7524cfb1
JM
641 ((char *) attr) + rta_len,
642 attr->rta_len - rta_len, 0);
97cfcf64
B
643 } else if (attr->rta_type == IFLA_MASTER)
644 brid = nla_get_u32((struct nlattr *) attr);
3f5285e8
JM
645 attr = RTA_NEXT(attr, attrlen);
646 }
97cfcf64
B
647
648 if (ifi->ifi_family == AF_BRIDGE && brid) {
649 /* device has been added to bridge */
650 char namebuf[IFNAMSIZ];
651 if_indextoname(brid, namebuf);
652 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
653 brid, namebuf);
654 add_ifidx(drv, brid);
655 }
3f5285e8
JM
656}
657
658
62d680c3
JM
659static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
660 struct ifinfomsg *ifi,
661 u8 *buf, size_t len)
3f5285e8 662{
36d84860
BG
663 struct nl80211_global *global = ctx;
664 struct wpa_driver_nl80211_data *drv;
62d680c3
JM
665 int attrlen, rta_len;
666 struct rtattr *attr;
97cfcf64 667 u32 brid = 0;
3f5285e8 668
36d84860
BG
669 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
670 if (!drv) {
671 wpa_printf(MSG_DEBUG, "nl80211: Ignore dellink event for "
672 "foreign ifindex %d", ifi->ifi_index);
673 return;
674 }
675
62d680c3
JM
676 attrlen = len;
677 attr = (struct rtattr *) buf;
3f5285e8
JM
678
679 rta_len = RTA_ALIGN(sizeof(struct rtattr));
680 while (RTA_OK(attr, attrlen)) {
681 if (attr->rta_type == IFLA_IFNAME) {
7524cfb1 682 wpa_driver_nl80211_event_link(
08063178 683 drv,
7524cfb1
JM
684 ((char *) attr) + rta_len,
685 attr->rta_len - rta_len, 1);
97cfcf64
B
686 } else if (attr->rta_type == IFLA_MASTER)
687 brid = nla_get_u32((struct nlattr *) attr);
3f5285e8
JM
688 attr = RTA_NEXT(attr, attrlen);
689 }
97cfcf64
B
690
691 if (ifi->ifi_family == AF_BRIDGE && brid) {
692 /* device has been removed from bridge */
693 char namebuf[IFNAMSIZ];
694 if_indextoname(brid, namebuf);
695 wpa_printf(MSG_DEBUG, "nl80211: Remove ifindex %u for bridge "
696 "%s", brid, namebuf);
697 del_ifidx(drv, brid);
698 }
3f5285e8
JM
699}
700
701
c2a04078
JM
702static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
703 const u8 *frame, size_t len)
704{
705 const struct ieee80211_mgmt *mgmt;
706 union wpa_event_data event;
707
708 mgmt = (const struct ieee80211_mgmt *) frame;
709 if (len < 24 + sizeof(mgmt->u.auth)) {
710 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
711 "frame");
712 return;
713 }
714
e6b8efeb 715 os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
c2a04078
JM
716 os_memset(&event, 0, sizeof(event));
717 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
718 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
719 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
720 if (len > 24 + sizeof(mgmt->u.auth)) {
721 event.auth.ies = mgmt->u.auth.variable;
722 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
723 }
724
725 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
726}
727
728
f5a8d422
JM
729static unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
730{
731 struct nl_msg *msg;
732 int ret;
733 struct nl80211_bss_info_arg arg;
734
735 os_memset(&arg, 0, sizeof(arg));
736 msg = nlmsg_alloc();
737 if (!msg)
738 goto nla_put_failure;
739
9fb04070 740 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
f5a8d422
JM
741 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
742
743 arg.drv = drv;
744 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
745 msg = NULL;
746 if (ret == 0) {
747 wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
748 "associated BSS from scan results: %u MHz",
749 arg.assoc_freq);
750 return arg.assoc_freq ? arg.assoc_freq : drv->assoc_freq;
751 }
752 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
753 "(%s)", ret, strerror(-ret));
754nla_put_failure:
755 nlmsg_free(msg);
756 return drv->assoc_freq;
757}
758
759
c2a04078
JM
760static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
761 const u8 *frame, size_t len)
762{
763 const struct ieee80211_mgmt *mgmt;
764 union wpa_event_data event;
765 u16 status;
766
767 mgmt = (const struct ieee80211_mgmt *) frame;
768 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
769 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
770 "frame");
771 return;
772 }
773
774 status = le_to_host16(mgmt->u.assoc_resp.status_code);
775 if (status != WLAN_STATUS_SUCCESS) {
efa46078 776 os_memset(&event, 0, sizeof(event));
59ddf221 777 event.assoc_reject.bssid = mgmt->bssid;
efa46078
JM
778 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
779 event.assoc_reject.resp_ies =
780 (u8 *) mgmt->u.assoc_resp.variable;
781 event.assoc_reject.resp_ies_len =
782 len - 24 - sizeof(mgmt->u.assoc_resp);
783 }
784 event.assoc_reject.status_code = status;
785
786 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
c2a04078
JM
787 return;
788 }
789
790 drv->associated = 1;
791 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
792
793 os_memset(&event, 0, sizeof(event));
794 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
795 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
796 event.assoc_info.resp_ies_len =
efa46078 797 len - 24 - sizeof(mgmt->u.assoc_resp);
c2a04078
JM
798 }
799
4832ecd7
JM
800 event.assoc_info.freq = drv->assoc_freq;
801
c2a04078
JM
802 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
803}
804
c1bb3e0a 805
da72a1c1
ZY
806static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
807 enum nl80211_commands cmd, struct nlattr *status,
808 struct nlattr *addr, struct nlattr *req_ie,
809 struct nlattr *resp_ie)
810{
811 union wpa_event_data event;
812
7da2c527
JM
813 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
814 /*
815 * Avoid reporting two association events that would confuse
816 * the core code.
817 */
818 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
819 "when using userspace SME", cmd);
820 return;
821 }
822
da72a1c1
ZY
823 os_memset(&event, 0, sizeof(event));
824 if (cmd == NL80211_CMD_CONNECT &&
825 nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
df89c1c8
JM
826 if (addr)
827 event.assoc_reject.bssid = nla_data(addr);
da72a1c1
ZY
828 if (resp_ie) {
829 event.assoc_reject.resp_ies = nla_data(resp_ie);
830 event.assoc_reject.resp_ies_len = nla_len(resp_ie);
831 }
832 event.assoc_reject.status_code = nla_get_u16(status);
833 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
834 return;
835 }
836
837 drv->associated = 1;
838 if (addr)
839 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
840
841 if (req_ie) {
842 event.assoc_info.req_ies = nla_data(req_ie);
843 event.assoc_info.req_ies_len = nla_len(req_ie);
844 }
845 if (resp_ie) {
846 event.assoc_info.resp_ies = nla_data(resp_ie);
847 event.assoc_info.resp_ies_len = nla_len(resp_ie);
848 }
849
f5a8d422
JM
850 event.assoc_info.freq = nl80211_get_assoc_freq(drv);
851
da72a1c1
ZY
852 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
853}
c2a04078 854
c1bb3e0a 855
20f5a4c2
JM
856static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
857 struct nlattr *reason, struct nlattr *addr)
858{
859 union wpa_event_data data;
860
861 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
862 /*
863 * Avoid reporting two disassociation events that could
864 * confuse the core code.
865 */
866 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
867 "event when using userspace SME");
868 return;
869 }
870
871 drv->associated = 0;
872 os_memset(&data, 0, sizeof(data));
873 if (reason)
874 data.disassoc_info.reason_code = nla_get_u16(reason);
875 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
876}
877
878
da1fb17c
JM
879static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
880 enum nl80211_commands cmd, struct nlattr *addr)
881{
882 union wpa_event_data event;
883 enum wpa_event_type ev;
884
885 if (nla_len(addr) != ETH_ALEN)
886 return;
887
888 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
889 cmd, MAC2STR((u8 *) nla_data(addr)));
890
891 if (cmd == NL80211_CMD_AUTHENTICATE)
892 ev = EVENT_AUTH_TIMED_OUT;
893 else if (cmd == NL80211_CMD_ASSOCIATE)
894 ev = EVENT_ASSOC_TIMED_OUT;
895 else
896 return;
897
898 os_memset(&event, 0, sizeof(event));
899 os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
900 wpa_supplicant_event(drv->ctx, ev, &event);
901}
902
903
5582a5d1
JB
904static void mlme_event_mgmt(struct wpa_driver_nl80211_data *drv,
905 struct nlattr *freq, const u8 *frame, size_t len)
58f6fbe0
JM
906{
907 const struct ieee80211_mgmt *mgmt;
908 union wpa_event_data event;
909 u16 fc, stype;
910
911 mgmt = (const struct ieee80211_mgmt *) frame;
912 if (len < 24) {
913 wpa_printf(MSG_DEBUG, "nl80211: Too short action frame");
914 return;
915 }
916
917 fc = le_to_host16(mgmt->frame_control);
918 stype = WLAN_FC_GET_STYPE(fc);
919
920 os_memset(&event, 0, sizeof(event));
5582a5d1 921 if (freq) {
58f6fbe0 922 event.rx_action.freq = nla_get_u32(freq);
5582a5d1
JB
923 drv->last_mgmt_freq = event.rx_action.freq;
924 }
925 if (stype == WLAN_FC_STYPE_ACTION) {
926 event.rx_action.da = mgmt->da;
927 event.rx_action.sa = mgmt->sa;
928 event.rx_action.bssid = mgmt->bssid;
929 event.rx_action.category = mgmt->u.action.category;
930 event.rx_action.data = &mgmt->u.action.category + 1;
931 event.rx_action.len = frame + len - event.rx_action.data;
932 wpa_supplicant_event(drv->ctx, EVENT_RX_ACTION, &event);
933 } else {
934 event.rx_mgmt.frame = frame;
935 event.rx_mgmt.frame_len = len;
936 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
937 }
58f6fbe0
JM
938}
939
940
941static void mlme_event_action_tx_status(struct wpa_driver_nl80211_data *drv,
942 struct nlattr *cookie, const u8 *frame,
943 size_t len, struct nlattr *ack)
944{
945 union wpa_event_data event;
946 const struct ieee80211_hdr *hdr;
947 u16 fc;
948 u64 cookie_val;
949
950 if (!cookie)
951 return;
952
953 cookie_val = nla_get_u64(cookie);
4796272f
JM
954 wpa_printf(MSG_DEBUG, "nl80211: Action TX status: cookie=0%llx%s "
955 "(ack=%d)",
58f6fbe0
JM
956 (long long unsigned int) cookie_val,
957 cookie_val == drv->send_action_cookie ?
4796272f 958 " (match)" : " (unknown)", ack != NULL);
58f6fbe0
JM
959 if (cookie_val != drv->send_action_cookie)
960 return;
961
962 hdr = (const struct ieee80211_hdr *) frame;
963 fc = le_to_host16(hdr->frame_control);
964
965 os_memset(&event, 0, sizeof(event));
966 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
967 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
968 event.tx_status.dst = hdr->addr1;
969 event.tx_status.data = frame;
970 event.tx_status.data_len = len;
971 event.tx_status.ack = ack != NULL;
972 wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
973}
974
975
0544b242
JM
976static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
977 enum wpa_event_type type,
978 const u8 *frame, size_t len)
979{
980 const struct ieee80211_mgmt *mgmt;
981 union wpa_event_data event;
982 const u8 *bssid = NULL;
983 u16 reason_code = 0;
984
cb30b297
PS
985 mgmt = (const struct ieee80211_mgmt *) frame;
986 if (len >= 24) {
987 bssid = mgmt->bssid;
988
989 if (drv->associated != 0 &&
990 os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
991 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
992 /*
993 * We have presumably received this deauth as a
994 * response to a clear_state_mismatch() outgoing
995 * deauth. Don't let it take us offline!
996 */
997 wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
998 "from Unknown BSSID " MACSTR " -- ignoring",
999 MAC2STR(bssid));
1000 return;
1001 }
1002 }
1003
0544b242
JM
1004 drv->associated = 0;
1005 os_memset(&event, 0, sizeof(event));
1006
0544b242
JM
1007 /* Note: Same offset for Reason Code in both frame subtypes */
1008 if (len >= 24 + sizeof(mgmt->u.deauth))
1009 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1010
1011 if (type == EVENT_DISASSOC) {
1012 event.disassoc_info.addr = bssid;
1013 event.disassoc_info.reason_code = reason_code;
046b26a2
JM
1014 if (frame + len > mgmt->u.disassoc.variable) {
1015 event.disassoc_info.ie = mgmt->u.disassoc.variable;
1016 event.disassoc_info.ie_len = frame + len -
1017 mgmt->u.disassoc.variable;
1018 }
0544b242
JM
1019 } else {
1020 event.deauth_info.addr = bssid;
1021 event.deauth_info.reason_code = reason_code;
046b26a2
JM
1022 if (frame + len > mgmt->u.deauth.variable) {
1023 event.deauth_info.ie = mgmt->u.deauth.variable;
1024 event.deauth_info.ie_len = frame + len -
1025 mgmt->u.deauth.variable;
1026 }
0544b242
JM
1027 }
1028
1029 wpa_supplicant_event(drv->ctx, type, &event);
1030}
1031
1032
7d878ca7
JM
1033static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
1034 enum wpa_event_type type,
1035 const u8 *frame, size_t len)
1036{
1037 const struct ieee80211_mgmt *mgmt;
1038 union wpa_event_data event;
1039 u16 reason_code = 0;
1040
1041 if (len < 24)
1042 return;
1043
1044 mgmt = (const struct ieee80211_mgmt *) frame;
1045
1046 os_memset(&event, 0, sizeof(event));
1047 /* Note: Same offset for Reason Code in both frame subtypes */
1048 if (len >= 24 + sizeof(mgmt->u.deauth))
1049 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1050
1051 if (type == EVENT_UNPROT_DISASSOC) {
1052 event.unprot_disassoc.sa = mgmt->sa;
1053 event.unprot_disassoc.da = mgmt->da;
1054 event.unprot_disassoc.reason_code = reason_code;
1055 } else {
1056 event.unprot_deauth.sa = mgmt->sa;
1057 event.unprot_deauth.da = mgmt->da;
1058 event.unprot_deauth.reason_code = reason_code;
1059 }
1060
1061 wpa_supplicant_event(drv->ctx, type, &event);
1062}
1063
1064
c2a04078 1065static void mlme_event(struct wpa_driver_nl80211_data *drv,
da1fb17c 1066 enum nl80211_commands cmd, struct nlattr *frame,
58f6fbe0
JM
1067 struct nlattr *addr, struct nlattr *timed_out,
1068 struct nlattr *freq, struct nlattr *ack,
1069 struct nlattr *cookie)
c2a04078 1070{
da1fb17c
JM
1071 if (timed_out && addr) {
1072 mlme_timeout_event(drv, cmd, addr);
1073 return;
1074 }
1075
c2a04078
JM
1076 if (frame == NULL) {
1077 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
1078 "data", cmd);
1079 return;
1080 }
1081
1082 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d", cmd);
1083 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
1084 nla_data(frame), nla_len(frame));
1085
1086 switch (cmd) {
1087 case NL80211_CMD_AUTHENTICATE:
1088 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
1089 break;
1090 case NL80211_CMD_ASSOCIATE:
1091 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
1092 break;
1093 case NL80211_CMD_DEAUTHENTICATE:
0544b242
JM
1094 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
1095 nla_data(frame), nla_len(frame));
c2a04078
JM
1096 break;
1097 case NL80211_CMD_DISASSOCIATE:
0544b242
JM
1098 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
1099 nla_data(frame), nla_len(frame));
c2a04078 1100 break;
bd94971e 1101 case NL80211_CMD_FRAME:
5582a5d1 1102 mlme_event_mgmt(drv, freq, nla_data(frame), nla_len(frame));
58f6fbe0 1103 break;
bd94971e 1104 case NL80211_CMD_FRAME_TX_STATUS:
58f6fbe0
JM
1105 mlme_event_action_tx_status(drv, cookie, nla_data(frame),
1106 nla_len(frame), ack);
1107 break;
7d878ca7
JM
1108 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
1109 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
1110 nla_data(frame), nla_len(frame));
1111 break;
1112 case NL80211_CMD_UNPROT_DISASSOCIATE:
1113 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
1114 nla_data(frame), nla_len(frame));
1115 break;
c2a04078
JM
1116 default:
1117 break;
1118 }
1119}
1120
1121
35583f3f
JM
1122static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv,
1123 struct nlattr *tb[])
1124{
1125 union wpa_event_data data;
1126
1127 wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
1128 os_memset(&data, 0, sizeof(data));
1129 if (tb[NL80211_ATTR_MAC]) {
1130 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
1131 nla_data(tb[NL80211_ATTR_MAC]),
1132 nla_len(tb[NL80211_ATTR_MAC]));
ad1e68e6 1133 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
35583f3f
JM
1134 }
1135 if (tb[NL80211_ATTR_KEY_SEQ]) {
1136 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
1137 nla_data(tb[NL80211_ATTR_KEY_SEQ]),
1138 nla_len(tb[NL80211_ATTR_KEY_SEQ]));
1139 }
1140 if (tb[NL80211_ATTR_KEY_TYPE]) {
1141 enum nl80211_key_type key_type =
1142 nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
1143 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
1144 if (key_type == NL80211_KEYTYPE_PAIRWISE)
1145 data.michael_mic_failure.unicast = 1;
1146 } else
1147 data.michael_mic_failure.unicast = 1;
1148
1149 if (tb[NL80211_ATTR_KEY_IDX]) {
1150 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
1151 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
1152 }
1153
1154 wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
1155}
1156
1157
5cc4d64b
JM
1158static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
1159 struct nlattr *tb[])
1160{
1161 if (tb[NL80211_ATTR_MAC] == NULL) {
1162 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
1163 "event");
1164 return;
1165 }
1166 os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1167 drv->associated = 1;
1168 wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
1169 MAC2STR(drv->bssid));
1170
1171 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
1172}
1173
1174
55777702
JM
1175static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
1176 int cancel_event, struct nlattr *tb[])
1177{
1178 unsigned int freq, chan_type, duration;
1179 union wpa_event_data data;
1180 u64 cookie;
1181
1182 if (tb[NL80211_ATTR_WIPHY_FREQ])
1183 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1184 else
1185 freq = 0;
1186
1187 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
1188 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1189 else
1190 chan_type = 0;
1191
1192 if (tb[NL80211_ATTR_DURATION])
1193 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
1194 else
1195 duration = 0;
1196
1197 if (tb[NL80211_ATTR_COOKIE])
1198 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
1199 else
1200 cookie = 0;
1201
1202 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
1203 "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
1204 cancel_event, freq, chan_type, duration,
1205 (long long unsigned int) cookie,
1206 cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
1207
1208 if (cookie != drv->remain_on_chan_cookie)
1209 return; /* not for us */
1210
531f0331
JB
1211 if (cancel_event)
1212 drv->pending_remain_on_chan = 0;
55777702
JM
1213
1214 os_memset(&data, 0, sizeof(data));
1215 data.remain_on_channel.freq = freq;
1216 data.remain_on_channel.duration = duration;
1217 wpa_supplicant_event(drv->ctx, cancel_event ?
1218 EVENT_CANCEL_REMAIN_ON_CHANNEL :
1219 EVENT_REMAIN_ON_CHANNEL, &data);
1220}
1221
1222
8d923a4a
JM
1223static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
1224 struct nlattr *tb[])
1225{
1226 union wpa_event_data event;
1227 struct nlattr *nl;
1228 int rem;
1229 struct scan_info *info;
1230#define MAX_REPORT_FREQS 50
1231 int freqs[MAX_REPORT_FREQS];
1232 int num_freqs = 0;
1233
1234 os_memset(&event, 0, sizeof(event));
1235 info = &event.scan_info;
1236 info->aborted = aborted;
1237
1238 if (tb[NL80211_ATTR_SCAN_SSIDS]) {
1239 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
1240 struct wpa_driver_scan_ssid *s =
1241 &info->ssids[info->num_ssids];
1242 s->ssid = nla_data(nl);
1243 s->ssid_len = nla_len(nl);
1244 info->num_ssids++;
1245 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
1246 break;
1247 }
1248 }
1249 if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
1250 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
1251 {
1252 freqs[num_freqs] = nla_get_u32(nl);
1253 num_freqs++;
1254 if (num_freqs == MAX_REPORT_FREQS - 1)
1255 break;
1256 }
1257 info->freqs = freqs;
1258 info->num_freqs = num_freqs;
1259 }
1260 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
1261}
1262
1263
60a972a6
JM
1264static int get_link_signal(struct nl_msg *msg, void *arg)
1265{
1266 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1267 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1268 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
1269 static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
1270 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
1271 };
7ee35bf3
PS
1272 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
1273 static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
1274 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
1275 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
1276 [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
1277 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
1278 };
1c5c7273 1279 struct wpa_signal_info *sig_change = arg;
60a972a6
JM
1280
1281 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1282 genlmsg_attrlen(gnlh, 0), NULL);
1283 if (!tb[NL80211_ATTR_STA_INFO] ||
1284 nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
1285 tb[NL80211_ATTR_STA_INFO], policy))
1286 return NL_SKIP;
1287 if (!sinfo[NL80211_STA_INFO_SIGNAL])
1288 return NL_SKIP;
1289
7ee35bf3
PS
1290 sig_change->current_signal =
1291 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
1292
1293 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
1294 if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
1295 sinfo[NL80211_STA_INFO_TX_BITRATE],
1296 rate_policy)) {
1297 sig_change->current_txrate = 0;
1298 } else {
1299 if (rinfo[NL80211_RATE_INFO_BITRATE]) {
1300 sig_change->current_txrate =
1301 nla_get_u16(rinfo[
1302 NL80211_RATE_INFO_BITRATE]) * 100;
1303 }
1304 }
1305 }
1306
60a972a6
JM
1307 return NL_SKIP;
1308}
1309
1310
1311static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
1c5c7273 1312 struct wpa_signal_info *sig)
60a972a6
JM
1313{
1314 struct nl_msg *msg;
1315
7ee35bf3
PS
1316 sig->current_signal = -9999;
1317 sig->current_txrate = 0;
60a972a6
JM
1318
1319 msg = nlmsg_alloc();
1320 if (!msg)
1321 return -ENOMEM;
1322
9fb04070 1323 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
60a972a6
JM
1324
1325 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1326 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
1327
1328 return send_and_recv_msgs(drv, msg, get_link_signal, sig);
1329 nla_put_failure:
1330 return -ENOBUFS;
1331}
1332
1333
7ee35bf3
PS
1334static int get_link_noise(struct nl_msg *msg, void *arg)
1335{
1336 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1337 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1338 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
1339 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
1340 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
1341 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
1342 };
1c5c7273 1343 struct wpa_signal_info *sig_change = arg;
7ee35bf3
PS
1344
1345 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1346 genlmsg_attrlen(gnlh, 0), NULL);
1347
1348 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
1349 wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
1350 return NL_SKIP;
1351 }
1352
1353 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
1354 tb[NL80211_ATTR_SURVEY_INFO],
1355 survey_policy)) {
1356 wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
1357 "attributes!");
1358 return NL_SKIP;
1359 }
1360
1361 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
1362 return NL_SKIP;
1363
1364 if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
1365 sig_change->frequency)
1366 return NL_SKIP;
1367
1368 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
1369 return NL_SKIP;
1370
1371 sig_change->current_noise =
1372 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
1373
1374 return NL_SKIP;
1375}
1376
1377
1378static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
1c5c7273 1379 struct wpa_signal_info *sig_change)
7ee35bf3
PS
1380{
1381 struct nl_msg *msg;
1382
1383 sig_change->current_noise = 9999;
1384 sig_change->frequency = drv->assoc_freq;
1385
1386 msg = nlmsg_alloc();
1387 if (!msg)
1388 return -ENOMEM;
1389
9fb04070 1390 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
7ee35bf3
PS
1391
1392 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1393
1394 return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
1395 nla_put_failure:
1396 return -ENOBUFS;
1397}
1398
1399
577db0ae
GM
1400static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
1401{
1402 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1403 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1404 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
1405 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
1406 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
1407 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
1408 };
1409 struct wpa_scan_results *scan_results = arg;
1410 struct wpa_scan_res *scan_res;
1411 size_t i;
1412
1413 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1414 genlmsg_attrlen(gnlh, 0), NULL);
1415
1416 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
1417 wpa_printf(MSG_DEBUG, "nl80211: Survey data missing");
1418 return NL_SKIP;
1419 }
1420
1421 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
1422 tb[NL80211_ATTR_SURVEY_INFO],
1423 survey_policy)) {
1424 wpa_printf(MSG_DEBUG, "nl80211: Failed to parse nested "
1425 "attributes");
1426 return NL_SKIP;
1427 }
1428
1429 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
1430 return NL_SKIP;
1431
1432 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
1433 return NL_SKIP;
1434
1435 for (i = 0; i < scan_results->num; ++i) {
1436 scan_res = scan_results->res[i];
1437 if (!scan_res)
1438 continue;
1439 if ((int) nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
1440 scan_res->freq)
1441 continue;
1442 if (!(scan_res->flags & WPA_SCAN_NOISE_INVALID))
1443 continue;
1444 scan_res->noise = (s8)
1445 nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
1446 scan_res->flags &= ~WPA_SCAN_NOISE_INVALID;
1447 }
1448
1449 return NL_SKIP;
1450}
1451
1452
1453static int nl80211_get_noise_for_scan_results(
1454 struct wpa_driver_nl80211_data *drv,
1455 struct wpa_scan_results *scan_res)
1456{
1457 struct nl_msg *msg;
1458
1459 msg = nlmsg_alloc();
1460 if (!msg)
1461 return -ENOMEM;
1462
1463 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
1464
1465 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1466
1467 return send_and_recv_msgs(drv, msg, get_noise_for_scan_results,
1468 scan_res);
1469 nla_put_failure:
1470 return -ENOBUFS;
1471}
1472
1473
93910401
JM
1474static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
1475 struct nlattr *tb[])
1476{
1477 static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
1478 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
1479 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
1480 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
0d7e5a3a 1481 [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
93910401
JM
1482 };
1483 struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
1484 enum nl80211_cqm_rssi_threshold_event event;
b625473c 1485 union wpa_event_data ed;
1c5c7273 1486 struct wpa_signal_info sig;
7ee35bf3 1487 int res;
93910401
JM
1488
1489 if (tb[NL80211_ATTR_CQM] == NULL ||
1490 nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
1491 cqm_policy)) {
1492 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
1493 return;
1494 }
1495
0d7e5a3a
JB
1496 os_memset(&ed, 0, sizeof(ed));
1497
1498 if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
1499 if (!tb[NL80211_ATTR_MAC])
1500 return;
1501 os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
1502 ETH_ALEN);
1503 wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
1504 return;
1505 }
1506
93910401
JM
1507 if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
1508 return;
1509 event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
b625473c 1510
93910401
JM
1511 if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
1512 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1513 "event: RSSI high");
b625473c 1514 ed.signal_change.above_threshold = 1;
93910401
JM
1515 } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
1516 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1517 "event: RSSI low");
b625473c
JM
1518 ed.signal_change.above_threshold = 0;
1519 } else
1520 return;
1521
60a972a6
JM
1522 res = nl80211_get_link_signal(drv, &sig);
1523 if (res == 0) {
7ee35bf3
PS
1524 ed.signal_change.current_signal = sig.current_signal;
1525 ed.signal_change.current_txrate = sig.current_txrate;
1526 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm txrate: %d",
1527 sig.current_signal, sig.current_txrate);
1528 }
1529
1530 res = nl80211_get_link_noise(drv, &sig);
1531 if (res == 0) {
1532 ed.signal_change.current_noise = sig.current_noise;
1533 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
1534 sig.current_noise);
60a972a6
JM
1535 }
1536
b625473c 1537 wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
93910401
JM
1538}
1539
1540
18d2ba08
JM
1541static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
1542 struct nlattr **tb)
1543{
1544 u8 *addr;
1545 union wpa_event_data data;
1546
1547 if (tb[NL80211_ATTR_MAC] == NULL)
1548 return;
1549 addr = nla_data(tb[NL80211_ATTR_MAC]);
1550 wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
5f310a9e 1551
61cbe2ff 1552 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
5f310a9e
JM
1553 u8 *ies = NULL;
1554 size_t ies_len = 0;
1555 if (tb[NL80211_ATTR_IE]) {
1556 ies = nla_data(tb[NL80211_ATTR_IE]);
1557 ies_len = nla_len(tb[NL80211_ATTR_IE]);
1558 }
1559 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
1560 drv_event_assoc(drv->ctx, addr, ies, ies_len, 0);
1561 return;
1562 }
1563
18d2ba08
JM
1564 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1565 return;
1566
1567 os_memset(&data, 0, sizeof(data));
1568 os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
1569 wpa_supplicant_event(drv->ctx, EVENT_IBSS_RSN_START, &data);
1570}
1571
1572
ef985058
JM
1573static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
1574 struct nlattr **tb)
1575{
1576 u8 *addr;
1577 union wpa_event_data data;
1578
1579 if (tb[NL80211_ATTR_MAC] == NULL)
1580 return;
1581 addr = nla_data(tb[NL80211_ATTR_MAC]);
1582 wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
1583 MAC2STR(addr));
5f310a9e 1584
61cbe2ff 1585 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
5f310a9e
JM
1586 drv_event_disassoc(drv->ctx, addr);
1587 return;
1588 }
1589
ef985058
JM
1590 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1591 return;
1592
1593 os_memset(&data, 0, sizeof(data));
1594 os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
1595 wpa_supplicant_event(drv->ctx, EVENT_IBSS_PEER_LOST, &data);
1596}
1597
1598
b14a210c
JB
1599static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
1600 struct nlattr **tb)
1601{
1602 struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
1603 static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
1604 [NL80211_REKEY_DATA_KEK] = {
1605 .minlen = NL80211_KEK_LEN,
1606 .maxlen = NL80211_KEK_LEN,
1607 },
1608 [NL80211_REKEY_DATA_KCK] = {
1609 .minlen = NL80211_KCK_LEN,
1610 .maxlen = NL80211_KCK_LEN,
1611 },
1612 [NL80211_REKEY_DATA_REPLAY_CTR] = {
1613 .minlen = NL80211_REPLAY_CTR_LEN,
1614 .maxlen = NL80211_REPLAY_CTR_LEN,
1615 },
1616 };
1617 union wpa_event_data data;
1618
1619 if (!tb[NL80211_ATTR_MAC])
1620 return;
1621 if (!tb[NL80211_ATTR_REKEY_DATA])
1622 return;
1623 if (nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
1624 tb[NL80211_ATTR_REKEY_DATA], rekey_policy))
1625 return;
1626 if (!rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
1627 return;
1628
1629 os_memset(&data, 0, sizeof(data));
1630 data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
1631 wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
1632 MAC2STR(data.driver_gtk_rekey.bssid));
1633 data.driver_gtk_rekey.replay_ctr =
1634 nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
1635 wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
1636 data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
1637 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
1638}
1639
1640
c36d5242
JM
1641static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
1642 struct nlattr **tb)
1643{
1644 struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
1645 static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
1646 [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
1647 [NL80211_PMKSA_CANDIDATE_BSSID] = {
1648 .minlen = ETH_ALEN,
1649 .maxlen = ETH_ALEN,
1650 },
1651 [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
1652 };
1653 union wpa_event_data data;
1654
1655 if (!tb[NL80211_ATTR_PMKSA_CANDIDATE])
1656 return;
1657 if (nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
1658 tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy))
1659 return;
1660 if (!cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
1661 !cand[NL80211_PMKSA_CANDIDATE_BSSID])
1662 return;
1663
1664 os_memset(&data, 0, sizeof(data));
1665 os_memcpy(data.pmkid_candidate.bssid,
1666 nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
1667 data.pmkid_candidate.index =
1668 nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
1669 data.pmkid_candidate.preauth =
1670 cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
1671 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
1672}
1673
1674
39718852
JB
1675static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
1676 struct nlattr **tb)
1677{
1678 union wpa_event_data data;
1679
1680 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
1681 return;
1682
1683 os_memset(&data, 0, sizeof(data));
1684 os_memcpy(data.client_poll.addr,
1685 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1686
1687 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
1688}
1689
1690
97865538
JM
1691static int process_event(struct nl_msg *msg, void *arg)
1692{
1693 struct wpa_driver_nl80211_data *drv = arg;
1694 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1695 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1696
1697 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1698 genlmsg_attrlen(gnlh, 0), NULL);
1699
1700 if (tb[NL80211_ATTR_IFINDEX]) {
1701 int ifindex = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
97cfcf64 1702 if (ifindex != drv->ifindex && !have_ifidx(drv, ifindex)) {
97865538
JM
1703 wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d)"
1704 " for foreign interface (ifindex %d)",
1705 gnlh->cmd, ifindex);
1706 return NL_SKIP;
1707 }
1708 }
1709
b1f625e0 1710 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
ad1e68e6
JM
1711 (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
1712 gnlh->cmd == NL80211_CMD_SCAN_ABORTED)) {
a2e40bb6 1713 wpa_driver_nl80211_set_mode(&drv->first_bss,
b1f625e0
EP
1714 drv->ap_scan_as_station);
1715 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
ad1e68e6
JM
1716 }
1717
97865538 1718 switch (gnlh->cmd) {
d942a79e
JM
1719 case NL80211_CMD_TRIGGER_SCAN:
1720 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger");
1721 break;
d21c63b9
LC
1722 case NL80211_CMD_START_SCHED_SCAN:
1723 wpa_printf(MSG_DEBUG, "nl80211: Sched scan started");
1724 break;
1725 case NL80211_CMD_SCHED_SCAN_STOPPED:
1726 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stopped");
1727 wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
1728 break;
97865538
JM
1729 case NL80211_CMD_NEW_SCAN_RESULTS:
1730 wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
1731 drv->scan_complete_events = 1;
1732 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
1733 drv->ctx);
8d923a4a 1734 send_scan_event(drv, 0, tb);
97865538 1735 break;
d21c63b9
LC
1736 case NL80211_CMD_SCHED_SCAN_RESULTS:
1737 wpa_printf(MSG_DEBUG,
1738 "nl80211: New sched scan results available");
1739 send_scan_event(drv, 0, tb);
1740 break;
97865538
JM
1741 case NL80211_CMD_SCAN_ABORTED:
1742 wpa_printf(MSG_DEBUG, "nl80211: Scan aborted");
1743 /*
1744 * Need to indicate that scan results are available in order
1745 * not to make wpa_supplicant stop its scanning.
1746 */
1747 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
1748 drv->ctx);
8d923a4a 1749 send_scan_event(drv, 1, tb);
97865538 1750 break;
c2a04078
JM
1751 case NL80211_CMD_AUTHENTICATE:
1752 case NL80211_CMD_ASSOCIATE:
1753 case NL80211_CMD_DEAUTHENTICATE:
1754 case NL80211_CMD_DISASSOCIATE:
bd94971e
JB
1755 case NL80211_CMD_FRAME:
1756 case NL80211_CMD_FRAME_TX_STATUS:
7d878ca7
JM
1757 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
1758 case NL80211_CMD_UNPROT_DISASSOCIATE:
da1fb17c 1759 mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME],
58f6fbe0
JM
1760 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
1761 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
1762 tb[NL80211_ATTR_COOKIE]);
c2a04078 1763 break;
da72a1c1
ZY
1764 case NL80211_CMD_CONNECT:
1765 case NL80211_CMD_ROAM:
1766 mlme_event_connect(drv, gnlh->cmd,
1767 tb[NL80211_ATTR_STATUS_CODE],
1768 tb[NL80211_ATTR_MAC],
1769 tb[NL80211_ATTR_REQ_IE],
1770 tb[NL80211_ATTR_RESP_IE]);
1771 break;
1772 case NL80211_CMD_DISCONNECT:
20f5a4c2
JM
1773 mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
1774 tb[NL80211_ATTR_MAC]);
da72a1c1 1775 break;
35583f3f
JM
1776 case NL80211_CMD_MICHAEL_MIC_FAILURE:
1777 mlme_event_michael_mic_failure(drv, tb);
1778 break;
5cc4d64b
JM
1779 case NL80211_CMD_JOIN_IBSS:
1780 mlme_event_join_ibss(drv, tb);
1781 break;
55777702
JM
1782 case NL80211_CMD_REMAIN_ON_CHANNEL:
1783 mlme_event_remain_on_channel(drv, 0, tb);
1784 break;
1785 case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
1786 mlme_event_remain_on_channel(drv, 1, tb);
1787 break;
93910401
JM
1788 case NL80211_CMD_NOTIFY_CQM:
1789 nl80211_cqm_event(drv, tb);
1790 break;
33c5deb8
JM
1791 case NL80211_CMD_REG_CHANGE:
1792 wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
1793 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
1794 NULL);
1795 break;
1796 case NL80211_CMD_REG_BEACON_HINT:
1797 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
1798 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
1799 NULL);
1800 break;
18d2ba08
JM
1801 case NL80211_CMD_NEW_STATION:
1802 nl80211_new_station_event(drv, tb);
1803 break;
ef985058
JM
1804 case NL80211_CMD_DEL_STATION:
1805 nl80211_del_station_event(drv, tb);
1806 break;
b14a210c
JB
1807 case NL80211_CMD_SET_REKEY_OFFLOAD:
1808 nl80211_rekey_offload_event(drv, tb);
1809 break;
c36d5242
JM
1810 case NL80211_CMD_PMKSA_CANDIDATE:
1811 nl80211_pmksa_candidate_event(drv, tb);
1812 break;
39718852
JB
1813 case NL80211_CMD_PROBE_CLIENT:
1814 nl80211_client_probe_event(drv, tb);
1815 break;
97865538 1816 default:
c2a04078
JM
1817 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
1818 "(cmd=%d)", gnlh->cmd);
97865538
JM
1819 break;
1820 }
1821
1822 return NL_SKIP;
1823}
1824
1825
1826static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
5582a5d1 1827 void *handle)
97865538
JM
1828{
1829 struct nl_cb *cb;
1830 struct wpa_driver_nl80211_data *drv = eloop_ctx;
1831
1832 wpa_printf(MSG_DEBUG, "nl80211: Event message available");
1833
2a7b66f5 1834 cb = nl_cb_clone(drv->global->nl_cb);
97865538
JM
1835 if (!cb)
1836 return;
1837 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
1838 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv);
5582a5d1 1839 nl_recvmsgs(handle, cb);
97865538
JM
1840 nl_cb_put(cb);
1841}
1842
1843
6d158490
LR
1844/**
1845 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
1846 * @priv: driver_nl80211 private data
1847 * @alpha2_arg: country to which to switch to
1848 * Returns: 0 on success, -1 on failure
1849 *
1850 * This asks nl80211 to set the regulatory domain for given
1851 * country ISO / IEC alpha2.
1852 */
1853static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
1854{
a2e40bb6
FF
1855 struct i802_bss *bss = priv;
1856 struct wpa_driver_nl80211_data *drv = bss->drv;
6d158490
LR
1857 char alpha2[3];
1858 struct nl_msg *msg;
1859
1860 msg = nlmsg_alloc();
1861 if (!msg)
e785c2ba 1862 return -ENOMEM;
6d158490
LR
1863
1864 alpha2[0] = alpha2_arg[0];
1865 alpha2[1] = alpha2_arg[1];
1866 alpha2[2] = '\0';
1867
9fb04070 1868 nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG);
6d158490
LR
1869
1870 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
1871 if (send_and_recv_msgs(drv, msg, NULL, NULL))
1872 return -EINVAL;
1873 return 0;
1874nla_put_failure:
1875 return -EINVAL;
1876}
1877
1878
80bc75f1 1879struct wiphy_info_data {
e8b5e24e
JB
1880 struct wpa_driver_capa *capa;
1881
1882 unsigned int error:1;
61cbe2ff 1883 unsigned int device_ap_sme:1;
39718852 1884 unsigned int poll_command_supported:1;
80bc75f1
JM
1885};
1886
1887
1888static int wiphy_info_handler(struct nl_msg *msg, void *arg)
1889{
1890 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1891 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1892 struct wiphy_info_data *info = arg;
9f51b113 1893 int p2p_go_supported = 0, p2p_client_supported = 0;
e8b5e24e
JB
1894 int p2p_concurrent = 0;
1895 int auth_supported = 0, connect_supported = 0;
1896 struct wpa_driver_capa *capa = info->capa;
7626850d
JB
1897 static struct nla_policy
1898 iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
1899 [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
1900 [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
1901 [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
1902 [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
1903 },
1904 iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
1905 [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
1906 [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
1907 };
80bc75f1
JM
1908
1909 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1910 genlmsg_attrlen(gnlh, 0), NULL);
1911
1912 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
e8b5e24e 1913 capa->max_scan_ssids =
80bc75f1
JM
1914 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
1915
d21c63b9 1916 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
e8b5e24e 1917 capa->max_sched_scan_ssids =
d21c63b9
LC
1918 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
1919
bd525934 1920 if (tb[NL80211_ATTR_MAX_MATCH_SETS])
e8b5e24e 1921 capa->max_match_sets =
bd525934
LC
1922 nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
1923
1581b38b
JM
1924 if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
1925 struct nlattr *nl_mode;
1926 int i;
1927 nla_for_each_nested(nl_mode,
1928 tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
58708b3b 1929 switch (nla_type(nl_mode)) {
9f51b113 1930 case NL80211_IFTYPE_AP:
e8b5e24e 1931 capa->flags |= WPA_DRIVER_FLAGS_AP;
1581b38b 1932 break;
9f51b113
JB
1933 case NL80211_IFTYPE_P2P_GO:
1934 p2p_go_supported = 1;
1935 break;
1936 case NL80211_IFTYPE_P2P_CLIENT:
1937 p2p_client_supported = 1;
1938 break;
1581b38b
JM
1939 }
1940 }
1941 }
1942
7626850d
JB
1943 if (tb[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
1944 struct nlattr *nl_combi;
1945 int rem_combi;
1946
1947 nla_for_each_nested(nl_combi,
1948 tb[NL80211_ATTR_INTERFACE_COMBINATIONS],
1949 rem_combi) {
1950 struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
1951 struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
1952 struct nlattr *nl_limit, *nl_mode;
1953 int err, rem_limit, rem_mode;
1954 int combination_has_p2p = 0, combination_has_mgd = 0;
1955
1956 err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
1957 nl_combi,
1958 iface_combination_policy);
1959 if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
1960 !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
1961 !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
1962 goto broken_combination;
1963
1964 nla_for_each_nested(nl_limit,
1965 tb_comb[NL80211_IFACE_COMB_LIMITS],
1966 rem_limit) {
1967 err = nla_parse_nested(tb_limit,
1968 MAX_NL80211_IFACE_LIMIT,
1969 nl_limit,
1970 iface_limit_policy);
1971 if (err ||
1972 !tb_limit[NL80211_IFACE_LIMIT_TYPES])
1973 goto broken_combination;
1974
1975 nla_for_each_nested(
1976 nl_mode,
1977 tb_limit[NL80211_IFACE_LIMIT_TYPES],
1978 rem_mode) {
1979 int ift = nla_type(nl_mode);
1980 if (ift == NL80211_IFTYPE_P2P_GO ||
1981 ift == NL80211_IFTYPE_P2P_CLIENT)
1982 combination_has_p2p = 1;
1983 if (ift == NL80211_IFTYPE_STATION)
1984 combination_has_mgd = 1;
1985 }
1986 if (combination_has_p2p && combination_has_mgd)
1987 break;
1988 }
1989
1990 if (combination_has_p2p && combination_has_mgd) {
e8b5e24e 1991 p2p_concurrent = 1;
7626850d
JB
1992 break;
1993 }
1994
1995broken_combination:
1996 ;
1997 }
1998 }
1999
93d11400
ZY
2000 if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
2001 struct nlattr *nl_cmd;
2002 int i;
2003
2004 nla_for_each_nested(nl_cmd,
2005 tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
e8b5e24e
JB
2006 switch (nla_get_u32(nl_cmd)) {
2007 case NL80211_CMD_AUTHENTICATE:
2008 auth_supported = 1;
2009 break;
2010 case NL80211_CMD_CONNECT:
2011 connect_supported = 1;
2012 break;
2013 case NL80211_CMD_START_SCHED_SCAN:
2014 capa->sched_scan_supported = 1;
2015 break;
39718852
JB
2016 case NL80211_CMD_PROBE_CLIENT:
2017 info->poll_command_supported = 1;
2018 break;
e8b5e24e 2019 }
93d11400
ZY
2020 }
2021 }
2022
e8b5e24e
JB
2023 if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
2024 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
2025 "off-channel TX");
2026 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
2027 }
2028
2029 if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
2030 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
2031 capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
2032 }
5dfca53f 2033
e8b5e24e
JB
2034 /* default to 5000 since early versions of mac80211 don't set it */
2035 capa->max_remain_on_chan = 5000;
004ba773 2036
89e07afb 2037 if (tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION])
e8b5e24e 2038 capa->max_remain_on_chan =
89e07afb
JB
2039 nla_get_u32(tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
2040
e8b5e24e
JB
2041 if (auth_supported)
2042 capa->flags |= WPA_DRIVER_FLAGS_SME;
2043 else if (!connect_supported) {
2044 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
2045 "authentication/association or connect commands");
2046 info->error = 1;
2047 }
2048
2049 if (p2p_go_supported && p2p_client_supported)
2050 capa->flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
2051 if (p2p_concurrent) {
2052 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
2053 "interface (driver advertised support)");
2054 capa->flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
2055 capa->flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
2056 }
2057
03ea1786
AN
2058 if (tb[NL80211_ATTR_TDLS_SUPPORT]) {
2059 wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
2060 capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
2061
2062 if (tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]) {
2063 wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
2064 capa->flags |=
2065 WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
2066 }
2067 }
2068
61cbe2ff
JB
2069 if (tb[NL80211_ATTR_DEVICE_AP_SME])
2070 info->device_ap_sme = 1;
2071
80bc75f1
JM
2072 return NL_SKIP;
2073}
2074
2075
2076static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
2077 struct wiphy_info_data *info)
2078{
2079 struct nl_msg *msg;
2080
2081 os_memset(info, 0, sizeof(*info));
e8b5e24e 2082 info->capa = &drv->capa;
89e07afb 2083
80bc75f1
JM
2084 msg = nlmsg_alloc();
2085 if (!msg)
2086 return -1;
2087
9fb04070 2088 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
80bc75f1 2089
a2e40bb6 2090 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->first_bss.ifindex);
80bc75f1
JM
2091
2092 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
2093 return 0;
2094 msg = NULL;
2095nla_put_failure:
2096 nlmsg_free(msg);
2097 return -1;
2098}
2099
2100
93d11400 2101static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
80bc75f1
JM
2102{
2103 struct wiphy_info_data info;
2104 if (wpa_driver_nl80211_get_info(drv, &info))
93d11400 2105 return -1;
e8b5e24e
JB
2106
2107 if (info.error)
2108 return -1;
2109
80bc75f1 2110 drv->has_capability = 1;
1b2a72e8
JM
2111 /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
2112 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2113 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
2114 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
2115 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
2116 drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 |
2117 WPA_DRIVER_CAPA_ENC_WEP104 |
2118 WPA_DRIVER_CAPA_ENC_TKIP |
2119 WPA_DRIVER_CAPA_ENC_CCMP;
291b6068
JM
2120 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
2121 WPA_DRIVER_AUTH_SHARED |
2122 WPA_DRIVER_AUTH_LEAP;
1b2a72e8 2123
871f4dd0 2124 drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
0194fedb 2125 drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
2fee890a 2126 drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
4dc03726 2127 drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
0194fedb 2128
61cbe2ff 2129 drv->device_ap_sme = info.device_ap_sme;
39718852 2130 drv->poll_command_supported = info.poll_command_supported;
61cbe2ff 2131
93d11400 2132 return 0;
80bc75f1
JM
2133}
2134
2135
2a7b66f5
BG
2136static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
2137{
2138 global->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
2139 if (global->nl_cb == NULL) {
2140 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
2141 "callbacks");
2142 return -1;
2143 }
2144
276e2d67
BG
2145 if (nl_create_handles(&global->nl, global->nl_cb, "nl"))
2146 return -1;
2147
335d42b1
JB
2148 global->nl80211_id = genl_ctrl_resolve(global->nl.handle, "nl80211");
2149 if (global->nl80211_id < 0) {
276e2d67
BG
2150 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
2151 "found");
2152 return -1;
2153 }
2154
2a7b66f5
BG
2155 return 0;
2156}
2157
2158
ba2d0d7d 2159static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv)
3f5285e8 2160{
2a7b66f5 2161 struct nl80211_global *global = drv->global;
9fff9fdc 2162 int ret;
3f5285e8 2163
9fff9fdc 2164 /* Initialize generic netlink and nl80211 */
3f5285e8 2165
2a7b66f5 2166 if (nl_create_handles(&drv->nl_event, global->nl_cb, "event"))
9fff9fdc 2167 goto err3;
9fff9fdc 2168
97865538
JM
2169 ret = nl_get_multicast_id(drv, "nl80211", "scan");
2170 if (ret >= 0)
a92dfde8 2171 ret = nl_socket_add_membership(drv->nl_event.handle, ret);
97865538
JM
2172 if (ret < 0) {
2173 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
2174 "membership for scan events: %d (%s)",
2175 ret, strerror(-ret));
2176 goto err4;
2177 }
c2a04078
JM
2178
2179 ret = nl_get_multicast_id(drv, "nl80211", "mlme");
2180 if (ret >= 0)
a92dfde8 2181 ret = nl_socket_add_membership(drv->nl_event.handle, ret);
c2a04078
JM
2182 if (ret < 0) {
2183 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
2184 "membership for mlme events: %d (%s)",
2185 ret, strerror(-ret));
2186 goto err4;
2187 }
c2a04078 2188
33c5deb8
JM
2189 ret = nl_get_multicast_id(drv, "nl80211", "regulatory");
2190 if (ret >= 0)
a92dfde8 2191 ret = nl_socket_add_membership(drv->nl_event.handle, ret);
33c5deb8
JM
2192 if (ret < 0) {
2193 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
2194 "membership for regulatory events: %d (%s)",
2195 ret, strerror(-ret));
2196 /* Continue without regulatory events */
2197 }
2198
a92dfde8 2199 eloop_register_read_sock(nl_socket_get_fd(drv->nl_event.handle),
5582a5d1 2200 wpa_driver_nl80211_event_receive, drv,
a92dfde8 2201 drv->nl_event.handle);
97865538 2202
9fff9fdc
JM
2203 return 0;
2204
2205err4:
a92dfde8 2206 nl_destroy_handles(&drv->nl_event);
9fff9fdc 2207err3:
9fff9fdc
JM
2208 return -1;
2209}
2210
2211
8401a6b0
JM
2212static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
2213{
8401a6b0 2214 wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
a63063b4
JM
2215 /*
2216 * This may be for any interface; use ifdown event to disable
2217 * interface.
2218 */
8401a6b0
JM
2219}
2220
2221
2222static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
2223{
2224 struct wpa_driver_nl80211_data *drv = ctx;
2225 wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
c81eff1a
BG
2226 if (linux_set_iface_flags(drv->global->ioctl_sock,
2227 drv->first_bss.ifname, 1)) {
8401a6b0
JM
2228 wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
2229 "after rfkill unblock");
2230 return;
2231 }
a63063b4 2232 /* rtnetlink ifup handler will report interface as enabled */
8401a6b0
JM
2233}
2234
2235
6859f1cb
BG
2236static void nl80211_get_phy_name(struct wpa_driver_nl80211_data *drv)
2237{
2238 /* Find phy (radio) to which this interface belongs */
2239 char buf[90], *pos;
2240 int f, rv;
2241
2242 drv->phyname[0] = '\0';
2243 snprintf(buf, sizeof(buf) - 1, "/sys/class/net/%s/phy80211/name",
2244 drv->first_bss.ifname);
2245 f = open(buf, O_RDONLY);
2246 if (f < 0) {
2247 wpa_printf(MSG_DEBUG, "Could not open file %s: %s",
2248 buf, strerror(errno));
2249 return;
2250 }
2251
2252 rv = read(f, drv->phyname, sizeof(drv->phyname) - 1);
2253 close(f);
2254 if (rv < 0) {
2255 wpa_printf(MSG_DEBUG, "Could not read file %s: %s",
2256 buf, strerror(errno));
2257 return;
2258 }
2259
2260 drv->phyname[rv] = '\0';
2261 pos = os_strchr(drv->phyname, '\n');
2262 if (pos)
2263 *pos = '\0';
2264 wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
2265 drv->first_bss.ifname, drv->phyname);
2266}
2267
2268
9fff9fdc
JM
2269/**
2270 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
2271 * @ctx: context to be used when calling wpa_supplicant functions,
2272 * e.g., wpa_supplicant_event()
2273 * @ifname: interface name, e.g., wlan0
f2ed8023 2274 * @global_priv: private driver global data from global_init()
9fff9fdc
JM
2275 * Returns: Pointer to private data, %NULL on failure
2276 */
f2ed8023
JM
2277static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
2278 void *global_priv)
9fff9fdc 2279{
9fff9fdc 2280 struct wpa_driver_nl80211_data *drv;
8401a6b0 2281 struct rfkill_config *rcfg;
a2e40bb6 2282 struct i802_bss *bss;
9fff9fdc 2283
a5c696ad
JM
2284 if (global_priv == NULL)
2285 return NULL;
9fff9fdc
JM
2286 drv = os_zalloc(sizeof(*drv));
2287 if (drv == NULL)
2288 return NULL;
f2ed8023 2289 drv->global = global_priv;
9fff9fdc 2290 drv->ctx = ctx;
a2e40bb6
FF
2291 bss = &drv->first_bss;
2292 bss->drv = drv;
2293 os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
9fff9fdc
JM
2294 drv->monitor_ifidx = -1;
2295 drv->monitor_sock = -1;
d12dab4c
JB
2296#ifdef CONFIG_AP
2297 drv->eapol_tx_sock = -1;
2298#endif /* CONFIG_AP */
b1f625e0 2299 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
9fff9fdc 2300
ba2d0d7d 2301 if (wpa_driver_nl80211_init_nl(drv)) {
bbaf0837
JM
2302 os_free(drv);
2303 return NULL;
2304 }
9fff9fdc 2305
6859f1cb
BG
2306 nl80211_get_phy_name(drv);
2307
8401a6b0
JM
2308 rcfg = os_zalloc(sizeof(*rcfg));
2309 if (rcfg == NULL)
2310 goto failed;
2311 rcfg->ctx = drv;
2312 os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
2313 rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
2314 rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
2315 drv->rfkill = rfkill_init(rcfg);
52169389 2316 if (drv->rfkill == NULL) {
8401a6b0 2317 wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
52169389
JM
2318 os_free(rcfg);
2319 }
8401a6b0 2320
08063178 2321 if (wpa_driver_nl80211_finish_drv_init(drv))
bbaf0837 2322 goto failed;
7524cfb1 2323
f10bfc9a 2324#ifdef CONFIG_AP
d12dab4c 2325 drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
f10bfc9a
JM
2326#endif /* CONFIG_AP */
2327
dac12351 2328 if (drv->global) {
c4bb8817 2329 dl_list_add(&drv->global->interfaces, &drv->list);
dac12351
BG
2330 drv->in_interface_list = 1;
2331 }
c4bb8817 2332
a2e40bb6 2333 return bss;
7524cfb1 2334
bbaf0837 2335failed:
dac12351 2336 wpa_driver_nl80211_deinit(bss);
7524cfb1
JM
2337 return NULL;
2338}
2339
2340
bd94971e 2341static int nl80211_register_frame(struct wpa_driver_nl80211_data *drv,
5582a5d1 2342 struct nl_handle *nl_handle,
bd94971e 2343 u16 type, const u8 *match, size_t match_len)
58f6fbe0
JM
2344{
2345 struct nl_msg *msg;
2346 int ret = -1;
2347
2348 msg = nlmsg_alloc();
2349 if (!msg)
2350 return -1;
2351
9fb04070 2352 nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION);
58f6fbe0
JM
2353
2354 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
bd94971e 2355 NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type);
58f6fbe0
JM
2356 NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
2357
5582a5d1 2358 ret = send_and_recv(drv, nl_handle, msg, NULL, NULL);
58f6fbe0
JM
2359 msg = NULL;
2360 if (ret) {
5582a5d1
JB
2361 wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
2362 "failed (type=%u): ret=%d (%s)",
2363 type, ret, strerror(-ret));
2364 wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
58f6fbe0
JM
2365 match, match_len);
2366 goto nla_put_failure;
2367 }
2368 ret = 0;
2369nla_put_failure:
2370 nlmsg_free(msg);
2371 return ret;
2372}
2373
2374
bd94971e
JB
2375static int nl80211_register_action_frame(struct wpa_driver_nl80211_data *drv,
2376 const u8 *match, size_t match_len)
2377{
2378 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
a92dfde8 2379 return nl80211_register_frame(drv, drv->nl_event.handle,
5582a5d1 2380 type, match, match_len);
bd94971e
JB
2381}
2382
2383
58f6fbe0
JM
2384static int nl80211_register_action_frames(struct wpa_driver_nl80211_data *drv)
2385{
4fe9fa0d 2386#if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
046b26a2
JM
2387 /* GAS Initial Request */
2388 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0a", 2) < 0)
2389 return -1;
2390 /* GAS Initial Response */
2391 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0b", 2) < 0)
2392 return -1;
18708aad
JM
2393 /* GAS Comeback Request */
2394 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0c", 2) < 0)
2395 return -1;
2396 /* GAS Comeback Response */
2397 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0d", 2) < 0)
2398 return -1;
4fe9fa0d
JM
2399#endif /* CONFIG_P2P || CONFIG_INTERWORKING */
2400#ifdef CONFIG_P2P
046b26a2
JM
2401 /* P2P Public Action */
2402 if (nl80211_register_action_frame(drv,
2403 (u8 *) "\x04\x09\x50\x6f\x9a\x09",
2404 6) < 0)
2405 return -1;
2406 /* P2P Action */
2407 if (nl80211_register_action_frame(drv,
2408 (u8 *) "\x7f\x50\x6f\x9a\x09",
2409 5) < 0)
2410 return -1;
2411#endif /* CONFIG_P2P */
7d878ca7
JM
2412#ifdef CONFIG_IEEE80211W
2413 /* SA Query Response */
2414 if (nl80211_register_action_frame(drv, (u8 *) "\x08\x01", 2) < 0)
2415 return -1;
2416#endif /* CONFIG_IEEE80211W */
35287637
AN
2417#ifdef CONFIG_TDLS
2418 if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
2419 /* TDLS Discovery Response */
2420 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0e", 2) <
2421 0)
2422 return -1;
2423 }
2424#endif /* CONFIG_TDLS */
046b26a2 2425
7b90c16a
JM
2426 /* FT Action frames */
2427 if (nl80211_register_action_frame(drv, (u8 *) "\x06", 1) < 0)
2428 return -1;
2429 else
2430 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
2431 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
2432
71269b37
JM
2433 /* WNM - BSS Transition Management Request */
2434 if (nl80211_register_action_frame(drv, (u8 *) "\x0a\x07", 2) < 0)
2435 return -1;
2436
58f6fbe0
JM
2437 return 0;
2438}
2439
2440
8401a6b0
JM
2441static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
2442{
2443 wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
2444}
2445
2446
362f781e 2447static int
7524cfb1
JM
2448wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
2449{
a2e40bb6 2450 struct i802_bss *bss = &drv->first_bss;
8401a6b0 2451 int send_rfkill_event = 0;
a2e40bb6
FF
2452
2453 drv->ifindex = if_nametoindex(bss->ifname);
2454 drv->first_bss.ifindex = drv->ifindex;
a87c9d96 2455
bbaf0837 2456#ifndef HOSTAPD
ff6a158b
JM
2457 /*
2458 * Make sure the interface starts up in station mode unless this is a
2459 * dynamically added interface (e.g., P2P) that was already configured
2460 * with proper iftype.
2461 */
a5c696ad 2462 if (drv->ifindex != drv->global->if_add_ifindex &&
b1f625e0 2463 wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION) < 0) {
6e8183d7 2464 wpa_printf(MSG_ERROR, "nl80211: Could not configure driver to "
a87c9d96 2465 "use managed mode");
6e8183d7 2466 return -1;
a87c9d96
JM
2467 }
2468
c81eff1a 2469 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) {
8401a6b0
JM
2470 if (rfkill_is_blocked(drv->rfkill)) {
2471 wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
2472 "interface '%s' due to rfkill",
2473 bss->ifname);
a63063b4 2474 drv->if_disabled = 1;
8401a6b0
JM
2475 send_rfkill_event = 1;
2476 } else {
2477 wpa_printf(MSG_ERROR, "nl80211: Could not set "
2478 "interface '%s' UP", bss->ifname);
2479 return -1;
2480 }
362f781e 2481 }
3f5285e8 2482
36d84860 2483 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
e2d02c29 2484 1, IF_OPER_DORMANT);
bbaf0837 2485#endif /* HOSTAPD */
362f781e 2486
2fee890a
JM
2487 if (wpa_driver_nl80211_capa(drv))
2488 return -1;
2489
c81eff1a
BG
2490 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2491 drv->addr))
2136f480 2492 return -1;
f2ed8023 2493
7b90c16a
JM
2494 if (nl80211_register_action_frames(drv) < 0) {
2495 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
2496 "frame processing - ignore for now");
2497 /*
2498 * Older kernel versions did not support this, so ignore the
2499 * error for now. Some functionality may not be available
2500 * because of this.
2501 */
2502 }
58f6fbe0 2503
8401a6b0
JM
2504 if (send_rfkill_event) {
2505 eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
2506 drv, drv->ctx);
2507 }
2508
362f781e 2509 return 0;
3f5285e8
JM
2510}
2511
2512
8a27af5c
JM
2513static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
2514{
2515 struct nl_msg *msg;
2516
2517 msg = nlmsg_alloc();
2518 if (!msg)
2519 return -ENOMEM;
2520
9fb04070 2521 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_BEACON);
8a27af5c
JM
2522 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2523
2524 return send_and_recv_msgs(drv, msg, NULL, NULL);
2525 nla_put_failure:
2526 return -ENOBUFS;
2527}
8a27af5c
JM
2528
2529
3f5285e8 2530/**
7e5ba1b9
JM
2531 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
2532 * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
3f5285e8
JM
2533 *
2534 * Shut down driver interface and processing of driver events. Free
2535 * private data buffer if one was allocated in wpa_driver_nl80211_init().
2536 */
7e5ba1b9 2537static void wpa_driver_nl80211_deinit(void *priv)
3f5285e8 2538{
a2e40bb6
FF
2539 struct i802_bss *bss = priv;
2540 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 2541
f10bfc9a 2542#ifdef CONFIG_AP
d12dab4c
JB
2543 if (drv->eapol_tx_sock >= 0)
2544 close(drv->eapol_tx_sock);
f10bfc9a
JM
2545#endif /* CONFIG_AP */
2546
221a59c9 2547 if (bss->nl_preq.handle)
5582a5d1 2548 wpa_driver_nl80211_probe_req_report(bss, 0);
e17a2477 2549 if (bss->added_if_into_bridge) {
c81eff1a
BG
2550 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
2551 bss->ifname) < 0)
94627f6c
JM
2552 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
2553 "interface %s from bridge %s: %s",
e17a2477 2554 bss->ifname, bss->brname, strerror(errno));
94627f6c 2555 }
e17a2477 2556 if (bss->added_bridge) {
c81eff1a 2557 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
94627f6c
JM
2558 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
2559 "bridge %s: %s",
e17a2477 2560 bss->brname, strerror(errno));
94627f6c
JM
2561 }
2562
460456f8 2563 nl80211_remove_monitor_interface(drv);
8a27af5c 2564
b1f625e0 2565 if (is_ap_interface(drv->nlmode))
8a27af5c 2566 wpa_driver_nl80211_del_beacon(drv);
0915d02c 2567
bbaf0837
JM
2568#ifdef HOSTAPD
2569 if (drv->last_freq_ht) {
2570 /* Clear HT flags from the driver */
2571 struct hostapd_freq_params freq;
2572 os_memset(&freq, 0, sizeof(freq));
2573 freq.freq = drv->last_freq;
2574 i802_set_freq(priv, &freq);
2575 }
2576
bbaf0837
JM
2577 if (drv->eapol_sock >= 0) {
2578 eloop_unregister_read_sock(drv->eapol_sock);
2579 close(drv->eapol_sock);
2580 }
2581
2582 if (drv->if_indices != drv->default_if_indices)
2583 os_free(drv->if_indices);
1b648c7e 2584#endif /* HOSTAPD */
3f5285e8 2585
b3af99d2 2586 if (drv->disabled_11b_rates)
4e5cb1a3
JM
2587 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
2588
36d84860
BG
2589 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
2590 IF_OPER_UP);
8401a6b0 2591 rfkill_deinit(drv->rfkill);
3f5285e8 2592
bbaf0837
JM
2593 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
2594
c81eff1a 2595 (void) linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
b1f625e0 2596 wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION);
3f5285e8 2597
a92dfde8 2598 eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_event.handle));
a92dfde8 2599 nl_destroy_handles(&drv->nl_event);
3f5285e8 2600
3812464c
JM
2601 os_free(drv->filter_ssids);
2602
dac12351 2603 if (drv->in_interface_list)
f2ed8023
JM
2604 dl_list_del(&drv->list);
2605
3f5285e8
JM
2606 os_free(drv);
2607}
2608
2609
2610/**
2611 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
ad1e68e6 2612 * @eloop_ctx: Driver private data
3f5285e8
JM
2613 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
2614 *
2615 * This function can be used as registered timeout when starting a scan to
2616 * generate a scan completed event if the driver does not report this.
2617 */
2618static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
2619{
ad1e68e6 2620 struct wpa_driver_nl80211_data *drv = eloop_ctx;
b1f625e0 2621 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
a2e40bb6 2622 wpa_driver_nl80211_set_mode(&drv->first_bss,
b1f625e0
EP
2623 drv->ap_scan_as_station);
2624 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
ad1e68e6 2625 }
3f5285e8
JM
2626 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
2627 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
2628}
2629
2630
2631/**
2632 * wpa_driver_nl80211_scan - Request the driver to initiate scan
ad1e68e6 2633 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
6a1063e0 2634 * @params: Scan parameters
3f5285e8
JM
2635 * Returns: 0 on success, -1 on failure
2636 */
6a1063e0
JM
2637static int wpa_driver_nl80211_scan(void *priv,
2638 struct wpa_driver_scan_params *params)
3f5285e8 2639{
a2e40bb6
FF
2640 struct i802_bss *bss = priv;
2641 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 2642 int ret = 0, timeout;
47185fc7 2643 struct nl_msg *msg, *ssids, *freqs, *rates;
6a1063e0 2644 size_t i;
3f5285e8 2645
0e75527f
JM
2646 msg = nlmsg_alloc();
2647 ssids = nlmsg_alloc();
d3a98225 2648 freqs = nlmsg_alloc();
47185fc7
RM
2649 rates = nlmsg_alloc();
2650 if (!msg || !ssids || !freqs || !rates) {
0e75527f
JM
2651 nlmsg_free(msg);
2652 nlmsg_free(ssids);
d3a98225 2653 nlmsg_free(freqs);
47185fc7 2654 nlmsg_free(rates);
3f5285e8
JM
2655 return -1;
2656 }
2657
3812464c
JM
2658 os_free(drv->filter_ssids);
2659 drv->filter_ssids = params->filter_ssids;
2660 params->filter_ssids = NULL;
2661 drv->num_filter_ssids = params->num_filter_ssids;
2662
9fb04070 2663 nl80211_cmd(drv, msg, 0, NL80211_CMD_TRIGGER_SCAN);
0e75527f
JM
2664
2665 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3f5285e8 2666
6a1063e0 2667 for (i = 0; i < params->num_ssids; i++) {
9fad706c
JM
2668 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
2669 params->ssids[i].ssid,
2670 params->ssids[i].ssid_len);
6a1063e0
JM
2671 NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
2672 params->ssids[i].ssid);
3f5285e8 2673 }
6a1063e0
JM
2674 if (params->num_ssids)
2675 nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
3f5285e8 2676
d173df52 2677 if (params->extra_ies) {
9fad706c
JM
2678 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan extra IEs",
2679 params->extra_ies, params->extra_ies_len);
d173df52
JM
2680 NLA_PUT(msg, NL80211_ATTR_IE, params->extra_ies_len,
2681 params->extra_ies);
2682 }
2683
d3a98225 2684 if (params->freqs) {
9fad706c
JM
2685 for (i = 0; params->freqs[i]; i++) {
2686 wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
2687 "MHz", params->freqs[i]);
d3a98225 2688 NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
9fad706c 2689 }
d3a98225
JM
2690 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
2691 }
2692
47185fc7
RM
2693 if (params->p2p_probe) {
2694 /*
2695 * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
2696 * by masking out everything else apart from the OFDM rates 6,
2697 * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
2698 * rates are left enabled.
2699 */
2700 NLA_PUT(rates, NL80211_BAND_2GHZ, 8,
2701 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
2702 nla_put_nested(msg, NL80211_ATTR_SCAN_SUPP_RATES, rates);
970fa12e
RM
2703
2704 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
47185fc7
RM
2705 }
2706
0e75527f
JM
2707 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2708 msg = NULL;
2709 if (ret) {
2710 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
2711 "(%s)", ret, strerror(-ret));
ad1e68e6 2712#ifdef HOSTAPD
b1f625e0 2713 if (is_ap_interface(drv->nlmode)) {
ad1e68e6
JM
2714 /*
2715 * mac80211 does not allow scan requests in AP mode, so
2716 * try to do this in station mode.
2717 */
b1f625e0
EP
2718 if (wpa_driver_nl80211_set_mode(
2719 bss, NL80211_IFTYPE_STATION))
ad1e68e6
JM
2720 goto nla_put_failure;
2721
2722 if (wpa_driver_nl80211_scan(drv, params)) {
b1f625e0 2723 wpa_driver_nl80211_set_mode(bss, drv->nlmode);
ad1e68e6
JM
2724 goto nla_put_failure;
2725 }
2726
2727 /* Restore AP mode when processing scan results */
b1f625e0 2728 drv->ap_scan_as_station = drv->nlmode;
ad1e68e6
JM
2729 ret = 0;
2730 } else
2731 goto nla_put_failure;
2732#else /* HOSTAPD */
0e75527f 2733 goto nla_put_failure;
ad1e68e6 2734#endif /* HOSTAPD */
3f5285e8
JM
2735 }
2736
2737 /* Not all drivers generate "scan completed" wireless event, so try to
2738 * read results after a timeout. */
0e75527f 2739 timeout = 10;
3f5285e8
JM
2740 if (drv->scan_complete_events) {
2741 /*
d173df52
JM
2742 * The driver seems to deliver events to notify when scan is
2743 * complete, so use longer timeout to avoid race conditions
2744 * with scanning and following association request.
3f5285e8
JM
2745 */
2746 timeout = 30;
2747 }
2748 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
2749 "seconds", ret, timeout);
2750 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
0e75527f
JM
2751 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
2752 drv, drv->ctx);
3f5285e8 2753
0e75527f
JM
2754nla_put_failure:
2755 nlmsg_free(ssids);
2756 nlmsg_free(msg);
d3a98225 2757 nlmsg_free(freqs);
47185fc7 2758 nlmsg_free(rates);
3f5285e8
JM
2759 return ret;
2760}
2761
2762
d21c63b9
LC
2763/**
2764 * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
2765 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
2766 * @params: Scan parameters
2767 * @interval: Interval between scan cycles in milliseconds
2768 * Returns: 0 on success, -1 on failure or if not supported
2769 */
2770static int wpa_driver_nl80211_sched_scan(void *priv,
2771 struct wpa_driver_scan_params *params,
2772 u32 interval)
2773{
2774 struct i802_bss *bss = priv;
2775 struct wpa_driver_nl80211_data *drv = bss->drv;
2776 int ret = 0;
bd525934 2777 struct nl_msg *msg, *ssids, *freqs, *match_set_ssid, *match_sets;
d21c63b9
LC
2778 size_t i;
2779
2780 msg = nlmsg_alloc();
2781 ssids = nlmsg_alloc();
2782 freqs = nlmsg_alloc();
2783 if (!msg || !ssids || !freqs) {
2784 nlmsg_free(msg);
2785 nlmsg_free(ssids);
2786 nlmsg_free(freqs);
2787 return -1;
2788 }
2789
2790 os_free(drv->filter_ssids);
2791 drv->filter_ssids = params->filter_ssids;
2792 params->filter_ssids = NULL;
2793 drv->num_filter_ssids = params->num_filter_ssids;
2794
9fb04070 2795 nl80211_cmd(drv, msg, 0, NL80211_CMD_START_SCHED_SCAN);
d21c63b9
LC
2796
2797 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2798
2799 NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
2800
bd525934
LC
2801 if (drv->num_filter_ssids) {
2802 match_sets = nlmsg_alloc();
2803
2804 for (i = 0; i < drv->num_filter_ssids; i++) {
2805 wpa_hexdump_ascii(MSG_MSGDUMP,
2806 "nl80211: Sched scan filter SSID",
2807 drv->filter_ssids[i].ssid,
2808 drv->filter_ssids[i].ssid_len);
2809
2810 match_set_ssid = nlmsg_alloc();
2811 nla_put(match_set_ssid,
2812 NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
2813 drv->filter_ssids[i].ssid_len,
2814 drv->filter_ssids[i].ssid);
2815
2816 nla_put_nested(match_sets, i + 1, match_set_ssid);
2817
2818 nlmsg_free(match_set_ssid);
2819 }
2820
2821 nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH,
2822 match_sets);
2823 nlmsg_free(match_sets);
2824 }
2825
d21c63b9
LC
2826 for (i = 0; i < params->num_ssids; i++) {
2827 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Sched scan SSID",
2828 params->ssids[i].ssid,
2829 params->ssids[i].ssid_len);
2830 NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
2831 params->ssids[i].ssid);
2832 }
2833 if (params->num_ssids)
2834 nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
2835
2836 if (params->extra_ies) {
2837 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Sched scan extra IEs",
2838 params->extra_ies, params->extra_ies_len);
2839 NLA_PUT(msg, NL80211_ATTR_IE, params->extra_ies_len,
2840 params->extra_ies);
2841 }
2842
2843 if (params->freqs) {
2844 for (i = 0; params->freqs[i]; i++) {
2845 wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
2846 "MHz", params->freqs[i]);
2847 NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
2848 }
2849 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
2850 }
2851
2852 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2853
2854 /* TODO: if we get an error here, we should fall back to normal scan */
2855
2856 msg = NULL;
2857 if (ret) {
2858 wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
2859 "ret=%d (%s)", ret, strerror(-ret));
2860 goto nla_put_failure;
2861 }
2862
2863 wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
2864 "scan interval %d msec", ret, interval);
2865
2866nla_put_failure:
2867 nlmsg_free(ssids);
2868 nlmsg_free(msg);
2869 nlmsg_free(freqs);
2870 return ret;
2871}
2872
2873
2874/**
2875 * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
2876 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
2877 * Returns: 0 on success, -1 on failure or if not supported
2878 */
2879static int wpa_driver_nl80211_stop_sched_scan(void *priv)
2880{
2881 struct i802_bss *bss = priv;
2882 struct wpa_driver_nl80211_data *drv = bss->drv;
2883 int ret = 0;
2884 struct nl_msg *msg;
2885
2886 msg = nlmsg_alloc();
2887 if (!msg)
2888 return -1;
2889
9fb04070 2890 nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_SCHED_SCAN);
d21c63b9
LC
2891
2892 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2893
2894 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2895 msg = NULL;
2896 if (ret) {
2897 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop failed: "
2898 "ret=%d (%s)", ret, strerror(-ret));
2899 goto nla_put_failure;
2900 }
2901
2902 wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop sent (ret=%d)", ret);
2903
2904nla_put_failure:
2905 nlmsg_free(msg);
2906 return ret;
2907}
2908
2909
3812464c
JM
2910static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
2911{
2912 const u8 *end, *pos;
2913
2914 if (ies == NULL)
2915 return NULL;
2916
2917 pos = ies;
2918 end = ies + ies_len;
2919
2920 while (pos + 1 < end) {
2921 if (pos + 2 + pos[1] > end)
2922 break;
2923 if (pos[0] == ie)
2924 return pos;
2925 pos += 2 + pos[1];
2926 }
2927
2928 return NULL;
2929}
2930
2931
2932static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
2933 const u8 *ie, size_t ie_len)
2934{
2935 const u8 *ssid;
2936 size_t i;
2937
2938 if (drv->filter_ssids == NULL)
2939 return 0;
2940
2941 ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
2942 if (ssid == NULL)
2943 return 1;
2944
2945 for (i = 0; i < drv->num_filter_ssids; i++) {
2946 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
2947 os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
2948 0)
2949 return 0;
2950 }
2951
2952 return 1;
2953}
2954
2955
b3db1e1c 2956static int bss_info_handler(struct nl_msg *msg, void *arg)
3f5285e8 2957{
b3db1e1c
JM
2958 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2959 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2960 struct nlattr *bss[NL80211_BSS_MAX + 1];
2961 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
2962 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
2963 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
2964 [NL80211_BSS_TSF] = { .type = NLA_U64 },
2965 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
2966 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
2967 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
2968 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
2969 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
e6b8efeb 2970 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
b3ad11bb 2971 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
8c090654 2972 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
b3db1e1c 2973 };
3812464c
JM
2974 struct nl80211_bss_info_arg *_arg = arg;
2975 struct wpa_scan_results *res = _arg->res;
3f5285e8
JM
2976 struct wpa_scan_res **tmp;
2977 struct wpa_scan_res *r;
8c090654
JM
2978 const u8 *ie, *beacon_ie;
2979 size_t ie_len, beacon_ie_len;
2980 u8 *pos;
46957a9b 2981 size_t i;
3f5285e8 2982
b3db1e1c
JM
2983 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2984 genlmsg_attrlen(gnlh, 0), NULL);
2985 if (!tb[NL80211_ATTR_BSS])
2986 return NL_SKIP;
2987 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
2988 bss_policy))
2989 return NL_SKIP;
f5a8d422
JM
2990 if (bss[NL80211_BSS_STATUS]) {
2991 enum nl80211_bss_status status;
2992 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
2993 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
2994 bss[NL80211_BSS_FREQUENCY]) {
2995 _arg->assoc_freq =
2996 nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
2997 wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
2998 _arg->assoc_freq);
2999 }
20f5a4c2
JM
3000 if (status == NL80211_BSS_STATUS_ASSOCIATED &&
3001 bss[NL80211_BSS_BSSID]) {
3002 os_memcpy(_arg->assoc_bssid,
3003 nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN);
3004 wpa_printf(MSG_DEBUG, "nl80211: Associated with "
3005 MACSTR, MAC2STR(_arg->assoc_bssid));
3006 }
f5a8d422
JM
3007 }
3008 if (!res)
3009 return NL_SKIP;
b3db1e1c
JM
3010 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
3011 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
3012 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
3013 } else {
3014 ie = NULL;
3015 ie_len = 0;
3016 }
8c090654
JM
3017 if (bss[NL80211_BSS_BEACON_IES]) {
3018 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
3019 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
3020 } else {
3021 beacon_ie = NULL;
3022 beacon_ie_len = 0;
3023 }
3f5285e8 3024
3812464c
JM
3025 if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
3026 ie ? ie_len : beacon_ie_len))
3027 return NL_SKIP;
3028
8c090654 3029 r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
3f5285e8 3030 if (r == NULL)
b3db1e1c
JM
3031 return NL_SKIP;
3032 if (bss[NL80211_BSS_BSSID])
3033 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
3034 ETH_ALEN);
3035 if (bss[NL80211_BSS_FREQUENCY])
3036 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
3037 if (bss[NL80211_BSS_BEACON_INTERVAL])
3038 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
3039 if (bss[NL80211_BSS_CAPABILITY])
3040 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
7c2849d2
JM
3041 r->flags |= WPA_SCAN_NOISE_INVALID;
3042 if (bss[NL80211_BSS_SIGNAL_MBM]) {
b3db1e1c 3043 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
7c2849d2
JM
3044 r->level /= 100; /* mBm to dBm */
3045 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
3046 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
3047 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
98ac6763 3048 r->flags |= WPA_SCAN_QUAL_INVALID;
7c2849d2
JM
3049 } else
3050 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
b3db1e1c
JM
3051 if (bss[NL80211_BSS_TSF])
3052 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
b3ad11bb
JM
3053 if (bss[NL80211_BSS_SEEN_MS_AGO])
3054 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
b3db1e1c 3055 r->ie_len = ie_len;
8c090654
JM
3056 pos = (u8 *) (r + 1);
3057 if (ie) {
3058 os_memcpy(pos, ie, ie_len);
3059 pos += ie_len;
3060 }
3061 r->beacon_ie_len = beacon_ie_len;
3062 if (beacon_ie)
3063 os_memcpy(pos, beacon_ie, beacon_ie_len);
3f5285e8 3064
e6b8efeb
JM
3065 if (bss[NL80211_BSS_STATUS]) {
3066 enum nl80211_bss_status status;
3067 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
3068 switch (status) {
3069 case NL80211_BSS_STATUS_AUTHENTICATED:
3070 r->flags |= WPA_SCAN_AUTHENTICATED;
3071 break;
3072 case NL80211_BSS_STATUS_ASSOCIATED:
3073 r->flags |= WPA_SCAN_ASSOCIATED;
3074 break;
3075 default:
3076 break;
3077 }
3078 }
3079
46957a9b
JM
3080 /*
3081 * cfg80211 maintains separate BSS table entries for APs if the same
3082 * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
3083 * not use frequency as a separate key in the BSS table, so filter out
3084 * duplicated entries. Prefer associated BSS entry in such a case in
3085 * order to get the correct frequency into the BSS table.
3086 */
3087 for (i = 0; i < res->num; i++) {
3088 const u8 *s1, *s2;
3089 if (os_memcmp(res->res[i]->bssid, r->bssid, ETH_ALEN) != 0)
3090 continue;
3091
3092 s1 = nl80211_get_ie((u8 *) (res->res[i] + 1),
3093 res->res[i]->ie_len, WLAN_EID_SSID);
3094 s2 = nl80211_get_ie((u8 *) (r + 1), r->ie_len, WLAN_EID_SSID);
3095 if (s1 == NULL || s2 == NULL || s1[1] != s2[1] ||
3096 os_memcmp(s1, s2, 2 + s1[1]) != 0)
3097 continue;
3098
3099 /* Same BSSID,SSID was already included in scan results */
3100 wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
3101 "for " MACSTR, MAC2STR(r->bssid));
3102
3103 if ((r->flags & WPA_SCAN_ASSOCIATED) &&
3104 !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) {
3105 os_free(res->res[i]);
3106 res->res[i] = r;
3107 } else
3108 os_free(r);
3109 return NL_SKIP;
3110 }
3111
3f5285e8
JM
3112 tmp = os_realloc(res->res,
3113 (res->num + 1) * sizeof(struct wpa_scan_res *));
3114 if (tmp == NULL) {
3115 os_free(r);
b3db1e1c 3116 return NL_SKIP;
3f5285e8
JM
3117 }
3118 tmp[res->num++] = r;
3119 res->res = tmp;
b3db1e1c
JM
3120
3121 return NL_SKIP;
3f5285e8 3122}
b3db1e1c 3123
3f5285e8 3124
d72aad94
JM
3125static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
3126 const u8 *addr)
3127{
3128 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
3129 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
582507be 3130 "mismatch (" MACSTR ")", MAC2STR(addr));
d72aad94
JM
3131 wpa_driver_nl80211_mlme(drv, addr,
3132 NL80211_CMD_DEAUTHENTICATE,
77339912 3133 WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
d72aad94
JM
3134 }
3135}
3136
3137
e6b8efeb
JM
3138static void wpa_driver_nl80211_check_bss_status(
3139 struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
3140{
3141 size_t i;
3142
3143 for (i = 0; i < res->num; i++) {
3144 struct wpa_scan_res *r = res->res[i];
3145 if (r->flags & WPA_SCAN_AUTHENTICATED) {
3146 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
3147 "indicates BSS status with " MACSTR
3148 " as authenticated",
3149 MAC2STR(r->bssid));
b1f625e0 3150 if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
3151 os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
3152 os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
3153 0) {
3154 wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
3155 " in local state (auth=" MACSTR
3156 " assoc=" MACSTR ")",
3157 MAC2STR(drv->auth_bssid),
3158 MAC2STR(drv->bssid));
582507be 3159 clear_state_mismatch(drv, r->bssid);
e6b8efeb
JM
3160 }
3161 }
3162
3163 if (r->flags & WPA_SCAN_ASSOCIATED) {
3164 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
3165 "indicate BSS status with " MACSTR
3166 " as associated",
3167 MAC2STR(r->bssid));
b1f625e0 3168 if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
3169 !drv->associated) {
3170 wpa_printf(MSG_DEBUG, "nl80211: Local state "
3171 "(not associated) does not match "
3172 "with BSS state");
d72aad94 3173 clear_state_mismatch(drv, r->bssid);
b1f625e0 3174 } else if (is_sta_interface(drv->nlmode) &&
e6b8efeb
JM
3175 os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
3176 0) {
3177 wpa_printf(MSG_DEBUG, "nl80211: Local state "
3178 "(associated with " MACSTR ") does "
3179 "not match with BSS state",
d72aad94
JM
3180 MAC2STR(drv->bssid));
3181 clear_state_mismatch(drv, r->bssid);
3182 clear_state_mismatch(drv, drv->bssid);
e6b8efeb
JM
3183 }
3184 }
3185 }
3186}
3187
3188
7e5ba1b9 3189static struct wpa_scan_results *
8856462d 3190nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
3f5285e8 3191{
b3db1e1c 3192 struct nl_msg *msg;
3f5285e8 3193 struct wpa_scan_results *res;
b3db1e1c 3194 int ret;
3812464c 3195 struct nl80211_bss_info_arg arg;
3f5285e8
JM
3196
3197 res = os_zalloc(sizeof(*res));
b3db1e1c 3198 if (res == NULL)
8e2c104f 3199 return NULL;
b3db1e1c
JM
3200 msg = nlmsg_alloc();
3201 if (!msg)
3202 goto nla_put_failure;
3f5285e8 3203
9fb04070 3204 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
b3db1e1c 3205 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3f5285e8 3206
3812464c
JM
3207 arg.drv = drv;
3208 arg.res = res;
3209 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
b3db1e1c
JM
3210 msg = NULL;
3211 if (ret == 0) {
577db0ae
GM
3212 wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu "
3213 "BSSes)", (unsigned long) res->num);
3214 nl80211_get_noise_for_scan_results(drv, res);
b3db1e1c 3215 return res;
3f5285e8 3216 }
b3db1e1c
JM
3217 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
3218 "(%s)", ret, strerror(-ret));
3219nla_put_failure:
3220 nlmsg_free(msg);
3221 wpa_scan_results_free(res);
3222 return NULL;
3f5285e8
JM
3223}
3224
3225
8856462d
JM
3226/**
3227 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
3228 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
3229 * Returns: Scan results on success, -1 on failure
3230 */
3231static struct wpa_scan_results *
3232wpa_driver_nl80211_get_scan_results(void *priv)
3233{
a2e40bb6
FF
3234 struct i802_bss *bss = priv;
3235 struct wpa_driver_nl80211_data *drv = bss->drv;
8856462d
JM
3236 struct wpa_scan_results *res;
3237
3238 res = nl80211_get_scan_results(drv);
3239 if (res)
3240 wpa_driver_nl80211_check_bss_status(drv, res);
3241 return res;
3242}
3243
3244
3245static void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
3246{
3247 struct wpa_scan_results *res;
3248 size_t i;
3249
3250 res = nl80211_get_scan_results(drv);
3251 if (res == NULL) {
3252 wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
3253 return;
3254 }
3255
3256 wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
3257 for (i = 0; i < res->num; i++) {
3258 struct wpa_scan_res *r = res->res[i];
3259 wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s%s",
3260 (int) i, (int) res->num, MAC2STR(r->bssid),
3261 r->flags & WPA_SCAN_AUTHENTICATED ? " [auth]" : "",
3262 r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
3263 }
3264
3265 wpa_scan_results_free(res);
3266}
3267
3268
642187d6 3269static int wpa_driver_nl80211_set_key(const char *ifname, void *priv,
71934751
JM
3270 enum wpa_alg alg, const u8 *addr,
3271 int key_idx, int set_tx,
642187d6
JM
3272 const u8 *seq, size_t seq_len,
3273 const u8 *key, size_t key_len)
3f5285e8 3274{
a2e40bb6
FF
3275 struct i802_bss *bss = priv;
3276 struct wpa_driver_nl80211_data *drv = bss->drv;
642187d6 3277 int ifindex = if_nametoindex(ifname);
3f5285e8 3278 struct nl_msg *msg;
1ad1cdc2 3279 int ret;
3f5285e8 3280
1ad1cdc2
JM
3281 wpa_printf(MSG_DEBUG, "%s: ifindex=%d alg=%d addr=%p key_idx=%d "
3282 "set_tx=%d seq_len=%lu key_len=%lu",
3283 __func__, ifindex, alg, addr, key_idx, set_tx,
3f5285e8 3284 (unsigned long) seq_len, (unsigned long) key_len);
8c66e185
JM
3285#ifdef CONFIG_TDLS
3286 if (key_idx == -1)
3287 key_idx = 0;
3288#endif /* CONFIG_TDLS */
3f5285e8
JM
3289
3290 msg = nlmsg_alloc();
1ad1cdc2
JM
3291 if (!msg)
3292 return -ENOMEM;
3f5285e8
JM
3293
3294 if (alg == WPA_ALG_NONE) {
9fb04070 3295 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_KEY);
3f5285e8 3296 } else {
9fb04070 3297 nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_KEY);
3f5285e8 3298 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
d723bab4
JM
3299 switch (alg) {
3300 case WPA_ALG_WEP:
3301 if (key_len == 5)
3302 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
3303 WLAN_CIPHER_SUITE_WEP40);
3304 else
3305 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
3306 WLAN_CIPHER_SUITE_WEP104);
3307 break;
3308 case WPA_ALG_TKIP:
3309 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
3310 WLAN_CIPHER_SUITE_TKIP);
3311 break;
3312 case WPA_ALG_CCMP:
3313 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
3314 WLAN_CIPHER_SUITE_CCMP);
3315 break;
3316 case WPA_ALG_IGTK:
3317 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
3318 WLAN_CIPHER_SUITE_AES_CMAC);
3319 break;
3320 default:
3321 wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
3322 "algorithm %d", __func__, alg);
3f5285e8
JM
3323 nlmsg_free(msg);
3324 return -1;
3325 }
3326 }
3327
849ef835 3328 if (seq && seq_len)
1ad1cdc2
JM
3329 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
3330
0382097e 3331 if (addr && !is_broadcast_ether_addr(addr)) {
3f5285e8
JM
3332 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
3333 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
89c38e32
JM
3334
3335 if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
3336 wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK");
3337 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE,
3338 NL80211_KEYTYPE_GROUP);
3339 }
60ea8187
JM
3340 } else if (addr && is_broadcast_ether_addr(addr)) {
3341 struct nl_msg *types;
3342 int err;
3343 wpa_printf(MSG_DEBUG, " broadcast key");
3344 types = nlmsg_alloc();
3345 if (!types)
3346 goto nla_put_failure;
3347 NLA_PUT_FLAG(types, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
3348 err = nla_put_nested(msg, NL80211_ATTR_KEY_DEFAULT_TYPES,
3349 types);
3350 nlmsg_free(types);
3351 if (err)
3352 goto nla_put_failure;
3f5285e8
JM
3353 }
3354 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1ad1cdc2 3355 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
3f5285e8 3356
1ad1cdc2 3357 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
15664ad0 3358 if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
1ad1cdc2
JM
3359 ret = 0;
3360 if (ret)
3361 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
3362 ret, strerror(-ret));
3f5285e8 3363
1ad1cdc2
JM
3364 /*
3365 * If we failed or don't need to set the default TX key (below),
3366 * we're done here.
3367 */
3368 if (ret || !set_tx || alg == WPA_ALG_NONE)
3369 return ret;
b1f625e0 3370 if (is_ap_interface(drv->nlmode) && addr &&
0382097e 3371 !is_broadcast_ether_addr(addr))
de12717a 3372 return ret;
3f5285e8 3373
1ad1cdc2
JM
3374 msg = nlmsg_alloc();
3375 if (!msg)
3376 return -ENOMEM;
3f5285e8 3377
9fb04070 3378 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_KEY);
1ad1cdc2
JM
3379 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
3380 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
3381 if (alg == WPA_ALG_IGTK)
3382 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
3383 else
3384 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
60ea8187
JM
3385 if (addr && is_broadcast_ether_addr(addr)) {
3386 struct nl_msg *types;
3387 int err;
3388 types = nlmsg_alloc();
3389 if (!types)
3390 goto nla_put_failure;
3391 NLA_PUT_FLAG(types, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
3392 err = nla_put_nested(msg, NL80211_ATTR_KEY_DEFAULT_TYPES,
3393 types);
3394 nlmsg_free(types);
3395 if (err)
3396 goto nla_put_failure;
3397 } else if (addr) {
3398 struct nl_msg *types;
3399 int err;
3400 types = nlmsg_alloc();
3401 if (!types)
3402 goto nla_put_failure;
3403 NLA_PUT_FLAG(types, NL80211_KEY_DEFAULT_TYPE_UNICAST);
3404 err = nla_put_nested(msg, NL80211_ATTR_KEY_DEFAULT_TYPES,
3405 types);
3406 nlmsg_free(types);
3407 if (err)
3408 goto nla_put_failure;
3409 }
3f5285e8 3410
1ad1cdc2
JM
3411 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3412 if (ret == -ENOENT)
3413 ret = 0;
3414 if (ret)
3415 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
3416 "err=%d %s)", ret, strerror(-ret));
3417 return ret;
3f5285e8
JM
3418
3419nla_put_failure:
6241fcb1 3420 return -ENOBUFS;
3f5285e8
JM
3421}
3422
3423
71934751 3424static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
0194fedb
JB
3425 int key_idx, int defkey,
3426 const u8 *seq, size_t seq_len,
3427 const u8 *key, size_t key_len)
3428{
3429 struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
3430 if (!key_attr)
3431 return -1;
3432
3433 if (defkey && alg == WPA_ALG_IGTK)
3434 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
3435 else if (defkey)
3436 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
3437
3438 NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
3439
d723bab4
JM
3440 switch (alg) {
3441 case WPA_ALG_WEP:
3442 if (key_len == 5)
2aa5f847
JM
3443 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
3444 WLAN_CIPHER_SUITE_WEP40);
d723bab4 3445 else
2aa5f847
JM
3446 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
3447 WLAN_CIPHER_SUITE_WEP104);
d723bab4
JM
3448 break;
3449 case WPA_ALG_TKIP:
2aa5f847 3450 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_TKIP);
d723bab4
JM
3451 break;
3452 case WPA_ALG_CCMP:
2aa5f847 3453 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_CCMP);
d723bab4
JM
3454 break;
3455 case WPA_ALG_IGTK:
2aa5f847
JM
3456 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
3457 WLAN_CIPHER_SUITE_AES_CMAC);
d723bab4
JM
3458 break;
3459 default:
3460 wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
3461 "algorithm %d", __func__, alg);
0194fedb 3462 return -1;
d723bab4 3463 }
0194fedb
JB
3464
3465 if (seq && seq_len)
3466 NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
3467
3468 NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
3469
3470 nla_nest_end(msg, key_attr);
3471
3472 return 0;
3473 nla_put_failure:
3474 return -1;
3475}
3476
c811d5bc 3477
cfaab580
ZY
3478static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
3479 struct nl_msg *msg)
3480{
3481 int i, privacy = 0;
3482 struct nlattr *nl_keys, *nl_key;
3483
3484 for (i = 0; i < 4; i++) {
3485 if (!params->wep_key[i])
3486 continue;
3487 privacy = 1;
3488 break;
3489 }
ce04af5a
JM
3490 if (params->wps == WPS_MODE_PRIVACY)
3491 privacy = 1;
3492 if (params->pairwise_suite &&
3493 params->pairwise_suite != WPA_CIPHER_NONE)
3494 privacy = 1;
3495
cfaab580
ZY
3496 if (!privacy)
3497 return 0;
3498
3499 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
3500
3501 nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
3502 if (!nl_keys)
3503 goto nla_put_failure;
3504
3505 for (i = 0; i < 4; i++) {
3506 if (!params->wep_key[i])
3507 continue;
3508
3509 nl_key = nla_nest_start(msg, i);
3510 if (!nl_key)
3511 goto nla_put_failure;
3512
3513 NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
3514 params->wep_key[i]);
3515 if (params->wep_key_len[i] == 5)
3516 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
3517 WLAN_CIPHER_SUITE_WEP40);
3518 else
3519 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
3520 WLAN_CIPHER_SUITE_WEP104);
3521
3522 NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
3523
3524 if (i == params->wep_tx_keyidx)
3525 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
3526
3527 nla_nest_end(msg, nl_key);
3528 }
3529 nla_nest_end(msg, nl_keys);
3530
3531 return 0;
3532
3533nla_put_failure:
3534 return -ENOBUFS;
3535}
3536
3537
c2a04078 3538static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
77339912
JM
3539 const u8 *addr, int cmd, u16 reason_code,
3540 int local_state_change)
c2a04078
JM
3541{
3542 int ret = -1;
3543 struct nl_msg *msg;
3544
3545 msg = nlmsg_alloc();
3546 if (!msg)
3547 return -1;
3548
9fb04070 3549 nl80211_cmd(drv, msg, 0, cmd);
c2a04078
JM
3550
3551 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3552 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
3553 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
77339912
JM
3554 if (local_state_change)
3555 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
c2a04078
JM
3556
3557 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3558 msg = NULL;
3559 if (ret) {
3b7ea880
BG
3560 wpa_dbg(drv->ctx, MSG_DEBUG,
3561 "nl80211: MLME command failed: reason=%u ret=%d (%s)",
3562 reason_code, ret, strerror(-ret));
c2a04078
JM
3563 goto nla_put_failure;
3564 }
3565 ret = 0;
3566
3567nla_put_failure:
3568 nlmsg_free(msg);
3569 return ret;
3570}
3f5285e8
JM
3571
3572
cfaab580
ZY
3573static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
3574 const u8 *addr, int reason_code)
3575{
2e75a2b3
JM
3576 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
3577 __func__, MAC2STR(addr), reason_code);
cfaab580
ZY
3578 drv->associated = 0;
3579 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISCONNECT,
77339912 3580 reason_code, 0);
cfaab580
ZY
3581}
3582
3583
3f5285e8 3584static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,
c2a04078 3585 int reason_code)
3f5285e8 3586{
a2e40bb6
FF
3587 struct i802_bss *bss = priv;
3588 struct wpa_driver_nl80211_data *drv = bss->drv;
cfaab580
ZY
3589 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
3590 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
2e75a2b3
JM
3591 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
3592 __func__, MAC2STR(addr), reason_code);
13405f35 3593 drv->associated = 0;
21bdbe38
JM
3594 if (drv->nlmode == NL80211_IFTYPE_ADHOC)
3595 return nl80211_leave_ibss(drv);
c2a04078 3596 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
77339912 3597 reason_code, 0);
3f5285e8
JM
3598}
3599
3600
3601static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,
c2a04078 3602 int reason_code)
3f5285e8 3603{
a2e40bb6
FF
3604 struct i802_bss *bss = priv;
3605 struct wpa_driver_nl80211_data *drv = bss->drv;
cfaab580
ZY
3606 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
3607 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
c2a04078 3608 wpa_printf(MSG_DEBUG, "%s", __func__);
13405f35 3609 drv->associated = 0;
c2a04078 3610 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISASSOCIATE,
77339912 3611 reason_code, 0);
3f5285e8
JM
3612}
3613
3614
c2a04078
JM
3615static int wpa_driver_nl80211_authenticate(
3616 void *priv, struct wpa_driver_auth_params *params)
3617{
a2e40bb6
FF
3618 struct i802_bss *bss = priv;
3619 struct wpa_driver_nl80211_data *drv = bss->drv;
a0b2f99b 3620 int ret = -1, i;
c2a04078
JM
3621 struct nl_msg *msg;
3622 enum nl80211_auth_type type;
2f4f73b1 3623 enum nl80211_iftype nlmode;
6d6f4bb8 3624 int count = 0;
c2a04078
JM
3625
3626 drv->associated = 0;
e6b8efeb 3627 os_memset(drv->auth_bssid, 0, ETH_ALEN);
af473088 3628 /* FIX: IBSS mode */
2f4f73b1
EP
3629 nlmode = params->p2p ?
3630 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
3631 if (drv->nlmode != nlmode &&
3632 wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
4a867032
JM
3633 return -1;
3634
6d6f4bb8 3635retry:
c2a04078
JM
3636 msg = nlmsg_alloc();
3637 if (!msg)
3638 return -1;
3639
3640 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
3641 drv->ifindex);
a0b2f99b 3642
9fb04070 3643 nl80211_cmd(drv, msg, 0, NL80211_CMD_AUTHENTICATE);
0194fedb 3644
a0b2f99b
JM
3645 for (i = 0; i < 4; i++) {
3646 if (!params->wep_key[i])
3647 continue;
2ea2fcc7
HS
3648 wpa_driver_nl80211_set_key(bss->ifname, priv, WPA_ALG_WEP,
3649 NULL, i,
a0b2f99b
JM
3650 i == params->wep_tx_keyidx, NULL, 0,
3651 params->wep_key[i],
3652 params->wep_key_len[i]);
0194fedb
JB
3653 if (params->wep_tx_keyidx != i)
3654 continue;
3655 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
3656 params->wep_key[i], params->wep_key_len[i])) {
3657 nlmsg_free(msg);
3658 return -1;
3659 }
a0b2f99b
JM
3660 }
3661
c2a04078
JM
3662 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3663 if (params->bssid) {
3664 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
3665 MAC2STR(params->bssid));
3666 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
3667 }
3668 if (params->freq) {
3669 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
3670 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
3671 }
3672 if (params->ssid) {
3673 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
3674 params->ssid, params->ssid_len);
3675 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
3676 params->ssid);
3677 }
3678 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
3679 if (params->ie)
3680 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
abd9fafa 3681 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
c2a04078 3682 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
abd9fafa 3683 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
c2a04078 3684 type = NL80211_AUTHTYPE_SHARED_KEY;
abd9fafa 3685 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
c2a04078 3686 type = NL80211_AUTHTYPE_NETWORK_EAP;
abd9fafa 3687 else if (params->auth_alg & WPA_AUTH_ALG_FT)
c2a04078
JM
3688 type = NL80211_AUTHTYPE_FT;
3689 else
3690 goto nla_put_failure;
3691 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
3692 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
77339912
JM
3693 if (params->local_state_change) {
3694 wpa_printf(MSG_DEBUG, " * Local state change only");
3695 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
3696 }
c2a04078
JM
3697
3698 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3699 msg = NULL;
3700 if (ret) {
3b7ea880
BG
3701 wpa_dbg(drv->ctx, MSG_DEBUG,
3702 "nl80211: MLME command failed (auth): ret=%d (%s)",
3703 ret, strerror(-ret));
6d6f4bb8 3704 count++;
77339912
JM
3705 if (ret == -EALREADY && count == 1 && params->bssid &&
3706 !params->local_state_change) {
6d6f4bb8
JM
3707 /*
3708 * mac80211 does not currently accept new
3709 * authentication if we are already authenticated. As a
3710 * workaround, force deauthentication and try again.
3711 */
3712 wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
3713 "after forced deauthentication");
3714 wpa_driver_nl80211_deauthenticate(
5205c4f9 3715 bss, params->bssid,
6d6f4bb8
JM
3716 WLAN_REASON_PREV_AUTH_NOT_VALID);
3717 nlmsg_free(msg);
3718 goto retry;
3719 }
c2a04078
JM
3720 goto nla_put_failure;
3721 }
3722 ret = 0;
3723 wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
3724 "successfully");
3725
3726nla_put_failure:
3727 nlmsg_free(msg);
3728 return ret;
3729}
3730
3731
282d5590
JM
3732struct phy_info_arg {
3733 u16 *num_modes;
3734 struct hostapd_hw_modes *modes;
3735};
3736
3737static int phy_info_handler(struct nl_msg *msg, void *arg)
3738{
3739 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3740 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3741 struct phy_info_arg *phy_info = arg;
3742
3743 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
3744
3745 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
3746 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
3747 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
3748 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
3749 [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
3750 [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },
3751 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
3752 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
3753 };
3754
3755 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
3756 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
3757 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
3758 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG },
3759 };
3760
3761 struct nlattr *nl_band;
3762 struct nlattr *nl_freq;
3763 struct nlattr *nl_rate;
3764 int rem_band, rem_freq, rem_rate;
3765 struct hostapd_hw_modes *mode;
3766 int idx, mode_is_set;
3767
3768 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3769 genlmsg_attrlen(gnlh, 0), NULL);
3770
3771 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
3772 return NL_SKIP;
3773
3774 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) {
e62fb0a0 3775 mode = os_realloc(phy_info->modes, (*phy_info->num_modes + 1) * sizeof(*mode));
282d5590
JM
3776 if (!mode)
3777 return NL_SKIP;
3778 phy_info->modes = mode;
3779
3780 mode_is_set = 0;
3781
3782 mode = &phy_info->modes[*(phy_info->num_modes)];
3783 memset(mode, 0, sizeof(*mode));
e3b473eb 3784 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN;
282d5590
JM
3785 *(phy_info->num_modes) += 1;
3786
3787 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
3788 nla_len(nl_band), NULL);
3789
3790 if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
3791 mode->ht_capab = nla_get_u16(
3792 tb_band[NL80211_BAND_ATTR_HT_CAPA]);
3793 }
3794
be8eb8ab
JM
3795 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) {
3796 mode->a_mpdu_params |= nla_get_u8(
3797 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) &
3798 0x03;
3799 }
3800
3801 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) {
3802 mode->a_mpdu_params |= nla_get_u8(
3803 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) <<
3804 2;
3805 }
3806
08eb154d
JM
3807 if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] &&
3808 nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET])) {
3809 u8 *mcs;
3810 mcs = nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
3811 os_memcpy(mode->mcs_set, mcs, 16);
3812 }
3813
282d5590
JM
3814 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
3815 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
3816 nla_len(nl_freq), freq_policy);
3817 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
3818 continue;
3819 mode->num_channels++;
3820 }
3821
e62fb0a0 3822 mode->channels = os_zalloc(mode->num_channels * sizeof(struct hostapd_channel_data));
282d5590
JM
3823 if (!mode->channels)
3824 return NL_SKIP;
3825
3826 idx = 0;
3827
3828 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
3829 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
3830 nla_len(nl_freq), freq_policy);
3831 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
3832 continue;
3833
3834 mode->channels[idx].freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
3835 mode->channels[idx].flag = 0;
3836
3837 if (!mode_is_set) {
3838 /* crude heuristic */
3839 if (mode->channels[idx].freq < 4000)
3840 mode->mode = HOSTAPD_MODE_IEEE80211B;
3841 else
3842 mode->mode = HOSTAPD_MODE_IEEE80211A;
3843 mode_is_set = 1;
3844 }
3845
3846 /* crude heuristic */
3847 if (mode->channels[idx].freq < 4000)
5a0ffb5f 3848 if (mode->channels[idx].freq == 2484)
282d5590
JM
3849 mode->channels[idx].chan = 14;
3850 else
3851 mode->channels[idx].chan = (mode->channels[idx].freq - 2407) / 5;
3852 else
3853 mode->channels[idx].chan = mode->channels[idx].freq/5 - 1000;
3854
3855 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
3856 mode->channels[idx].flag |=
3857 HOSTAPD_CHAN_DISABLED;
3858 if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
3859 mode->channels[idx].flag |=
3860 HOSTAPD_CHAN_PASSIVE_SCAN;
3861 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])
3862 mode->channels[idx].flag |=
3863 HOSTAPD_CHAN_NO_IBSS;
3864 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
3865 mode->channels[idx].flag |=
3866 HOSTAPD_CHAN_RADAR;
3867
3868 if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] &&
3869 !tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
3870 mode->channels[idx].max_tx_power =
3871 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) / 100;
3872
3873 idx++;
3874 }
3875
3876 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
3877 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
3878 nla_len(nl_rate), rate_policy);
3879 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
3880 continue;
3881 mode->num_rates++;
3882 }
3883
e62fb0a0 3884 mode->rates = os_zalloc(mode->num_rates * sizeof(int));
282d5590
JM
3885 if (!mode->rates)
3886 return NL_SKIP;
3887
3888 idx = 0;
3889
3890 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
3891 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
3892 nla_len(nl_rate), rate_policy);
3893 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
3894 continue;
fb7842aa 3895 mode->rates[idx] = nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE]);
282d5590
JM
3896
3897 /* crude heuristic */
3898 if (mode->mode == HOSTAPD_MODE_IEEE80211B &&
fb7842aa 3899 mode->rates[idx] > 200)
282d5590
JM
3900 mode->mode = HOSTAPD_MODE_IEEE80211G;
3901
282d5590
JM
3902 idx++;
3903 }
3904 }
3905
3906 return NL_SKIP;
3907}
3908
3909static struct hostapd_hw_modes *
3910wpa_driver_nl80211_add_11b(struct hostapd_hw_modes *modes, u16 *num_modes)
3911{
3912 u16 m;
3913 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
3914 int i, mode11g_idx = -1;
3915
3916 /* If only 802.11g mode is included, use it to construct matching
3917 * 802.11b mode data. */
3918
3919 for (m = 0; m < *num_modes; m++) {
3920 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
3921 return modes; /* 802.11b already included */
3922 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
3923 mode11g_idx = m;
3924 }
3925
3926 if (mode11g_idx < 0)
3927 return modes; /* 2.4 GHz band not supported at all */
3928
3929 nmodes = os_realloc(modes, (*num_modes + 1) * sizeof(*nmodes));
3930 if (nmodes == NULL)
3931 return modes; /* Could not add 802.11b mode */
3932
3933 mode = &nmodes[*num_modes];
3934 os_memset(mode, 0, sizeof(*mode));
3935 (*num_modes)++;
3936 modes = nmodes;
3937
3938 mode->mode = HOSTAPD_MODE_IEEE80211B;
3939
3940 mode11g = &modes[mode11g_idx];
3941 mode->num_channels = mode11g->num_channels;
3942 mode->channels = os_malloc(mode11g->num_channels *
3943 sizeof(struct hostapd_channel_data));
3944 if (mode->channels == NULL) {
3945 (*num_modes)--;
3946 return modes; /* Could not add 802.11b mode */
3947 }
3948 os_memcpy(mode->channels, mode11g->channels,
3949 mode11g->num_channels * sizeof(struct hostapd_channel_data));
3950
3951 mode->num_rates = 0;
fb7842aa 3952 mode->rates = os_malloc(4 * sizeof(int));
282d5590
JM
3953 if (mode->rates == NULL) {
3954 os_free(mode->channels);
3955 (*num_modes)--;
3956 return modes; /* Could not add 802.11b mode */
3957 }
3958
3959 for (i = 0; i < mode11g->num_rates; i++) {
fb7842aa
JM
3960 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
3961 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
282d5590
JM
3962 continue;
3963 mode->rates[mode->num_rates] = mode11g->rates[i];
3964 mode->num_rates++;
3965 if (mode->num_rates == 4)
3966 break;
3967 }
3968
3969 if (mode->num_rates == 0) {
3970 os_free(mode->channels);
3971 os_free(mode->rates);
3972 (*num_modes)--;
3973 return modes; /* No 802.11b rates */
3974 }
3975
3976 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
3977 "information");
3978
3979 return modes;
3980}
3981
3982
d8e66e80
JM
3983static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
3984 int end)
3985{
3986 int c;
3987
3988 for (c = 0; c < mode->num_channels; c++) {
3989 struct hostapd_channel_data *chan = &mode->channels[c];
3990 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
3991 chan->flag |= HOSTAPD_CHAN_HT40;
3992 }
3993}
3994
3995
3996static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
3997 int end)
3998{
3999 int c;
4000
4001 for (c = 0; c < mode->num_channels; c++) {
4002 struct hostapd_channel_data *chan = &mode->channels[c];
4003 if (!(chan->flag & HOSTAPD_CHAN_HT40))
4004 continue;
4005 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
4006 chan->flag |= HOSTAPD_CHAN_HT40MINUS;
4007 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
4008 chan->flag |= HOSTAPD_CHAN_HT40PLUS;
4009 }
4010}
4011
4012
4013static void nl80211_reg_rule_ht40(struct nlattr *tb[],
4014 struct phy_info_arg *results)
4015{
4016 u32 start, end, max_bw;
4017 u16 m;
4018
4019 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
4020 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
4021 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
4022 return;
4023
4024 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
4025 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
4026 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
4027
4028 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz",
4029 start, end, max_bw);
4030 if (max_bw < 40)
4031 return;
4032
4033 for (m = 0; m < *results->num_modes; m++) {
4034 if (!(results->modes[m].ht_capab &
4035 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
4036 continue;
4037 nl80211_set_ht40_mode(&results->modes[m], start, end);
4038 }
4039}
4040
4041
4042static void nl80211_reg_rule_sec(struct nlattr *tb[],
4043 struct phy_info_arg *results)
4044{
4045 u32 start, end, max_bw;
4046 u16 m;
4047
4048 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
4049 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
4050 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
4051 return;
4052
4053 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
4054 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
4055 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
4056
4057 if (max_bw < 20)
4058 return;
4059
4060 for (m = 0; m < *results->num_modes; m++) {
4061 if (!(results->modes[m].ht_capab &
4062 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
4063 continue;
4064 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
4065 }
4066}
4067
4068
4069static int nl80211_get_reg(struct nl_msg *msg, void *arg)
4070{
4071 struct phy_info_arg *results = arg;
4072 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
4073 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4074 struct nlattr *nl_rule;
4075 struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
4076 int rem_rule;
4077 static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
4078 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
4079 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
4080 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
4081 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
4082 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
4083 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
4084 };
4085
4086 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4087 genlmsg_attrlen(gnlh, 0), NULL);
4088 if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
4089 !tb_msg[NL80211_ATTR_REG_RULES]) {
4090 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
4091 "available");
4092 return NL_SKIP;
4093 }
4094
4095 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
4096 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
4097
4098 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
4099 {
4100 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
4101 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
4102 nl80211_reg_rule_ht40(tb_rule, results);
4103 }
4104
4105 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
4106 {
4107 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
4108 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
4109 nl80211_reg_rule_sec(tb_rule, results);
4110 }
4111
4112 return NL_SKIP;
4113}
4114
4115
4116static int nl80211_set_ht40_flags(struct wpa_driver_nl80211_data *drv,
4117 struct phy_info_arg *results)
4118{
4119 struct nl_msg *msg;
4120
4121 msg = nlmsg_alloc();
4122 if (!msg)
4123 return -ENOMEM;
4124
9fb04070 4125 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
d8e66e80
JM
4126 return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
4127}
4128
4129
282d5590
JM
4130static struct hostapd_hw_modes *
4131wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
4132{
a2e40bb6
FF
4133 struct i802_bss *bss = priv;
4134 struct wpa_driver_nl80211_data *drv = bss->drv;
282d5590
JM
4135 struct nl_msg *msg;
4136 struct phy_info_arg result = {
4137 .num_modes = num_modes,
4138 .modes = NULL,
4139 };
4140
4141 *num_modes = 0;
4142 *flags = 0;
4143
4144 msg = nlmsg_alloc();
4145 if (!msg)
4146 return NULL;
4147
9fb04070 4148 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
282d5590
JM
4149
4150 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4151
d8e66e80
JM
4152 if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
4153 nl80211_set_ht40_flags(drv, &result);
282d5590 4154 return wpa_driver_nl80211_add_11b(result.modes, num_modes);
d8e66e80 4155 }
282d5590
JM
4156 nla_put_failure:
4157 return NULL;
4158}
4159
4160
2c2010ac
JM
4161static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
4162 const void *data, size_t len,
fab25336 4163 int encrypt, int noack)
2c2010ac
JM
4164{
4165 __u8 rtap_hdr[] = {
4166 0x00, 0x00, /* radiotap version */
4167 0x0e, 0x00, /* radiotap length */
4168 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
4169 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
4170 0x00, /* padding */
4171 0x00, 0x00, /* RX and TX flags to indicate that */
4172 0x00, 0x00, /* this is the injected frame directly */
4173 };
4174 struct iovec iov[2] = {
4175 {
4176 .iov_base = &rtap_hdr,
4177 .iov_len = sizeof(rtap_hdr),
4178 },
4179 {
4180 .iov_base = (void *) data,
4181 .iov_len = len,
4182 }
4183 };
4184 struct msghdr msg = {
4185 .msg_name = NULL,
4186 .msg_namelen = 0,
4187 .msg_iov = iov,
4188 .msg_iovlen = 2,
4189 .msg_control = NULL,
4190 .msg_controllen = 0,
4191 .msg_flags = 0,
4192 };
ebbec8b2 4193 int res;
fab25336 4194 u16 txflags = 0;
2c2010ac
JM
4195
4196 if (encrypt)
4197 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
4198
866af8b6
JM
4199 if (drv->monitor_sock < 0) {
4200 wpa_printf(MSG_DEBUG, "nl80211: No monitor socket available "
4201 "for %s", __func__);
4202 return -1;
4203 }
4204
fab25336
HS
4205 if (noack)
4206 txflags |= IEEE80211_RADIOTAP_F_TX_NOACK;
4207 *(le16 *) &rtap_hdr[12] = host_to_le16(txflags);
4208
ebbec8b2
JM
4209 res = sendmsg(drv->monitor_sock, &msg, 0);
4210 if (res < 0) {
4211 wpa_printf(MSG_INFO, "nl80211: sendmsg: %s", strerror(errno));
4212 return -1;
4213 }
4214 return 0;
2c2010ac
JM
4215}
4216
4217
4218static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
8cfa3527 4219 size_t data_len, int noack)
2c2010ac 4220{
a2e40bb6
FF
4221 struct i802_bss *bss = priv;
4222 struct wpa_driver_nl80211_data *drv = bss->drv;
2c2010ac 4223 struct ieee80211_mgmt *mgmt;
7a47d567 4224 int encrypt = 1;
2c2010ac
JM
4225 u16 fc;
4226
4227 mgmt = (struct ieee80211_mgmt *) data;
4228 fc = le_to_host16(mgmt->frame_control);
4229
b1f625e0 4230 if (is_sta_interface(drv->nlmode) &&
5582a5d1
JB
4231 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
4232 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
4233 /*
4234 * The use of last_mgmt_freq is a bit of a hack,
4235 * but it works due to the single-threaded nature
4236 * of wpa_supplicant.
4237 */
88df0ef7
JB
4238 return nl80211_send_frame_cmd(bss, drv->last_mgmt_freq, 0,
4239 data, data_len, NULL, 1, noack,
4240 1);
5582a5d1
JB
4241 }
4242
61cbe2ff 4243 if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
88df0ef7
JB
4244 return nl80211_send_frame_cmd(bss, drv->ap_oper_freq, 0,
4245 data, data_len, NULL, 0, noack,
4246 0);
86957e62
JM
4247 }
4248
2c2010ac
JM
4249 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
4250 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
4251 /*
4252 * Only one of the authentication frame types is encrypted.
4253 * In order for static WEP encryption to work properly (i.e.,
4254 * to not encrypt the frame), we need to tell mac80211 about
4255 * the frames that must not be encrypted.
4256 */
4257 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
4258 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
7a47d567
JB
4259 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
4260 encrypt = 0;
2c2010ac
JM
4261 }
4262
fab25336
HS
4263 return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt,
4264 noack);
2c2010ac
JM
4265}
4266
4267
fd13a541
JM
4268static int nl80211_set_ap_isolate(struct i802_bss *bss, int enabled)
4269{
4270 struct wpa_driver_nl80211_data *drv = bss->drv;
4271 struct nl_msg *msg;
4272
4273 msg = nlmsg_alloc();
4274 if (!msg)
4275 return -ENOMEM;
4276
9fb04070 4277 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_BSS);
fd13a541
JM
4278
4279 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
4280 NLA_PUT_U8(msg, NL80211_ATTR_AP_ISOLATE, enabled);
4281
4282 return send_and_recv_msgs(drv, msg, NULL, NULL);
4283 nla_put_failure:
4284 return -ENOBUFS;
4285}
4286
4287
31357268
JM
4288static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
4289 int slot, int ht_opmode)
4290{
4291 struct wpa_driver_nl80211_data *drv = bss->drv;
4292 struct nl_msg *msg;
4293
4294 msg = nlmsg_alloc();
4295 if (!msg)
4296 return -ENOMEM;
4297
9fb04070 4298 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_BSS);
31357268
JM
4299
4300 if (cts >= 0)
4301 NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
4302 if (preamble >= 0)
4303 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
4304 if (slot >= 0)
4305 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
4306 if (ht_opmode >= 0)
4307 NLA_PUT_U16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode);
4308 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
4309
4310 return send_and_recv_msgs(drv, msg, NULL, NULL);
4311 nla_put_failure:
4312 return -ENOBUFS;
4313}
4314
4315
19c3b566
JM
4316static int wpa_driver_nl80211_set_ap(void *priv,
4317 struct wpa_driver_ap_params *params)
d2440ba0 4318{
a2e40bb6
FF
4319 struct i802_bss *bss = priv;
4320 struct wpa_driver_nl80211_data *drv = bss->drv;
d2440ba0
JM
4321 struct nl_msg *msg;
4322 u8 cmd = NL80211_CMD_NEW_BEACON;
4323 int ret;
b4fd6fab 4324 int beacon_set;
8b897f5a 4325 int ifindex = if_nametoindex(bss->ifname);
b11d1d64
JM
4326 int num_suites;
4327 u32 suites[10];
4328 u32 ver;
b4fd6fab 4329
b4fd6fab 4330 beacon_set = bss->beacon_set;
d2440ba0
JM
4331
4332 msg = nlmsg_alloc();
4333 if (!msg)
4334 return -ENOMEM;
4335
4336 wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
b4fd6fab
JM
4337 beacon_set);
4338 if (beacon_set)
d2440ba0
JM
4339 cmd = NL80211_CMD_SET_BEACON;
4340
9fb04070 4341 nl80211_cmd(drv, msg, 0, cmd);
19c3b566
JM
4342 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, params->head_len, params->head);
4343 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len, params->tail);
b4fd6fab 4344 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
19c3b566
JM
4345 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
4346 NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
ccb941e6
JM
4347 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
4348 params->ssid);
97a7a0b5
JM
4349 switch (params->hide_ssid) {
4350 case NO_SSID_HIDING:
4351 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
4352 NL80211_HIDDEN_SSID_NOT_IN_USE);
4353 break;
4354 case HIDDEN_SSID_ZERO_LEN:
4355 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
4356 NL80211_HIDDEN_SSID_ZERO_LEN);
4357 break;
4358 case HIDDEN_SSID_ZERO_CONTENTS:
4359 NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
4360 NL80211_HIDDEN_SSID_ZERO_CONTENTS);
4361 break;
4362 }
b11d1d64
JM
4363 if (params->privacy)
4364 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
4365 if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
4366 (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
4367 /* Leave out the attribute */
4368 } else if (params->auth_algs & WPA_AUTH_ALG_SHARED)
4369 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
4370 NL80211_AUTHTYPE_SHARED_KEY);
4371 else
4372 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
4373 NL80211_AUTHTYPE_OPEN_SYSTEM);
4374
4375 ver = 0;
4376 if (params->wpa_version & WPA_PROTO_WPA)
4377 ver |= NL80211_WPA_VERSION_1;
4378 if (params->wpa_version & WPA_PROTO_RSN)
4379 ver |= NL80211_WPA_VERSION_2;
4380 if (ver)
4381 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
4382
4383 num_suites = 0;
4384 if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
4385 suites[num_suites++] = WLAN_AKM_SUITE_8021X;
4386 if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
4387 suites[num_suites++] = WLAN_AKM_SUITE_PSK;
4388 if (num_suites) {
4389 NLA_PUT(msg, NL80211_ATTR_AKM_SUITES,
4390 num_suites * sizeof(u32), suites);
4391 }
4392
4393 num_suites = 0;
4394 if (params->pairwise_ciphers & WPA_CIPHER_CCMP)
4395 suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
4396 if (params->pairwise_ciphers & WPA_CIPHER_TKIP)
4397 suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
4398 if (params->pairwise_ciphers & WPA_CIPHER_WEP104)
4399 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
4400 if (params->pairwise_ciphers & WPA_CIPHER_WEP40)
4401 suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
4402 if (num_suites) {
4403 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
4404 num_suites * sizeof(u32), suites);
4405 }
4406
4407 switch (params->group_cipher) {
4408 case WPA_CIPHER_CCMP:
4409 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
4410 WLAN_CIPHER_SUITE_CCMP);
4411 break;
4412 case WPA_CIPHER_TKIP:
4413 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
4414 WLAN_CIPHER_SUITE_TKIP);
4415 break;
4416 case WPA_CIPHER_WEP104:
4417 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
4418 WLAN_CIPHER_SUITE_WEP104);
4419 break;
4420 case WPA_CIPHER_WEP40:
4421 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
4422 WLAN_CIPHER_SUITE_WEP40);
4423 break;
4424 }
d2440ba0 4425
fb91db56
JM
4426 if (params->beacon_ies) {
4427 NLA_PUT(msg, NL80211_ATTR_IE, wpabuf_len(params->beacon_ies),
4428 wpabuf_head(params->beacon_ies));
4429 }
4430 if (params->proberesp_ies) {
4431 NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
4432 wpabuf_len(params->proberesp_ies),
4433 wpabuf_head(params->proberesp_ies));
4434 }
4435 if (params->assocresp_ies) {
4436 NLA_PUT(msg, NL80211_ATTR_IE_ASSOC_RESP,
4437 wpabuf_len(params->assocresp_ies),
4438 wpabuf_head(params->assocresp_ies));
4439 }
4440
d2440ba0
JM
4441 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4442 if (ret) {
4443 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
4444 ret, strerror(-ret));
b4fd6fab 4445 } else {
b4fd6fab 4446 bss->beacon_set = 1;
fd13a541
JM
4447 ret = nl80211_set_ap_isolate(bss, params->isolate);
4448 if (!params->isolate && ret) {
4449 wpa_printf(MSG_DEBUG, "nl80211: Ignore AP isolation "
4450 "configuration error since isolation is "
4451 "not used");
4452 ret = 0;
4453 }
31357268
JM
4454
4455 nl80211_set_bss(bss, params->cts_protect, params->preamble,
4456 params->short_slot_time, params->ht_opmode);
b4fd6fab 4457 }
d2440ba0
JM
4458 return ret;
4459 nla_put_failure:
4460 return -ENOBUFS;
4461}
4462
4463
f019981a
JM
4464static int wpa_driver_nl80211_set_freq(struct wpa_driver_nl80211_data *drv,
4465 int freq, int ht_enabled,
4466 int sec_channel_offset)
1581b38b
JM
4467{
4468 struct nl_msg *msg;
d2440ba0 4469 int ret;
1581b38b 4470
44dc872e
JM
4471 wpa_printf(MSG_DEBUG, "nl80211: Set freq %d (ht_enabled=%d "
4472 "sec_channel_offset=%d)",
4473 freq, ht_enabled, sec_channel_offset);
1581b38b
JM
4474 msg = nlmsg_alloc();
4475 if (!msg)
4476 return -1;
4477
9fb04070 4478 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
1581b38b
JM
4479
4480 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
f019981a
JM
4481 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
4482 if (ht_enabled) {
4483 switch (sec_channel_offset) {
4484 case -1:
4485 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
4486 NL80211_CHAN_HT40MINUS);
4487 break;
4488 case 1:
4489 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
4490 NL80211_CHAN_HT40PLUS);
4491 break;
4492 default:
4493 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
4494 NL80211_CHAN_HT20);
4495 break;
4496 }
4497 }
1581b38b 4498
d2440ba0
JM
4499 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4500 if (ret == 0)
1581b38b 4501 return 0;
f019981a
JM
4502 wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
4503 "%d (%s)", freq, ret, strerror(-ret));
1581b38b
JM
4504nla_put_failure:
4505 return -1;
4506}
4507
0f4e8b4f 4508
95ab6063
AN
4509static u32 sta_flags_nl80211(int flags)
4510{
4511 u32 f = 0;
4512
4513 if (flags & WPA_STA_AUTHORIZED)
4514 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
4515 if (flags & WPA_STA_WMM)
4516 f |= BIT(NL80211_STA_FLAG_WME);
4517 if (flags & WPA_STA_SHORT_PREAMBLE)
4518 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
4519 if (flags & WPA_STA_MFP)
4520 f |= BIT(NL80211_STA_FLAG_MFP);
45b722f1
AN
4521 if (flags & WPA_STA_TDLS_PEER)
4522 f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
95ab6063
AN
4523
4524 return f;
4525}
4526
4527
62847751 4528static int wpa_driver_nl80211_sta_add(void *priv,
0f4e8b4f
JM
4529 struct hostapd_sta_add_params *params)
4530{
a2e40bb6
FF
4531 struct i802_bss *bss = priv;
4532 struct wpa_driver_nl80211_data *drv = bss->drv;
0f4e8b4f 4533 struct nl_msg *msg;
95ab6063 4534 struct nl80211_sta_flag_update upd;
0f4e8b4f
JM
4535 int ret = -ENOBUFS;
4536
45b722f1
AN
4537 if ((params->flags & WPA_STA_TDLS_PEER) &&
4538 !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
4539 return -EOPNOTSUPP;
4540
0f4e8b4f
JM
4541 msg = nlmsg_alloc();
4542 if (!msg)
4543 return -ENOMEM;
4544
45b722f1
AN
4545 nl80211_cmd(drv, msg, 0, params->set ? NL80211_CMD_SET_STATION :
4546 NL80211_CMD_NEW_STATION);
0f4e8b4f 4547
62847751 4548 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
0f4e8b4f 4549 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
0f4e8b4f
JM
4550 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
4551 params->supp_rates);
45b722f1
AN
4552 if (!params->set) {
4553 NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
4554 NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
4555 params->listen_interval);
4556 }
0f4e8b4f
JM
4557 if (params->ht_capabilities) {
4558 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
fc4e2d95
JM
4559 sizeof(*params->ht_capabilities),
4560 params->ht_capabilities);
0f4e8b4f 4561 }
0f4e8b4f 4562
95ab6063
AN
4563 os_memset(&upd, 0, sizeof(upd));
4564 upd.mask = sta_flags_nl80211(params->flags);
4565 upd.set = upd.mask;
4566 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
4567
0f4e8b4f
JM
4568 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4569 if (ret)
45b722f1
AN
4570 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
4571 "result: %d (%s)", params->set ? "SET" : "NEW", ret,
4572 strerror(-ret));
0f4e8b4f
JM
4573 if (ret == -EEXIST)
4574 ret = 0;
4575 nla_put_failure:
4576 return ret;
4577}
4578
4579
4580static int wpa_driver_nl80211_sta_remove(void *priv, const u8 *addr)
4581{
a2e40bb6
FF
4582 struct i802_bss *bss = priv;
4583 struct wpa_driver_nl80211_data *drv = bss->drv;
0f4e8b4f
JM
4584 struct nl_msg *msg;
4585 int ret;
4586
4587 msg = nlmsg_alloc();
4588 if (!msg)
4589 return -ENOMEM;
4590
9fb04070 4591 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
0f4e8b4f
JM
4592
4593 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 4594 if_nametoindex(bss->ifname));
0f4e8b4f
JM
4595 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
4596
4597 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4598 if (ret == -ENOENT)
4599 return 0;
4600 return ret;
4601 nla_put_failure:
4602 return -ENOBUFS;
4603}
4604
1581b38b 4605
0915d02c
JM
4606static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
4607 int ifidx)
4608{
4609 struct nl_msg *msg;
4610
c6e8e8e4
JM
4611 wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
4612
2135f224
JM
4613 /* stop listening for EAPOL on this interface */
4614 del_ifidx(drv, ifidx);
2135f224 4615
0915d02c
JM
4616 msg = nlmsg_alloc();
4617 if (!msg)
4618 goto nla_put_failure;
4619
9fb04070 4620 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
0915d02c
JM
4621 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
4622
4623 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
4624 return;
4625 nla_put_failure:
e748062b 4626 wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
0915d02c
JM
4627}
4628
4629
a1922f93
JM
4630static const char * nl80211_iftype_str(enum nl80211_iftype mode)
4631{
4632 switch (mode) {
4633 case NL80211_IFTYPE_ADHOC:
4634 return "ADHOC";
4635 case NL80211_IFTYPE_STATION:
4636 return "STATION";
4637 case NL80211_IFTYPE_AP:
4638 return "AP";
4639 case NL80211_IFTYPE_MONITOR:
4640 return "MONITOR";
4641 case NL80211_IFTYPE_P2P_CLIENT:
4642 return "P2P_CLIENT";
4643 case NL80211_IFTYPE_P2P_GO:
4644 return "P2P_GO";
4645 default:
4646 return "unknown";
4647 }
4648}
4649
4650
a35187e7
KH
4651static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
4652 const char *ifname,
4653 enum nl80211_iftype iftype,
fbbfcbac 4654 const u8 *addr, int wds)
0915d02c
JM
4655{
4656 struct nl_msg *msg, *flags = NULL;
4657 int ifidx;
4658 int ret = -ENOBUFS;
4659
a1922f93
JM
4660 wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
4661 iftype, nl80211_iftype_str(iftype));
4662
0915d02c
JM
4663 msg = nlmsg_alloc();
4664 if (!msg)
4665 return -1;
4666
9fb04070 4667 nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_INTERFACE);
0915d02c
JM
4668 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4669 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
4670 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
4671
4672 if (iftype == NL80211_IFTYPE_MONITOR) {
4673 int err;
4674
4675 flags = nlmsg_alloc();
4676 if (!flags)
4677 goto nla_put_failure;
4678
4679 NLA_PUT_FLAG(flags, NL80211_MNTR_FLAG_COOK_FRAMES);
4680
4681 err = nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);
4682
4683 nlmsg_free(flags);
4684
4685 if (err)
4686 goto nla_put_failure;
fbbfcbac
FF
4687 } else if (wds) {
4688 NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
0915d02c
JM
4689 }
4690
4691 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4692 if (ret) {
4693 nla_put_failure:
a35187e7
KH
4694 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
4695 ifname, ret, strerror(-ret));
0915d02c
JM
4696 return ret;
4697 }
4698
4699 ifidx = if_nametoindex(ifname);
c6e8e8e4
JM
4700 wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
4701 ifname, ifidx);
0915d02c
JM
4702
4703 if (ifidx <= 0)
4704 return -1;
4705
2135f224
JM
4706 /* start listening for EAPOL on this interface */
4707 add_ifidx(drv, ifidx);
4708
7bfc47c3 4709 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
c81eff1a 4710 linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
41d931ee
JM
4711 nl80211_remove_iface(drv, ifidx);
4712 return -1;
2135f224 4713 }
2135f224 4714
0915d02c
JM
4715 return ifidx;
4716}
22a7c9d7
JM
4717
4718
a35187e7
KH
4719static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
4720 const char *ifname, enum nl80211_iftype iftype,
fbbfcbac 4721 const u8 *addr, int wds)
a35187e7
KH
4722{
4723 int ret;
4724
fbbfcbac 4725 ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds);
a35187e7 4726
ffbf1eaa 4727 /* if error occurred and interface exists already */
a35187e7
KH
4728 if (ret == -ENFILE && if_nametoindex(ifname)) {
4729 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
4730
4731 /* Try to remove the interface that was already there. */
4732 nl80211_remove_iface(drv, if_nametoindex(ifname));
4733
4734 /* Try to create the interface again */
fbbfcbac
FF
4735 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
4736 wds);
a35187e7
KH
4737 }
4738
b3af99d2 4739 if (ret >= 0 && is_p2p_interface(iftype))
4e5cb1a3
JM
4740 nl80211_disable_11b_rates(drv, ret, 1);
4741
a35187e7
KH
4742 return ret;
4743}
0915d02c 4744
2135f224 4745
0915d02c
JM
4746static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
4747{
4748 struct ieee80211_hdr *hdr;
f8b1f695
JM
4749 u16 fc;
4750 union wpa_event_data event;
0915d02c
JM
4751
4752 hdr = (struct ieee80211_hdr *) buf;
4753 fc = le_to_host16(hdr->frame_control);
4754
f8b1f695
JM
4755 os_memset(&event, 0, sizeof(event));
4756 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
4757 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
4758 event.tx_status.dst = hdr->addr1;
4759 event.tx_status.data = buf;
4760 event.tx_status.data_len = len;
4761 event.tx_status.ack = ok;
4762 wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event);
0915d02c
JM
4763}
4764
4765
4b9841d3 4766static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
0d9fc3d8 4767 u8 *buf, size_t len)
0915d02c 4768{
9b90955e
JB
4769 struct ieee80211_hdr *hdr = (void *)buf;
4770 u16 fc;
f8b1f695 4771 union wpa_event_data event;
9b90955e
JB
4772
4773 if (len < sizeof(*hdr))
4774 return;
4775
4776 fc = le_to_host16(hdr->frame_control);
4777
f8b1f695 4778 os_memset(&event, 0, sizeof(event));
9b90955e
JB
4779 event.rx_from_unknown.bssid = get_hdr_bssid(hdr, len);
4780 event.rx_from_unknown.addr = hdr->addr2;
4781 event.rx_from_unknown.wds = (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) ==
4782 (WLAN_FC_FROMDS | WLAN_FC_TODS);
f8b1f695 4783 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
4b9841d3 4784}
0915d02c 4785
4b9841d3
JM
4786
4787static void handle_frame(struct wpa_driver_nl80211_data *drv,
2a8b7416 4788 u8 *buf, size_t len, int datarate, int ssi_signal)
4b9841d3
JM
4789{
4790 struct ieee80211_hdr *hdr;
f8b1f695
JM
4791 u16 fc;
4792 union wpa_event_data event;
0915d02c
JM
4793
4794 hdr = (struct ieee80211_hdr *) buf;
4795 fc = le_to_host16(hdr->frame_control);
0915d02c 4796
4b9841d3 4797 switch (WLAN_FC_GET_TYPE(fc)) {
0915d02c 4798 case WLAN_FC_TYPE_MGMT:
f8b1f695
JM
4799 os_memset(&event, 0, sizeof(event));
4800 event.rx_mgmt.frame = buf;
4801 event.rx_mgmt.frame_len = len;
2a8b7416
JM
4802 event.rx_mgmt.datarate = datarate;
4803 event.rx_mgmt.ssi_signal = ssi_signal;
f8b1f695 4804 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
0915d02c
JM
4805 break;
4806 case WLAN_FC_TYPE_CTRL:
4807 /* can only get here with PS-Poll frames */
4808 wpa_printf(MSG_DEBUG, "CTRL");
0d9fc3d8 4809 from_unknown_sta(drv, buf, len);
0915d02c
JM
4810 break;
4811 case WLAN_FC_TYPE_DATA:
0d9fc3d8 4812 from_unknown_sta(drv, buf, len);
0915d02c
JM
4813 break;
4814 }
4815}
4816
4817
4818static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
4819{
4820 struct wpa_driver_nl80211_data *drv = eloop_ctx;
4821 int len;
4822 unsigned char buf[3000];
4823 struct ieee80211_radiotap_iterator iter;
4824 int ret;
2a8b7416 4825 int datarate = 0, ssi_signal = 0;
4b9841d3 4826 int injected = 0, failed = 0, rxflags = 0;
0915d02c
JM
4827
4828 len = recv(sock, buf, sizeof(buf), 0);
4829 if (len < 0) {
4830 perror("recv");
4831 return;
4832 }
4833
4834 if (ieee80211_radiotap_iterator_init(&iter, (void*)buf, len)) {
4835 printf("received invalid radiotap frame\n");
4836 return;
4837 }
4838
0915d02c
JM
4839 while (1) {
4840 ret = ieee80211_radiotap_iterator_next(&iter);
4841 if (ret == -ENOENT)
4842 break;
4843 if (ret) {
4844 printf("received invalid radiotap frame (%d)\n", ret);
4845 return;
4846 }
4847 switch (iter.this_arg_index) {
4848 case IEEE80211_RADIOTAP_FLAGS:
4849 if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
4850 len -= 4;
4851 break;
4852 case IEEE80211_RADIOTAP_RX_FLAGS:
4853 rxflags = 1;
4854 break;
4855 case IEEE80211_RADIOTAP_TX_FLAGS:
4856 injected = 1;
4857 failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
4858 IEEE80211_RADIOTAP_F_TX_FAIL;
4859 break;
4860 case IEEE80211_RADIOTAP_DATA_RETRIES:
4861 break;
4862 case IEEE80211_RADIOTAP_CHANNEL:
2a8b7416 4863 /* TODO: convert from freq/flags to channel number */
0915d02c
JM
4864 break;
4865 case IEEE80211_RADIOTAP_RATE:
2a8b7416 4866 datarate = *iter.this_arg * 5;
0915d02c
JM
4867 break;
4868 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
2a8b7416 4869 ssi_signal = *iter.this_arg;
0915d02c
JM
4870 break;
4871 }
4872 }
4873
4874 if (rxflags && injected)
4875 return;
4876
4877 if (!injected)
4b9841d3 4878 handle_frame(drv, buf + iter.max_length,
2a8b7416 4879 len - iter.max_length, datarate, ssi_signal);
0915d02c 4880 else
4b9841d3
JM
4881 handle_tx_callback(drv->ctx, buf + iter.max_length,
4882 len - iter.max_length, !failed);
0915d02c
JM
4883}
4884
4885
4886/*
4887 * we post-process the filter code later and rewrite
4888 * this to the offset to the last instruction
4889 */
4890#define PASS 0xFF
4891#define FAIL 0xFE
4892
4893static struct sock_filter msock_filter_insns[] = {
4894 /*
4895 * do a little-endian load of the radiotap length field
4896 */
4897 /* load lower byte into A */
4898 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
4899 /* put it into X (== index register) */
4900 BPF_STMT(BPF_MISC| BPF_TAX, 0),
4901 /* load upper byte into A */
4902 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 3),
4903 /* left-shift it by 8 */
4904 BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
4905 /* or with X */
4906 BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
4907 /* put result into X */
4908 BPF_STMT(BPF_MISC| BPF_TAX, 0),
4909
4910 /*
4911 * Allow management frames through, this also gives us those
4912 * management frames that we sent ourselves with status
4913 */
4914 /* load the lower byte of the IEEE 802.11 frame control field */
4915 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
4916 /* mask off frame type and version */
4917 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
4918 /* accept frame if it's both 0, fall through otherwise */
4919 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
4920
4921 /*
4922 * TODO: add a bit to radiotap RX flags that indicates
4923 * that the sending station is not associated, then
4924 * add a filter here that filters on our DA and that flag
4925 * to allow us to deauth frames to that bad station.
4926 *
65ae1afd 4927 * For now allow all To DS data frames through.
0915d02c 4928 */
65ae1afd
HS
4929 /* load the IEEE 802.11 frame control field */
4930 BPF_STMT(BPF_LD | BPF_H | BPF_IND, 0),
4931 /* mask off frame type, version and DS status */
4932 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0F03),
4933 /* accept frame if version 0, type 2 and To DS, fall through otherwise
4934 */
4935 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0801, PASS, 0),
0915d02c
JM
4936
4937#if 0
4938 /*
fbbfcbac 4939 * drop non-data frames
0915d02c
JM
4940 */
4941 /* load the lower byte of the frame control field */
4942 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
4943 /* mask off QoS bit */
4944 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0c),
4945 /* drop non-data frames */
4946 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 8, 0, FAIL),
fbbfcbac 4947#endif
0915d02c 4948 /* load the upper byte of the frame control field */
fbbfcbac 4949 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
0915d02c
JM
4950 /* mask off toDS/fromDS */
4951 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x03),
fbbfcbac
FF
4952 /* accept WDS frames */
4953 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 3, PASS, 0),
0915d02c
JM
4954
4955 /*
4956 * add header length to index
4957 */
4958 /* load the lower byte of the frame control field */
4959 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
4960 /* mask off QoS bit */
4961 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80),
4962 /* right shift it by 6 to give 0 or 2 */
4963 BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 6),
4964 /* add data frame header length */
4965 BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 24),
4966 /* add index, was start of 802.11 header */
4967 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
4968 /* move to index, now start of LL header */
4969 BPF_STMT(BPF_MISC | BPF_TAX, 0),
4970
4971 /*
4972 * Accept empty data frames, we use those for
4973 * polling activity.
4974 */
4975 BPF_STMT(BPF_LD | BPF_W | BPF_LEN, 0),
4976 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
4977
4978 /*
4979 * Accept EAPOL frames
4980 */
4981 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 0),
4982 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
4983 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 4),
4984 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
4985
4986 /* keep these last two statements or change the code below */
4987 /* return 0 == "DROP" */
4988 BPF_STMT(BPF_RET | BPF_K, 0),
4989 /* return ~0 == "keep all" */
4990 BPF_STMT(BPF_RET | BPF_K, ~0),
4991};
4992
4993static struct sock_fprog msock_filter = {
4994 .len = sizeof(msock_filter_insns)/sizeof(msock_filter_insns[0]),
4995 .filter = msock_filter_insns,
4996};
4997
4998
4999static int add_monitor_filter(int s)
5000{
5001 int idx;
5002
5003 /* rewrite all PASS/FAIL jump offsets */
5004 for (idx = 0; idx < msock_filter.len; idx++) {
5005 struct sock_filter *insn = &msock_filter_insns[idx];
5006
5007 if (BPF_CLASS(insn->code) == BPF_JMP) {
5008 if (insn->code == (BPF_JMP|BPF_JA)) {
5009 if (insn->k == PASS)
5010 insn->k = msock_filter.len - idx - 2;
5011 else if (insn->k == FAIL)
5012 insn->k = msock_filter.len - idx - 3;
5013 }
5014
5015 if (insn->jt == PASS)
5016 insn->jt = msock_filter.len - idx - 2;
5017 else if (insn->jt == FAIL)
5018 insn->jt = msock_filter.len - idx - 3;
5019
5020 if (insn->jf == PASS)
5021 insn->jf = msock_filter.len - idx - 2;
5022 else if (insn->jf == FAIL)
5023 insn->jf = msock_filter.len - idx - 3;
5024 }
5025 }
5026
5027 if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
5028 &msock_filter, sizeof(msock_filter))) {
5029 perror("SO_ATTACH_FILTER");
5030 return -1;
5031 }
5032
5033 return 0;
5034}
5035
5036
460456f8
JM
5037static void nl80211_remove_monitor_interface(
5038 struct wpa_driver_nl80211_data *drv)
5039{
5040 if (drv->monitor_ifidx >= 0) {
5041 nl80211_remove_iface(drv, drv->monitor_ifidx);
5042 drv->monitor_ifidx = -1;
5043 }
504e905c
JM
5044 if (drv->monitor_sock >= 0) {
5045 eloop_unregister_read_sock(drv->monitor_sock);
5046 close(drv->monitor_sock);
5047 drv->monitor_sock = -1;
5048 }
460456f8
JM
5049}
5050
5051
0915d02c
JM
5052static int
5053nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
5054{
5055 char buf[IFNAMSIZ];
5056 struct sockaddr_ll ll;
5057 int optval;
5058 socklen_t optlen;
0915d02c 5059
6758b167
JJ
5060 if (os_strncmp(drv->first_bss.ifname, "p2p-", 4) == 0) {
5061 /*
5062 * P2P interface name is of the format p2p-%s-%d. For monitor
5063 * interface name corresponding to P2P GO, replace "p2p-" with
5064 * "mon-" to retain the same interface name length and to
5065 * indicate that it is a monitor interface.
5066 */
5067 snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss.ifname + 4);
5068 } else {
5069 /* Non-P2P interface with AP functionality. */
5070 snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss.ifname);
5071 }
5072
0915d02c
JM
5073 buf[IFNAMSIZ - 1] = '\0';
5074
5075 drv->monitor_ifidx =
fbbfcbac
FF
5076 nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
5077 0);
0915d02c 5078
866af8b6 5079 if (drv->monitor_ifidx == -EOPNOTSUPP) {
61cbe2ff
JB
5080 /*
5081 * This is backward compatibility for a few versions of
5082 * the kernel only that didn't advertise the right
5083 * attributes for the only driver that then supported
5084 * AP mode w/o monitor -- ath6kl.
5085 */
866af8b6
JM
5086 wpa_printf(MSG_DEBUG, "nl80211: Driver does not support "
5087 "monitor interface type - try to run without it");
61cbe2ff 5088 drv->device_ap_sme = 1;
866af8b6
JM
5089 }
5090
0915d02c
JM
5091 if (drv->monitor_ifidx < 0)
5092 return -1;
5093
c81eff1a 5094 if (linux_set_iface_flags(drv->global->ioctl_sock, buf, 1))
0915d02c 5095 goto error;
0915d02c
JM
5096
5097 memset(&ll, 0, sizeof(ll));
5098 ll.sll_family = AF_PACKET;
5099 ll.sll_ifindex = drv->monitor_ifidx;
5100 drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
5101 if (drv->monitor_sock < 0) {
5102 perror("socket[PF_PACKET,SOCK_RAW]");
5103 goto error;
5104 }
5105
5106 if (add_monitor_filter(drv->monitor_sock)) {
5107 wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
5108 "interface; do filtering in user space");
5109 /* This works, but will cost in performance. */
5110 }
5111
2135f224 5112 if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
0915d02c
JM
5113 perror("monitor socket bind");
5114 goto error;
5115 }
5116
5117 optlen = sizeof(optval);
5118 optval = 20;
5119 if (setsockopt
5120 (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
5121 perror("Failed to set socket priority");
5122 goto error;
5123 }
5124
5125 if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
5126 drv, NULL)) {
5127 printf("Could not register monitor read socket\n");
5128 goto error;
5129 }
5130
5131 return 0;
5132 error:
460456f8 5133 nl80211_remove_monitor_interface(drv);
0915d02c
JM
5134 return -1;
5135}
5136
db149ac9 5137
5fb1a232 5138#ifdef CONFIG_AP
f10bfc9a
JM
5139static int nl80211_send_eapol_data(struct i802_bss *bss,
5140 const u8 *addr, const u8 *data,
d12dab4c 5141 size_t data_len)
f10bfc9a 5142{
d12dab4c
JB
5143 struct sockaddr_ll ll;
5144 int ret;
5145
5146 if (bss->drv->eapol_tx_sock < 0) {
5147 wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
f10bfc9a
JM
5148 return -1;
5149 }
5150
d12dab4c
JB
5151 os_memset(&ll, 0, sizeof(ll));
5152 ll.sll_family = AF_PACKET;
5153 ll.sll_ifindex = bss->ifindex;
5154 ll.sll_protocol = htons(ETH_P_PAE);
5155 ll.sll_halen = ETH_ALEN;
5156 os_memcpy(ll.sll_addr, addr, ETH_ALEN);
5157 ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
5158 (struct sockaddr *) &ll, sizeof(ll));
5159 if (ret < 0)
5160 wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
5161 strerror(errno));
5162
5163 return ret;
f10bfc9a 5164}
5fb1a232
JM
5165#endif /* CONFIG_AP */
5166
f10bfc9a 5167
db149ac9
JM
5168static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
5169
5170static int wpa_driver_nl80211_hapd_send_eapol(
5171 void *priv, const u8 *addr, const u8 *data,
4378fc14 5172 size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
db149ac9 5173{
a2e40bb6
FF
5174 struct i802_bss *bss = priv;
5175 struct wpa_driver_nl80211_data *drv = bss->drv;
db149ac9
JM
5176 struct ieee80211_hdr *hdr;
5177 size_t len;
5178 u8 *pos;
5179 int res;
4378fc14 5180 int qos = flags & WPA_STA_WMM;
db149ac9 5181
5fb1a232 5182#ifdef CONFIG_AP
61cbe2ff 5183 if (drv->device_ap_sme)
d12dab4c 5184 return nl80211_send_eapol_data(bss, addr, data, data_len);
5fb1a232 5185#endif /* CONFIG_AP */
f10bfc9a 5186
db149ac9
JM
5187 len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
5188 data_len;
5189 hdr = os_zalloc(len);
5190 if (hdr == NULL) {
5191 printf("malloc() failed for i802_send_data(len=%lu)\n",
5192 (unsigned long) len);
5193 return -1;
5194 }
5195
5196 hdr->frame_control =
5197 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
5198 hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
5199 if (encrypt)
5200 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
db149ac9
JM
5201 if (qos) {
5202 hdr->frame_control |=
5203 host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
5204 }
db149ac9
JM
5205
5206 memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
5207 memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
5208 memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
5209 pos = (u8 *) (hdr + 1);
5210
db149ac9
JM
5211 if (qos) {
5212 /* add an empty QoS header if needed */
5213 pos[0] = 0;
5214 pos[1] = 0;
5215 pos += 2;
5216 }
db149ac9
JM
5217
5218 memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
5219 pos += sizeof(rfc1042_header);
5220 WPA_PUT_BE16(pos, ETH_P_PAE);
5221 pos += 2;
5222 memcpy(pos, data, data_len);
5223
fab25336 5224 res = wpa_driver_nl80211_send_frame(drv, (u8 *) hdr, len, encrypt, 0);
db149ac9
JM
5225 if (res < 0) {
5226 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
5227 "failed: %d (%s)",
5228 (unsigned long) len, errno, strerror(errno));
5229 }
7bf12757 5230 os_free(hdr);
db149ac9
JM
5231
5232 return res;
5233}
5234
a8d6ffa4 5235
3234cba4
JM
5236static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
5237 int total_flags,
4c32757d 5238 int flags_or, int flags_and)
a8d6ffa4 5239{
a2e40bb6
FF
5240 struct i802_bss *bss = priv;
5241 struct wpa_driver_nl80211_data *drv = bss->drv;
a8d6ffa4 5242 struct nl_msg *msg, *flags = NULL;
7e76ee9c 5243 struct nl80211_sta_flag_update upd;
a8d6ffa4
JM
5244
5245 msg = nlmsg_alloc();
5246 if (!msg)
5247 return -ENOMEM;
5248
5249 flags = nlmsg_alloc();
5250 if (!flags) {
5251 nlmsg_free(msg);
5252 return -ENOMEM;
5253 }
5254
9fb04070 5255 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
a8d6ffa4
JM
5256
5257 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
3234cba4 5258 if_nametoindex(bss->ifname));
a8d6ffa4
JM
5259 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
5260
7e76ee9c
JM
5261 /*
5262 * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
5263 * can be removed eventually.
5264 */
0de39516 5265 if (total_flags & WPA_STA_AUTHORIZED)
a8d6ffa4
JM
5266 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);
5267
0de39516 5268 if (total_flags & WPA_STA_WMM)
a8d6ffa4
JM
5269 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);
5270
0de39516 5271 if (total_flags & WPA_STA_SHORT_PREAMBLE)
a8d6ffa4
JM
5272 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);
5273
0de39516 5274 if (total_flags & WPA_STA_MFP)
a8d6ffa4
JM
5275 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_MFP);
5276
45b722f1
AN
5277 if (total_flags & WPA_STA_TDLS_PEER)
5278 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_TDLS_PEER);
5279
a8d6ffa4
JM
5280 if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))
5281 goto nla_put_failure;
5282
7e76ee9c
JM
5283 os_memset(&upd, 0, sizeof(upd));
5284 upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
5285 upd.set = sta_flags_nl80211(flags_or);
5286 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
5287
a8d6ffa4
JM
5288 nlmsg_free(flags);
5289
5290 return send_and_recv_msgs(drv, msg, NULL, NULL);
5291 nla_put_failure:
5292 nlmsg_free(flags);
5293 return -ENOBUFS;
5294}
5295
0915d02c 5296
1581b38b
JM
5297static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
5298 struct wpa_driver_associate_params *params)
5299{
b1f625e0
EP
5300 enum nl80211_iftype nlmode;
5301
5302 if (params->p2p) {
046b26a2
JM
5303 wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
5304 "group (GO)");
b1f625e0
EP
5305 nlmode = NL80211_IFTYPE_P2P_GO;
5306 } else
5307 nlmode = NL80211_IFTYPE_AP;
5308
5309 if (wpa_driver_nl80211_set_mode(&drv->first_bss, nlmode) ||
f019981a 5310 wpa_driver_nl80211_set_freq(drv, params->freq, 0, 0)) {
460456f8 5311 nl80211_remove_monitor_interface(drv);
1581b38b 5312 return -1;
0915d02c 5313 }
1581b38b 5314
61cbe2ff 5315 if (drv->device_ap_sme) {
86957e62
JM
5316 if (wpa_driver_nl80211_probe_req_report(&drv->first_bss, 1) < 0)
5317 {
5318 wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
5319 "Probe Request frame reporting in AP mode");
5320 /* Try to survive without this */
5321 }
5322 }
5323
5324 drv->ap_oper_freq = params->freq;
1581b38b
JM
5325
5326 return 0;
5327}
1581b38b
JM
5328
5329
5cc4d64b
JM
5330static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
5331{
5332 struct nl_msg *msg;
5333 int ret = -1;
5334
5335 msg = nlmsg_alloc();
5336 if (!msg)
5337 return -1;
5338
9fb04070 5339 nl80211_cmd(drv, msg, 0, NL80211_CMD_LEAVE_IBSS);
5cc4d64b
JM
5340 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5341 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5342 msg = NULL;
5343 if (ret) {
5344 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
5345 "(%s)", ret, strerror(-ret));
5346 goto nla_put_failure;
5347 }
5348
5349 ret = 0;
5350 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
5351
5352nla_put_failure:
5353 nlmsg_free(msg);
5354 return ret;
5355}
5356
5357
5358static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
5359 struct wpa_driver_associate_params *params)
5360{
5361 struct nl_msg *msg;
5362 int ret = -1;
5363 int count = 0;
5364
5365 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
5366
b1f625e0
EP
5367 if (wpa_driver_nl80211_set_mode(&drv->first_bss,
5368 NL80211_IFTYPE_ADHOC)) {
5cc4d64b
JM
5369 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
5370 "IBSS mode");
5371 return -1;
5372 }
5373
5374retry:
5375 msg = nlmsg_alloc();
5376 if (!msg)
5377 return -1;
5378
9fb04070 5379 nl80211_cmd(drv, msg, 0, NL80211_CMD_JOIN_IBSS);
5cc4d64b
JM
5380 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5381
5382 if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
5383 goto nla_put_failure;
5384
5385 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
5386 params->ssid, params->ssid_len);
5387 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
5388 params->ssid);
5389 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
5390 drv->ssid_len = params->ssid_len;
5391
5392 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
5393 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
5394
5395 ret = nl80211_set_conn_keys(params, msg);
5396 if (ret)
5397 goto nla_put_failure;
5398
a95795ad
JM
5399 if (params->wpa_ie) {
5400 wpa_hexdump(MSG_DEBUG,
5401 " * Extra IEs for Beacon/Probe Response frames",
5402 params->wpa_ie, params->wpa_ie_len);
5403 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
5404 params->wpa_ie);
5405 }
5406
5cc4d64b
JM
5407 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5408 msg = NULL;
5409 if (ret) {
5410 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
5411 ret, strerror(-ret));
5412 count++;
5413 if (ret == -EALREADY && count == 1) {
5414 wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
5415 "forced leave");
5416 nl80211_leave_ibss(drv);
5417 nlmsg_free(msg);
5418 goto retry;
5419 }
5420
5421 goto nla_put_failure;
5422 }
5423 ret = 0;
5424 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
5425
5426nla_put_failure:
5427 nlmsg_free(msg);
5428 return ret;
5429}
5430
5431
20f5a4c2
JM
5432static unsigned int nl80211_get_assoc_bssid(struct wpa_driver_nl80211_data *drv,
5433 u8 *bssid)
5434{
5435 struct nl_msg *msg;
5436 int ret;
5437 struct nl80211_bss_info_arg arg;
5438
5439 os_memset(&arg, 0, sizeof(arg));
5440 msg = nlmsg_alloc();
5441 if (!msg)
5442 goto nla_put_failure;
5443
9fb04070 5444 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
20f5a4c2
JM
5445 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5446
5447 arg.drv = drv;
5448 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
5449 msg = NULL;
5450 if (ret == 0) {
5451 if (is_zero_ether_addr(arg.assoc_bssid))
5452 return -ENOTCONN;
5453 os_memcpy(bssid, arg.assoc_bssid, ETH_ALEN);
5454 return 0;
5455 }
5456 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
5457 "(%s)", ret, strerror(-ret));
5458nla_put_failure:
5459 nlmsg_free(msg);
5460 return drv->assoc_freq;
5461}
5462
5463
5464static int nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
5465 const u8 *bssid)
5466{
5467 u8 addr[ETH_ALEN];
5468
5469 if (bssid == NULL) {
5470 int res = nl80211_get_assoc_bssid(drv, addr);
5471 if (res)
5472 return res;
5473 bssid = addr;
5474 }
5475
5476 return wpa_driver_nl80211_disconnect(drv, bssid,
5477 WLAN_REASON_PREV_AUTH_NOT_VALID);
5478}
5479
5480
cfaab580
ZY
5481static int wpa_driver_nl80211_connect(
5482 struct wpa_driver_nl80211_data *drv,
5483 struct wpa_driver_associate_params *params)
5484{
5485 struct nl_msg *msg;
5486 enum nl80211_auth_type type;
5487 int ret = 0;
3f360238 5488 int algs;
cfaab580
ZY
5489
5490 msg = nlmsg_alloc();
5491 if (!msg)
5492 return -1;
5493
5494 wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
9fb04070 5495 nl80211_cmd(drv, msg, 0, NL80211_CMD_CONNECT);
cfaab580
ZY
5496
5497 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5498 if (params->bssid) {
5499 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
5500 MAC2STR(params->bssid));
5501 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
5502 }
5503 if (params->freq) {
5504 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
5505 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
5506 }
5507 if (params->ssid) {
5508 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
5509 params->ssid, params->ssid_len);
5510 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
5511 params->ssid);
5512 if (params->ssid_len > sizeof(drv->ssid))
5513 goto nla_put_failure;
5514 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
5515 drv->ssid_len = params->ssid_len;
5516 }
5517 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
5518 if (params->wpa_ie)
5519 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
5520 params->wpa_ie);
5521
3f360238
JM
5522 algs = 0;
5523 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
5524 algs++;
5525 if (params->auth_alg & WPA_AUTH_ALG_SHARED)
5526 algs++;
5527 if (params->auth_alg & WPA_AUTH_ALG_LEAP)
5528 algs++;
5529 if (algs > 1) {
5530 wpa_printf(MSG_DEBUG, " * Leave out Auth Type for automatic "
5531 "selection");
5532 goto skip_auth_type;
5533 }
5534
abd9fafa 5535 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
cfaab580 5536 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
abd9fafa 5537 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
cfaab580 5538 type = NL80211_AUTHTYPE_SHARED_KEY;
abd9fafa 5539 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
cfaab580 5540 type = NL80211_AUTHTYPE_NETWORK_EAP;
abd9fafa 5541 else if (params->auth_alg & WPA_AUTH_ALG_FT)
cfaab580
ZY
5542 type = NL80211_AUTHTYPE_FT;
5543 else
5544 goto nla_put_failure;
5545
5546 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
5547 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
5548
3f360238 5549skip_auth_type:
64fa840a
JM
5550 if (params->wpa_proto) {
5551 enum nl80211_wpa_versions ver = 0;
cfaab580 5552
64fa840a
JM
5553 if (params->wpa_proto & WPA_PROTO_WPA)
5554 ver |= NL80211_WPA_VERSION_1;
5555 if (params->wpa_proto & WPA_PROTO_RSN)
5556 ver |= NL80211_WPA_VERSION_2;
cfaab580 5557
64fa840a 5558 wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
cfaab580
ZY
5559 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
5560 }
5561
5562 if (params->pairwise_suite != CIPHER_NONE) {
c1bb3e0a 5563 int cipher;
cfaab580
ZY
5564
5565 switch (params->pairwise_suite) {
5566 case CIPHER_WEP40:
5567 cipher = WLAN_CIPHER_SUITE_WEP40;
5568 break;
5569 case CIPHER_WEP104:
5570 cipher = WLAN_CIPHER_SUITE_WEP104;
5571 break;
5572 case CIPHER_CCMP:
5573 cipher = WLAN_CIPHER_SUITE_CCMP;
5574 break;
5575 case CIPHER_TKIP:
5576 default:
5577 cipher = WLAN_CIPHER_SUITE_TKIP;
5578 break;
5579 }
5580 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
5581 }
5582
5583 if (params->group_suite != CIPHER_NONE) {
c1bb3e0a 5584 int cipher;
cfaab580
ZY
5585
5586 switch (params->group_suite) {
5587 case CIPHER_WEP40:
5588 cipher = WLAN_CIPHER_SUITE_WEP40;
5589 break;
5590 case CIPHER_WEP104:
5591 cipher = WLAN_CIPHER_SUITE_WEP104;
5592 break;
5593 case CIPHER_CCMP:
5594 cipher = WLAN_CIPHER_SUITE_CCMP;
5595 break;
5596 case CIPHER_TKIP:
5597 default:
5598 cipher = WLAN_CIPHER_SUITE_TKIP;
5599 break;
5600 }
5601 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
5602 }
5603
5604 if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
5605 params->key_mgmt_suite == KEY_MGMT_PSK) {
5606 int mgmt = WLAN_AKM_SUITE_PSK;
5607
5608 switch (params->key_mgmt_suite) {
5609 case KEY_MGMT_802_1X:
5610 mgmt = WLAN_AKM_SUITE_8021X;
5611 break;
5612 case KEY_MGMT_PSK:
5613 default:
5614 mgmt = WLAN_AKM_SUITE_PSK;
5615 break;
5616 }
5617 NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
5618 }
5619
5620 ret = nl80211_set_conn_keys(params, msg);
5621 if (ret)
5622 goto nla_put_failure;
5623
5624 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5625 msg = NULL;
5626 if (ret) {
5627 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
5628 "(%s)", ret, strerror(-ret));
20f5a4c2
JM
5629 /*
5630 * cfg80211 does not currently accept new connection if we are
5631 * already connected. As a workaround, force disconnection and
5632 * try again once the driver indicates it completed
5633 * disconnection.
5634 */
5635 if (ret == -EALREADY)
5636 nl80211_disconnect(drv, params->bssid);
cfaab580
ZY
5637 goto nla_put_failure;
5638 }
5639 ret = 0;
5640 wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
5641
5642nla_put_failure:
5643 nlmsg_free(msg);
5644 return ret;
5645
5646}
5647
5648
c2a04078
JM
5649static int wpa_driver_nl80211_associate(
5650 void *priv, struct wpa_driver_associate_params *params)
5651{
a2e40bb6
FF
5652 struct i802_bss *bss = priv;
5653 struct wpa_driver_nl80211_data *drv = bss->drv;
c2a04078
JM
5654 int ret = -1;
5655 struct nl_msg *msg;
5656
5cc4d64b 5657 if (params->mode == IEEE80211_MODE_AP)
1581b38b 5658 return wpa_driver_nl80211_ap(drv, params);
1581b38b 5659
5cc4d64b
JM
5660 if (params->mode == IEEE80211_MODE_IBSS)
5661 return wpa_driver_nl80211_ibss(drv, params);
5662
4a867032 5663 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
b1f625e0
EP
5664 enum nl80211_iftype nlmode = params->p2p ?
5665 NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
5666
5667 if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
4a867032 5668 return -1;
cfaab580 5669 return wpa_driver_nl80211_connect(drv, params);
4a867032 5670 }
cfaab580 5671
c2a04078
JM
5672 drv->associated = 0;
5673
5674 msg = nlmsg_alloc();
5675 if (!msg)
5676 return -1;
5677
5678 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
5679 drv->ifindex);
9fb04070 5680 nl80211_cmd(drv, msg, 0, NL80211_CMD_ASSOCIATE);
c2a04078
JM
5681
5682 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5683 if (params->bssid) {
5684 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
5685 MAC2STR(params->bssid));
5686 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
5687 }
5688 if (params->freq) {
5689 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
5690 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
4832ecd7
JM
5691 drv->assoc_freq = params->freq;
5692 } else
5693 drv->assoc_freq = 0;
c2a04078
JM
5694 if (params->ssid) {
5695 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
5696 params->ssid, params->ssid_len);
5697 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
5698 params->ssid);
fd05d64e
JM
5699 if (params->ssid_len > sizeof(drv->ssid))
5700 goto nla_put_failure;
5701 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
5702 drv->ssid_len = params->ssid_len;
c2a04078
JM
5703 }
5704 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
5705 if (params->wpa_ie)
5706 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
5707 params->wpa_ie);
5708
aca01605
JM
5709 if (params->pairwise_suite != CIPHER_NONE) {
5710 int cipher;
5711
5712 switch (params->pairwise_suite) {
5713 case CIPHER_WEP40:
5714 cipher = WLAN_CIPHER_SUITE_WEP40;
5715 break;
5716 case CIPHER_WEP104:
5717 cipher = WLAN_CIPHER_SUITE_WEP104;
5718 break;
5719 case CIPHER_CCMP:
5720 cipher = WLAN_CIPHER_SUITE_CCMP;
5721 break;
5722 case CIPHER_TKIP:
5723 default:
5724 cipher = WLAN_CIPHER_SUITE_TKIP;
5725 break;
5726 }
79c3124c 5727 wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
aca01605
JM
5728 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
5729 }
5730
5731 if (params->group_suite != CIPHER_NONE) {
5732 int cipher;
5733
5734 switch (params->group_suite) {
5735 case CIPHER_WEP40:
5736 cipher = WLAN_CIPHER_SUITE_WEP40;
5737 break;
5738 case CIPHER_WEP104:
5739 cipher = WLAN_CIPHER_SUITE_WEP104;
5740 break;
5741 case CIPHER_CCMP:
5742 cipher = WLAN_CIPHER_SUITE_CCMP;
5743 break;
5744 case CIPHER_TKIP:
5745 default:
5746 cipher = WLAN_CIPHER_SUITE_TKIP;
5747 break;
5748 }
79c3124c 5749 wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
aca01605
JM
5750 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
5751 }
5752
e572fa33
JM
5753#ifdef CONFIG_IEEE80211W
5754 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
5755 NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
5756#endif /* CONFIG_IEEE80211W */
5757
01652550
JM
5758 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
5759
62fa124c
JM
5760 if (params->prev_bssid) {
5761 wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
5762 MAC2STR(params->prev_bssid));
5763 NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
5764 params->prev_bssid);
5765 }
5766
046b26a2
JM
5767 if (params->p2p)
5768 wpa_printf(MSG_DEBUG, " * P2P group");
5769
c2a04078
JM
5770 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5771 msg = NULL;
5772 if (ret) {
3b7ea880
BG
5773 wpa_dbg(drv->ctx, MSG_DEBUG,
5774 "nl80211: MLME command failed (assoc): ret=%d (%s)",
5775 ret, strerror(-ret));
8856462d 5776 nl80211_dump_scan(drv);
c2a04078
JM
5777 goto nla_put_failure;
5778 }
5779 ret = 0;
5780 wpa_printf(MSG_DEBUG, "nl80211: Association request send "
5781 "successfully");
5782
5783nla_put_failure:
5784 nlmsg_free(msg);
5785 return ret;
5786}
3f5285e8
JM
5787
5788
ad1e68e6 5789static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
a1922f93 5790 int ifindex, enum nl80211_iftype mode)
3f5285e8 5791{
3f5285e8 5792 struct nl_msg *msg;
ad1e68e6
JM
5793 int ret = -ENOBUFS;
5794
a1922f93
JM
5795 wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
5796 ifindex, mode, nl80211_iftype_str(mode));
5797
ad1e68e6
JM
5798 msg = nlmsg_alloc();
5799 if (!msg)
5800 return -ENOMEM;
5801
9fb04070 5802 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_INTERFACE);
ad1e68e6
JM
5803 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5804 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
5805
5806 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5807 if (!ret)
5808 return 0;
5809nla_put_failure:
5810 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
5811 " %d (%s)", ifindex, mode, ret, strerror(-ret));
5812 return ret;
5813}
5814
5815
b1f625e0
EP
5816static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
5817 enum nl80211_iftype nlmode)
ad1e68e6 5818{
a2e40bb6 5819 struct wpa_driver_nl80211_data *drv = bss->drv;
ad1e68e6 5820 int ret = -1;
26af9dca 5821 int i;
86957e62 5822 int was_ap = is_ap_interface(drv->nlmode);
1581b38b 5823
ad1e68e6
JM
5824 if (nl80211_set_mode(drv, drv->ifindex, nlmode) == 0) {
5825 drv->nlmode = nlmode;
460456f8
JM
5826 ret = 0;
5827 goto done;
ad1e68e6 5828 }
3f5285e8 5829
460456f8 5830 if (nlmode == drv->nlmode) {
c6e8e8e4
JM
5831 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
5832 "requested mode - ignore error");
460456f8
JM
5833 ret = 0;
5834 goto done; /* Already in the requested mode */
5835 }
3f5285e8 5836
3f5285e8
JM
5837 /* mac80211 doesn't allow mode changes while the device is up, so
5838 * take the device down, try to set the mode again, and bring the
5839 * device back up.
5840 */
26af9dca
JM
5841 wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
5842 "interface down");
5843 for (i = 0; i < 10; i++) {
6e8183d7 5844 int res;
c81eff1a
BG
5845 res = linux_set_iface_flags(drv->global->ioctl_sock,
5846 bss->ifname, 0);
6e8183d7
JM
5847 if (res == -EACCES || res == -ENODEV)
5848 break;
5849 if (res == 0) {
26af9dca
JM
5850 /* Try to set the mode again while the interface is
5851 * down */
5852 ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
6e8183d7
JM
5853 if (ret == -EACCES)
5854 break;
c81eff1a 5855 res = linux_set_iface_flags(drv->global->ioctl_sock,
6e8183d7
JM
5856 bss->ifname, 1);
5857 if (res && !ret)
26af9dca 5858 ret = -1;
6e8183d7 5859 else if (ret != -EBUSY)
26af9dca
JM
5860 break;
5861 } else
5862 wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
5863 "interface down");
5864 os_sleep(0, 100000);
3f5285e8
JM
5865 }
5866
c6e8e8e4
JM
5867 if (!ret) {
5868 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
5869 "interface is down");
ad1e68e6 5870 drv->nlmode = nlmode;
7d9c3698 5871 drv->ignore_if_down_event = 1;
c6e8e8e4 5872 }
ad1e68e6 5873
460456f8 5874done:
b1f625e0 5875 if (!ret && is_ap_interface(nlmode)) {
460456f8 5876 /* Setup additional AP mode functionality if needed */
61cbe2ff 5877 if (!drv->device_ap_sme && drv->monitor_ifidx < 0 &&
866af8b6 5878 nl80211_create_monitor_interface(drv) &&
61cbe2ff 5879 !drv->device_ap_sme)
460456f8 5880 return -1;
b1f625e0 5881 } else if (!ret && !is_ap_interface(nlmode)) {
460456f8 5882 /* Remove additional AP mode functionality */
61cbe2ff 5883 if (was_ap && drv->device_ap_sme)
86957e62 5884 wpa_driver_nl80211_probe_req_report(bss, 0);
460456f8 5885 nl80211_remove_monitor_interface(drv);
a2e40bb6 5886 bss->beacon_set = 0;
460456f8 5887 }
460456f8 5888
b3af99d2 5889 if (!ret && is_p2p_interface(drv->nlmode)) {
08359050 5890 nl80211_disable_11b_rates(drv, drv->ifindex, 1);
b3af99d2
JM
5891 drv->disabled_11b_rates = 1;
5892 } else if (!ret && drv->disabled_11b_rates) {
5893 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
5894 drv->disabled_11b_rates = 0;
5895 }
08359050 5896
c6e8e8e4
JM
5897 if (ret)
5898 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
5899 "from %d failed", nlmode, drv->nlmode);
5900
3f5285e8
JM
5901 return ret;
5902}
5903
5904
3f5285e8
JM
5905static int wpa_driver_nl80211_get_capa(void *priv,
5906 struct wpa_driver_capa *capa)
5907{
a2e40bb6
FF
5908 struct i802_bss *bss = priv;
5909 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8
JM
5910 if (!drv->has_capability)
5911 return -1;
5912 os_memcpy(capa, &drv->capa, sizeof(*capa));
5913 return 0;
5914}
5915
5916
5917static int wpa_driver_nl80211_set_operstate(void *priv, int state)
5918{
a2e40bb6
FF
5919 struct i802_bss *bss = priv;
5920 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8
JM
5921
5922 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
5923 __func__, drv->operstate, state, state ? "UP" : "DORMANT");
5924 drv->operstate = state;
36d84860 5925 return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
e2d02c29 5926 state ? IF_OPER_UP : IF_OPER_DORMANT);
3f5285e8
JM
5927}
5928
01652550
JM
5929
5930static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
5931{
a2e40bb6
FF
5932 struct i802_bss *bss = priv;
5933 struct wpa_driver_nl80211_data *drv = bss->drv;
01652550
JM
5934 struct nl_msg *msg;
5935 struct nl80211_sta_flag_update upd;
5936
5937 msg = nlmsg_alloc();
5938 if (!msg)
5939 return -ENOMEM;
5940
9fb04070 5941 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
01652550
JM
5942
5943 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 5944 if_nametoindex(bss->ifname));
01652550
JM
5945 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
5946
5947 os_memset(&upd, 0, sizeof(upd));
5948 upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
5949 if (authorized)
5950 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
5951 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
5952
5953 return send_and_recv_msgs(drv, msg, NULL, NULL);
5954 nla_put_failure:
5955 return -ENOBUFS;
5956}
5957
3f5285e8 5958
f07ead6a
JM
5959/* Set kernel driver on given frequency (MHz) */
5960static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
c5121837 5961{
f07ead6a
JM
5962 struct i802_bss *bss = priv;
5963 struct wpa_driver_nl80211_data *drv = bss->drv;
5964 return wpa_driver_nl80211_set_freq(drv, freq->freq, freq->ht_enabled,
5965 freq->sec_channel_offset);
c5121837
JM
5966}
5967
f7b3920c
JM
5968
5969#if defined(HOSTAPD) || defined(CONFIG_AP)
c5121837 5970
c5121837
JM
5971static inline int min_int(int a, int b)
5972{
5973 if (a < b)
5974 return a;
5975 return b;
5976}
5977
5978
5979static int get_key_handler(struct nl_msg *msg, void *arg)
5980{
5981 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5982 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5983
5984 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5985 genlmsg_attrlen(gnlh, 0), NULL);
5986
5987 /*
5988 * TODO: validate the key index and mac address!
5989 * Otherwise, there's a race condition as soon as
5990 * the kernel starts sending key notifications.
5991 */
5992
5993 if (tb[NL80211_ATTR_KEY_SEQ])
5994 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
5995 min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
5996 return NL_SKIP;
5997}
5998
5999
6000static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
6001 int idx, u8 *seq)
6002{
a2e40bb6
FF
6003 struct i802_bss *bss = priv;
6004 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6005 struct nl_msg *msg;
6006
6007 msg = nlmsg_alloc();
6008 if (!msg)
6009 return -ENOMEM;
6010
9fb04070 6011 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_KEY);
c5121837
JM
6012
6013 if (addr)
6014 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
6015 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
6016 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
6017
6018 memset(seq, 0, 6);
6019
6020 return send_and_recv_msgs(drv, msg, get_key_handler, seq);
6021 nla_put_failure:
6022 return -ENOBUFS;
6023}
6024
6025
6026static int i802_set_rate_sets(void *priv, int *supp_rates, int *basic_rates,
6027 int mode)
6028{
a2e40bb6
FF
6029 struct i802_bss *bss = priv;
6030 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6031 struct nl_msg *msg;
6032 u8 rates[NL80211_MAX_SUPP_RATES];
6033 u8 rates_len = 0;
6034 int i;
6035
6036 msg = nlmsg_alloc();
6037 if (!msg)
6038 return -ENOMEM;
6039
9fb04070 6040 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_BSS);
c5121837
JM
6041
6042 for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0; i++)
6043 rates[rates_len++] = basic_rates[i] / 5;
6044
6045 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
6046
a2e40bb6 6047 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
6048
6049 return send_and_recv_msgs(drv, msg, NULL, NULL);
6050 nla_put_failure:
6051 return -ENOBUFS;
6052}
6053
e3802622 6054
c5121837
JM
6055static int i802_set_rts(void *priv, int rts)
6056{
a2e40bb6
FF
6057 struct i802_bss *bss = priv;
6058 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
6059 struct nl_msg *msg;
6060 int ret = -ENOBUFS;
6061 u32 val;
c5121837 6062
ad649451
JM
6063 msg = nlmsg_alloc();
6064 if (!msg)
6065 return -ENOMEM;
c5121837 6066
ad649451
JM
6067 if (rts >= 2347)
6068 val = (u32) -1;
6069 else
6070 val = rts;
c5121837 6071
9fb04070 6072 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
ad649451
JM
6073 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
6074 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
6075
6076 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6077 if (!ret)
6078 return 0;
6079nla_put_failure:
6080 wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
6081 "%d (%s)", rts, ret, strerror(-ret));
6082 return ret;
c5121837
JM
6083}
6084
6085
6086static int i802_set_frag(void *priv, int frag)
6087{
a2e40bb6
FF
6088 struct i802_bss *bss = priv;
6089 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
6090 struct nl_msg *msg;
6091 int ret = -ENOBUFS;
6092 u32 val;
c5121837 6093
ad649451
JM
6094 msg = nlmsg_alloc();
6095 if (!msg)
6096 return -ENOMEM;
c5121837 6097
ad649451
JM
6098 if (frag >= 2346)
6099 val = (u32) -1;
6100 else
6101 val = frag;
c5121837 6102
9fb04070 6103 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
ad649451
JM
6104 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
6105 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
6106
6107 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6108 if (!ret)
6109 return 0;
6110nla_put_failure:
6111 wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
6112 "%d: %d (%s)", frag, ret, strerror(-ret));
6113 return ret;
c5121837
JM
6114}
6115
6116
c5121837
JM
6117static int i802_flush(void *priv)
6118{
a2e40bb6
FF
6119 struct i802_bss *bss = priv;
6120 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6121 struct nl_msg *msg;
6122
6123 msg = nlmsg_alloc();
6124 if (!msg)
6125 return -1;
6126
9fb04070 6127 nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
c5121837
JM
6128
6129 /*
6130 * XXX: FIX! this needs to flush all VLANs too
6131 */
6132 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 6133 if_nametoindex(bss->ifname));
c5121837
JM
6134
6135 return send_and_recv_msgs(drv, msg, NULL, NULL);
6136 nla_put_failure:
6137 return -ENOBUFS;
6138}
6139
6140
6141static int get_sta_handler(struct nl_msg *msg, void *arg)
6142{
6143 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6144 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6145 struct hostap_sta_driver_data *data = arg;
6146 struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
6147 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
6148 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
6149 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
6150 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
6151 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
6152 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
6153 };
6154
6155 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6156 genlmsg_attrlen(gnlh, 0), NULL);
6157
6158 /*
6159 * TODO: validate the interface and mac address!
6160 * Otherwise, there's a race condition as soon as
6161 * the kernel starts sending station notifications.
6162 */
6163
6164 if (!tb[NL80211_ATTR_STA_INFO]) {
6165 wpa_printf(MSG_DEBUG, "sta stats missing!");
6166 return NL_SKIP;
6167 }
6168 if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
6169 tb[NL80211_ATTR_STA_INFO],
6170 stats_policy)) {
6171 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
6172 return NL_SKIP;
6173 }
6174
6175 if (stats[NL80211_STA_INFO_INACTIVE_TIME])
6176 data->inactive_msec =
6177 nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
6178 if (stats[NL80211_STA_INFO_RX_BYTES])
6179 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
6180 if (stats[NL80211_STA_INFO_TX_BYTES])
6181 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
6182 if (stats[NL80211_STA_INFO_RX_PACKETS])
6183 data->rx_packets =
6184 nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
6185 if (stats[NL80211_STA_INFO_TX_PACKETS])
6186 data->tx_packets =
6187 nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
6188
6189 return NL_SKIP;
6190}
6191
6192static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
6193 const u8 *addr)
6194{
a2e40bb6
FF
6195 struct i802_bss *bss = priv;
6196 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6197 struct nl_msg *msg;
6198
6199 os_memset(data, 0, sizeof(*data));
6200 msg = nlmsg_alloc();
6201 if (!msg)
6202 return -ENOMEM;
6203
9fb04070 6204 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
c5121837
JM
6205
6206 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
a2e40bb6 6207 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
6208
6209 return send_and_recv_msgs(drv, msg, get_sta_handler, data);
6210 nla_put_failure:
6211 return -ENOBUFS;
6212}
6213
6214
c5121837
JM
6215static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
6216 int cw_min, int cw_max, int burst_time)
6217{
a2e40bb6
FF
6218 struct i802_bss *bss = priv;
6219 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
6220 struct nl_msg *msg;
6221 struct nlattr *txq, *params;
6222
6223 msg = nlmsg_alloc();
6224 if (!msg)
6225 return -1;
6226
9fb04070 6227 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
c5121837 6228
a2e40bb6 6229 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
6230
6231 txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
6232 if (!txq)
6233 goto nla_put_failure;
6234
6235 /* We are only sending parameters for a single TXQ at a time */
6236 params = nla_nest_start(msg, 1);
6237 if (!params)
6238 goto nla_put_failure;
6239
7e3c1781
JM
6240 switch (queue) {
6241 case 0:
6242 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO);
6243 break;
6244 case 1:
6245 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI);
6246 break;
6247 case 2:
6248 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE);
6249 break;
6250 case 3:
6251 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK);
6252 break;
6253 }
c5121837
JM
6254 /* Burst time is configured in units of 0.1 msec and TXOP parameter in
6255 * 32 usec, so need to convert the value here. */
6256 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
6257 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
6258 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
6259 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
6260
6261 nla_nest_end(msg, params);
6262
6263 nla_nest_end(msg, txq);
6264
6265 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
6266 return 0;
6267 nla_put_failure:
6268 return -1;
6269}
6270
6271
c5121837
JM
6272static int i802_set_sta_vlan(void *priv, const u8 *addr,
6273 const char *ifname, int vlan_id)
6274{
a2e40bb6
FF
6275 struct i802_bss *bss = priv;
6276 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 6277 struct nl_msg *msg;
cd1d72c1 6278 int ret = -ENOBUFS;
c5121837
JM
6279
6280 msg = nlmsg_alloc();
6281 if (!msg)
6282 return -ENOMEM;
6283
9fb04070 6284 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
c5121837
JM
6285
6286 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 6287 if_nametoindex(bss->ifname));
c5121837 6288 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1c766b09 6289 NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
c5121837
JM
6290 if_nametoindex(ifname));
6291
cd1d72c1
JM
6292 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6293 if (ret < 0) {
6294 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
6295 MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
6296 MAC2STR(addr), ifname, vlan_id, ret,
6297 strerror(-ret));
6298 }
c5121837 6299 nla_put_failure:
cd1d72c1 6300 return ret;
c5121837
JM
6301}
6302
fbbfcbac 6303
c5121837
JM
6304static int i802_get_inact_sec(void *priv, const u8 *addr)
6305{
6306 struct hostap_sta_driver_data data;
6307 int ret;
6308
6309 data.inactive_msec = (unsigned long) -1;
6310 ret = i802_read_sta_data(priv, &data, addr);
6311 if (ret || data.inactive_msec == (unsigned long) -1)
6312 return -1;
6313 return data.inactive_msec / 1000;
6314}
6315
6316
6317static int i802_sta_clear_stats(void *priv, const u8 *addr)
6318{
6319#if 0
6320 /* TODO */
6321#endif
6322 return 0;
6323}
6324
6325
731723a5
JM
6326static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
6327 int reason)
c5121837 6328{
a2e40bb6 6329 struct i802_bss *bss = priv;
c5121837
JM
6330 struct ieee80211_mgmt mgmt;
6331
6332 memset(&mgmt, 0, sizeof(mgmt));
6333 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
6334 WLAN_FC_STYPE_DEAUTH);
6335 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
6336 memcpy(mgmt.sa, own_addr, ETH_ALEN);
6337 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 6338 mgmt.u.deauth.reason_code = host_to_le16(reason);
a2e40bb6 6339 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 6340 IEEE80211_HDRLEN +
8cfa3527 6341 sizeof(mgmt.u.deauth), 0);
c5121837
JM
6342}
6343
6344
731723a5
JM
6345static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
6346 int reason)
c5121837 6347{
a2e40bb6 6348 struct i802_bss *bss = priv;
c5121837
JM
6349 struct ieee80211_mgmt mgmt;
6350
6351 memset(&mgmt, 0, sizeof(mgmt));
6352 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
6353 WLAN_FC_STYPE_DISASSOC);
6354 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
6355 memcpy(mgmt.sa, own_addr, ETH_ALEN);
6356 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 6357 mgmt.u.disassoc.reason_code = host_to_le16(reason);
a2e40bb6 6358 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61 6359 IEEE80211_HDRLEN +
8cfa3527 6360 sizeof(mgmt.u.disassoc), 0);
c5121837
JM
6361}
6362
ee7ab173
JB
6363#endif /* HOSTAPD || CONFIG_AP */
6364
6365#ifdef HOSTAPD
c5121837 6366
f07ead6a
JM
6367static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
6368{
6369 int i;
6370 int *old;
6371
6372 wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
6373 ifidx);
6374 for (i = 0; i < drv->num_if_indices; i++) {
6375 if (drv->if_indices[i] == 0) {
6376 drv->if_indices[i] = ifidx;
6377 return;
6378 }
6379 }
6380
6381 if (drv->if_indices != drv->default_if_indices)
6382 old = drv->if_indices;
6383 else
6384 old = NULL;
6385
6386 drv->if_indices = os_realloc(old,
6387 sizeof(int) * (drv->num_if_indices + 1));
6388 if (!drv->if_indices) {
6389 if (!old)
6390 drv->if_indices = drv->default_if_indices;
6391 else
6392 drv->if_indices = old;
6393 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
6394 "interfaces");
6395 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
6396 return;
6397 } else if (!old)
6398 os_memcpy(drv->if_indices, drv->default_if_indices,
6399 sizeof(drv->default_if_indices));
6400 drv->if_indices[drv->num_if_indices] = ifidx;
6401 drv->num_if_indices++;
6402}
6403
6404
6405static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
6406{
6407 int i;
6408
6409 for (i = 0; i < drv->num_if_indices; i++) {
6410 if (drv->if_indices[i] == ifidx) {
6411 drv->if_indices[i] = 0;
6412 break;
6413 }
6414 }
6415}
6416
6417
6418static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
6419{
6420 int i;
6421
6422 for (i = 0; i < drv->num_if_indices; i++)
6423 if (drv->if_indices[i] == ifidx)
6424 return 1;
6425
6426 return 0;
6427}
6428
6429
6430static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
6431 const char *bridge_ifname)
6432{
6433 struct i802_bss *bss = priv;
6434 struct wpa_driver_nl80211_data *drv = bss->drv;
6435 char name[IFNAMSIZ + 1];
6436
6437 os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
6438 wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
6439 " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
6440 if (val) {
6441 if (!if_nametoindex(name)) {
6442 if (nl80211_create_iface(drv, name,
6443 NL80211_IFTYPE_AP_VLAN,
6444 NULL, 1) < 0)
6445 return -1;
6446 if (bridge_ifname &&
c81eff1a
BG
6447 linux_br_add_if(drv->global->ioctl_sock,
6448 bridge_ifname, name) < 0)
f07ead6a
JM
6449 return -1;
6450 }
c81eff1a 6451 linux_set_iface_flags(drv->global->ioctl_sock, name, 1);
f07ead6a
JM
6452 return i802_set_sta_vlan(priv, addr, name, 0);
6453 } else {
6454 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
6455 return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN,
6456 name);
6457 }
6458}
6459
6460
6461static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
6462{
6463 struct wpa_driver_nl80211_data *drv = eloop_ctx;
6464 struct sockaddr_ll lladdr;
6465 unsigned char buf[3000];
6466 int len;
6467 socklen_t fromlen = sizeof(lladdr);
6468
6469 len = recvfrom(sock, buf, sizeof(buf), 0,
6470 (struct sockaddr *)&lladdr, &fromlen);
6471 if (len < 0) {
6472 perror("recv");
6473 return;
6474 }
6475
6476 if (have_ifidx(drv, lladdr.sll_ifindex))
6477 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
6478}
6479
6480
94627f6c 6481static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
e17a2477 6482 struct i802_bss *bss,
94627f6c
JM
6483 const char *brname, const char *ifname)
6484{
6485 int ifindex;
6486 char in_br[IFNAMSIZ];
6487
e17a2477 6488 os_strlcpy(bss->brname, brname, IFNAMSIZ);
94627f6c
JM
6489 ifindex = if_nametoindex(brname);
6490 if (ifindex == 0) {
6491 /*
6492 * Bridge was configured, but the bridge device does
6493 * not exist. Try to add it now.
6494 */
c81eff1a 6495 if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
94627f6c
JM
6496 wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
6497 "bridge interface %s: %s",
6498 brname, strerror(errno));
6499 return -1;
6500 }
e17a2477 6501 bss->added_bridge = 1;
94627f6c
JM
6502 add_ifidx(drv, if_nametoindex(brname));
6503 }
6504
6505 if (linux_br_get(in_br, ifname) == 0) {
6506 if (os_strcmp(in_br, brname) == 0)
6507 return 0; /* already in the bridge */
6508
6509 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
6510 "bridge %s", ifname, in_br);
c81eff1a
BG
6511 if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
6512 0) {
94627f6c
JM
6513 wpa_printf(MSG_ERROR, "nl80211: Failed to "
6514 "remove interface %s from bridge "
6515 "%s: %s",
6516 ifname, brname, strerror(errno));
6517 return -1;
6518 }
6519 }
6520
6521 wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
6522 ifname, brname);
c81eff1a 6523 if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
94627f6c
JM
6524 wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
6525 "into bridge %s: %s",
6526 ifname, brname, strerror(errno));
6527 return -1;
6528 }
e17a2477 6529 bss->added_if_into_bridge = 1;
94627f6c
JM
6530
6531 return 0;
6532}
6533
6534
92f475b4
JM
6535static void *i802_init(struct hostapd_data *hapd,
6536 struct wpa_init_params *params)
c5121837
JM
6537{
6538 struct wpa_driver_nl80211_data *drv;
a2e40bb6 6539 struct i802_bss *bss;
c5121837 6540 size_t i;
94627f6c
JM
6541 char brname[IFNAMSIZ];
6542 int ifindex, br_ifindex;
6543 int br_added = 0;
c5121837 6544
4b24282a
JM
6545 bss = wpa_driver_nl80211_init(hapd, params->ifname,
6546 params->global_priv);
a2e40bb6 6547 if (bss == NULL)
c5121837 6548 return NULL;
c5121837 6549
a2e40bb6 6550 drv = bss->drv;
0382097e 6551 drv->nlmode = NL80211_IFTYPE_AP;
7635bfb0
JB
6552 drv->eapol_sock = -1;
6553
94627f6c
JM
6554 if (linux_br_get(brname, params->ifname) == 0) {
6555 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
6556 params->ifname, brname);
6557 br_ifindex = if_nametoindex(brname);
6558 } else {
6559 brname[0] = '\0';
6560 br_ifindex = 0;
6561 }
6562
c5121837
JM
6563 drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
6564 drv->if_indices = drv->default_if_indices;
92f475b4 6565 for (i = 0; i < params->num_bridge; i++) {
94627f6c
JM
6566 if (params->bridge[i]) {
6567 ifindex = if_nametoindex(params->bridge[i]);
6568 if (ifindex)
6569 add_ifidx(drv, ifindex);
6570 if (ifindex == br_ifindex)
6571 br_added = 1;
6572 }
c5121837 6573 }
94627f6c
JM
6574 if (!br_added && br_ifindex &&
6575 (params->num_bridge == 0 || !params->bridge[0]))
6576 add_ifidx(drv, br_ifindex);
c5121837 6577
ad1e68e6
JM
6578 /* start listening for EAPOL on the default AP interface */
6579 add_ifidx(drv, drv->ifindex);
6580
c81eff1a 6581 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0))
6980c191 6582 goto failed;
ad1e68e6 6583
6980c191 6584 if (params->bssid) {
c81eff1a 6585 if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2ac9688e 6586 params->bssid))
460456f8
JM
6587 goto failed;
6588 }
ad1e68e6 6589
b1f625e0 6590 if (wpa_driver_nl80211_set_mode(bss, drv->nlmode)) {
ad1e68e6 6591 wpa_printf(MSG_ERROR, "nl80211: Failed to set interface %s "
a2e40bb6 6592 "into AP mode", bss->ifname);
bbaf0837 6593 goto failed;
ad1e68e6
JM
6594 }
6595
94627f6c 6596 if (params->num_bridge && params->bridge[0] &&
e17a2477 6597 i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
94627f6c
JM
6598 goto failed;
6599
c81eff1a 6600 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1))
bbaf0837 6601 goto failed;
ad1e68e6
JM
6602
6603 drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
6604 if (drv->eapol_sock < 0) {
6605 perror("socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE)");
bbaf0837 6606 goto failed;
ad1e68e6
JM
6607 }
6608
6609 if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
6610 {
6611 printf("Could not register read socket for eapol\n");
c5121837 6612 goto failed;
ad1e68e6
JM
6613 }
6614
c81eff1a
BG
6615 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
6616 params->own_addr))
bbaf0837 6617 goto failed;
c5121837 6618
a2e40bb6 6619 return bss;
c5121837
JM
6620
6621failed:
7635bfb0 6622 wpa_driver_nl80211_deinit(bss);
bbaf0837
JM
6623 return NULL;
6624}
c5121837 6625
c5121837 6626
bbaf0837
JM
6627static void i802_deinit(void *priv)
6628{
6629 wpa_driver_nl80211_deinit(priv);
c5121837
JM
6630}
6631
6632#endif /* HOSTAPD */
6633
6634
22a7c9d7
JM
6635static enum nl80211_iftype wpa_driver_nl80211_if_type(
6636 enum wpa_driver_if_type type)
6637{
6638 switch (type) {
6639 case WPA_IF_STATION:
9f51b113 6640 return NL80211_IFTYPE_STATION;
75bde05d
JM
6641 case WPA_IF_P2P_CLIENT:
6642 case WPA_IF_P2P_GROUP:
9f51b113 6643 return NL80211_IFTYPE_P2P_CLIENT;
22a7c9d7
JM
6644 case WPA_IF_AP_VLAN:
6645 return NL80211_IFTYPE_AP_VLAN;
6646 case WPA_IF_AP_BSS:
6647 return NL80211_IFTYPE_AP;
9f51b113
JB
6648 case WPA_IF_P2P_GO:
6649 return NL80211_IFTYPE_P2P_GO;
22a7c9d7
JM
6650 }
6651 return -1;
6652}
6653
6654
482856c8
JM
6655#ifdef CONFIG_P2P
6656
f2ed8023
JM
6657static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
6658{
6659 struct wpa_driver_nl80211_data *drv;
6660 dl_list_for_each(drv, &global->interfaces,
6661 struct wpa_driver_nl80211_data, list) {
6662 if (os_memcmp(addr, drv->addr, ETH_ALEN) == 0)
6663 return 1;
6664 }
6665 return 0;
6666}
6667
6668
6669static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data *drv,
6670 u8 *new_addr)
6671{
6672 unsigned int idx;
6673
6674 if (!drv->global)
6675 return -1;
6676
6677 os_memcpy(new_addr, drv->addr, ETH_ALEN);
6678 for (idx = 0; idx < 64; idx++) {
6679 new_addr[0] = drv->addr[0] | 0x02;
6680 new_addr[0] ^= idx << 2;
6681 if (!nl80211_addr_in_use(drv->global, new_addr))
6682 break;
6683 }
6684 if (idx == 64)
6685 return -1;
6686
6687 wpa_printf(MSG_DEBUG, "nl80211: Assigned new P2P Interface Address "
6688 MACSTR, MAC2STR(new_addr));
6689
6690 return 0;
6691}
6692
482856c8
JM
6693#endif /* CONFIG_P2P */
6694
f2ed8023 6695
7ab68865 6696static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
8043e725 6697 const char *ifname, const u8 *addr,
f3585c8a 6698 void *bss_ctx, void **drv_priv,
e17a2477
JM
6699 char *force_ifname, u8 *if_addr,
6700 const char *bridge)
22a7c9d7 6701{
a2e40bb6
FF
6702 struct i802_bss *bss = priv;
6703 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7
JM
6704 int ifidx;
6705#ifdef HOSTAPD
a2e40bb6 6706 struct i802_bss *new_bss = NULL;
22a7c9d7
JM
6707
6708 if (type == WPA_IF_AP_BSS) {
a2e40bb6
FF
6709 new_bss = os_zalloc(sizeof(*new_bss));
6710 if (new_bss == NULL)
22a7c9d7
JM
6711 return -1;
6712 }
6713#endif /* HOSTAPD */
6714
f3585c8a
JM
6715 if (addr)
6716 os_memcpy(if_addr, addr, ETH_ALEN);
22a7c9d7 6717 ifidx = nl80211_create_iface(drv, ifname,
fbbfcbac
FF
6718 wpa_driver_nl80211_if_type(type), addr,
6719 0);
22a7c9d7
JM
6720 if (ifidx < 0) {
6721#ifdef HOSTAPD
a2e40bb6 6722 os_free(new_bss);
22a7c9d7
JM
6723#endif /* HOSTAPD */
6724 return -1;
6725 }
6726
f3585c8a 6727 if (!addr &&
c81eff1a
BG
6728 linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
6729 if_addr) < 0) {
c55f774d 6730 nl80211_remove_iface(drv, ifidx);
f3585c8a 6731 return -1;
c55f774d
JM
6732 }
6733
6734#ifdef CONFIG_P2P
6735 if (!addr &&
6736 (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
6737 type == WPA_IF_P2P_GO)) {
6738 /* Enforce unique P2P Interface Address */
6739 u8 new_addr[ETH_ALEN], own_addr[ETH_ALEN];
6740
c81eff1a
BG
6741 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
6742 own_addr) < 0 ||
6743 linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
6744 new_addr) < 0) {
c55f774d
JM
6745 nl80211_remove_iface(drv, ifidx);
6746 return -1;
6747 }
6748 if (os_memcmp(own_addr, new_addr, ETH_ALEN) == 0) {
6749 wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
6750 "for P2P group interface");
f2ed8023 6751 if (nl80211_p2p_interface_addr(drv, new_addr) < 0) {
c55f774d
JM
6752 nl80211_remove_iface(drv, ifidx);
6753 return -1;
6754 }
c81eff1a 6755 if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
c55f774d
JM
6756 new_addr) < 0) {
6757 nl80211_remove_iface(drv, ifidx);
6758 return -1;
6759 }
c55f774d 6760 }
f67eeb5c 6761 os_memcpy(if_addr, new_addr, ETH_ALEN);
c55f774d
JM
6762 }
6763#endif /* CONFIG_P2P */
f3585c8a 6764
22a7c9d7 6765#ifdef HOSTAPD
e17a2477
JM
6766 if (bridge &&
6767 i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
6768 wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
6769 "interface %s to a bridge %s", ifname, bridge);
6770 nl80211_remove_iface(drv, ifidx);
6771 os_free(new_bss);
6772 return -1;
6773 }
6774
22a7c9d7 6775 if (type == WPA_IF_AP_BSS) {
c81eff1a
BG
6776 if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
6777 {
34f2f814 6778 nl80211_remove_iface(drv, ifidx);
07179987 6779 os_free(new_bss);
22a7c9d7
JM
6780 return -1;
6781 }
a2e40bb6
FF
6782 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
6783 new_bss->ifindex = ifidx;
6784 new_bss->drv = drv;
6785 new_bss->next = drv->first_bss.next;
6786 drv->first_bss.next = new_bss;
6787 if (drv_priv)
6788 *drv_priv = new_bss;
22a7c9d7
JM
6789 }
6790#endif /* HOSTAPD */
6791
ff6a158b
JM
6792 if (drv->global)
6793 drv->global->if_add_ifindex = ifidx;
6794
22a7c9d7
JM
6795 return 0;
6796}
6797
6798
6799static int wpa_driver_nl80211_if_remove(void *priv,
6800 enum wpa_driver_if_type type,
6801 const char *ifname)
6802{
a2e40bb6
FF
6803 struct i802_bss *bss = priv;
6804 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7
JM
6805 int ifindex = if_nametoindex(ifname);
6806
e748062b
JM
6807 wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d",
6808 __func__, type, ifname, ifindex);
6809 if (ifindex <= 0)
6810 return -1;
e17a2477
JM
6811
6812#ifdef HOSTAPD
6813 if (bss->added_if_into_bridge) {
c81eff1a
BG
6814 if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
6815 bss->ifname) < 0)
e17a2477
JM
6816 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
6817 "interface %s from bridge %s: %s",
6818 bss->ifname, bss->brname, strerror(errno));
6819 }
6820 if (bss->added_bridge) {
c81eff1a 6821 if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
e17a2477
JM
6822 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
6823 "bridge %s: %s",
6824 bss->brname, strerror(errno));
6825 }
6826#endif /* HOSTAPD */
6827
22a7c9d7
JM
6828 nl80211_remove_iface(drv, ifindex);
6829
6830#ifdef HOSTAPD
a2e40bb6
FF
6831 if (type != WPA_IF_AP_BSS)
6832 return 0;
6833
6834 if (bss != &drv->first_bss) {
8546ea19 6835 struct i802_bss *tbss;
a2e40bb6 6836
8546ea19
JM
6837 for (tbss = &drv->first_bss; tbss; tbss = tbss->next) {
6838 if (tbss->next == bss) {
6839 tbss->next = bss->next;
6840 os_free(bss);
6841 bss = NULL;
6842 break;
6843 }
22a7c9d7 6844 }
8546ea19
JM
6845 if (bss)
6846 wpa_printf(MSG_INFO, "nl80211: %s - could not find "
6847 "BSS %p in the list", __func__, bss);
22a7c9d7
JM
6848 }
6849#endif /* HOSTAPD */
6850
6851 return 0;
6852}
6853
6854
55777702
JM
6855static int cookie_handler(struct nl_msg *msg, void *arg)
6856{
6857 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6858 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6859 u64 *cookie = arg;
6860 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6861 genlmsg_attrlen(gnlh, 0), NULL);
6862 if (tb[NL80211_ATTR_COOKIE])
6863 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
6864 return NL_SKIP;
6865}
6866
6867
88df0ef7 6868static int nl80211_send_frame_cmd(struct i802_bss *bss,
5dfca53f
JB
6869 unsigned int freq, unsigned int wait,
6870 const u8 *buf, size_t buf_len,
88df0ef7
JB
6871 u64 *cookie_out, int no_cck, int no_ack,
6872 int offchanok)
9884f9cc 6873{
88df0ef7 6874 struct wpa_driver_nl80211_data *drv = bss->drv;
9884f9cc
JB
6875 struct nl_msg *msg;
6876 u64 cookie;
6877 int ret = -1;
6878
6879 msg = nlmsg_alloc();
6880 if (!msg)
6881 return -1;
6882
9fb04070 6883 nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME);
9884f9cc 6884
88df0ef7 6885 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
9884f9cc 6886 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
9db931ed
JM
6887 if (wait)
6888 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
88df0ef7
JB
6889 if (offchanok)
6890 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
b106173a
JM
6891 if (no_cck)
6892 NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
ddc53271
JM
6893 if (no_ack)
6894 NLA_PUT_FLAG(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK);
970fa12e 6895
9884f9cc
JB
6896 NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
6897
6898 cookie = 0;
6899 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
6900 msg = NULL;
6901 if (ret) {
6902 wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
a05225c8
JM
6903 "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
6904 freq, wait);
9884f9cc
JB
6905 goto nla_put_failure;
6906 }
ddc53271
JM
6907 wpa_printf(MSG_DEBUG, "nl80211: Frame TX command accepted%s; "
6908 "cookie 0x%llx", no_ack ? " (no ACK)" : "",
6909 (long long unsigned int) cookie);
9884f9cc
JB
6910
6911 if (cookie_out)
ddc53271 6912 *cookie_out = no_ack ? (u64) -1 : cookie;
9884f9cc
JB
6913
6914nla_put_failure:
6915 nlmsg_free(msg);
6916 return ret;
6917}
6918
6919
58f6fbe0 6920static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
190b9062 6921 unsigned int wait_time,
58f6fbe0
JM
6922 const u8 *dst, const u8 *src,
6923 const u8 *bssid,
b106173a
JM
6924 const u8 *data, size_t data_len,
6925 int no_cck)
58f6fbe0 6926{
a2e40bb6
FF
6927 struct i802_bss *bss = priv;
6928 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0 6929 int ret = -1;
58f6fbe0
JM
6930 u8 *buf;
6931 struct ieee80211_hdr *hdr;
58f6fbe0 6932
5dfca53f 6933 wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
b106173a 6934 "wait=%d ms no_cck=%d)", drv->ifindex, wait_time, no_cck);
58f6fbe0
JM
6935
6936 buf = os_zalloc(24 + data_len);
6937 if (buf == NULL)
6938 return ret;
6939 os_memcpy(buf + 24, data, data_len);
6940 hdr = (struct ieee80211_hdr *) buf;
6941 hdr->frame_control =
6942 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
6943 os_memcpy(hdr->addr1, dst, ETH_ALEN);
6944 os_memcpy(hdr->addr2, src, ETH_ALEN);
6945 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
6946
b1f625e0 6947 if (is_ap_interface(drv->nlmode))
8cfa3527
HS
6948 ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len,
6949 0);
9884f9cc 6950 else
88df0ef7 6951 ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
5dfca53f 6952 24 + data_len,
b106173a 6953 &drv->send_action_cookie,
88df0ef7 6954 no_cck, 0, 1);
58f6fbe0 6955
f8bf1421 6956 os_free(buf);
58f6fbe0
JM
6957 return ret;
6958}
6959
6960
5dfca53f
JB
6961static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
6962{
6963 struct i802_bss *bss = priv;
6964 struct wpa_driver_nl80211_data *drv = bss->drv;
6965 struct nl_msg *msg;
6966 int ret;
6967
6968 msg = nlmsg_alloc();
6969 if (!msg)
6970 return;
6971
9fb04070 6972 nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME_WAIT_CANCEL);
5dfca53f
JB
6973
6974 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
6975 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie);
6976
6977 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6978 msg = NULL;
6979 if (ret)
6980 wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
6981 "(%s)", ret, strerror(-ret));
6982
6983 nla_put_failure:
6984 nlmsg_free(msg);
6985}
6986
6987
55777702
JM
6988static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
6989 unsigned int duration)
6990{
a2e40bb6
FF
6991 struct i802_bss *bss = priv;
6992 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
6993 struct nl_msg *msg;
6994 int ret;
6995 u64 cookie;
6996
6997 msg = nlmsg_alloc();
6998 if (!msg)
6999 return -1;
7000
9fb04070 7001 nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL);
55777702
JM
7002
7003 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7004 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
7005 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
7006
7007 cookie = 0;
7008 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
7009 if (ret == 0) {
7010 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
7011 "0x%llx for freq=%u MHz duration=%u",
7012 (long long unsigned int) cookie, freq, duration);
7013 drv->remain_on_chan_cookie = cookie;
531f0331 7014 drv->pending_remain_on_chan = 1;
55777702
JM
7015 return 0;
7016 }
7017 wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
15ed5535
JM
7018 "(freq=%d duration=%u): %d (%s)",
7019 freq, duration, ret, strerror(-ret));
55777702
JM
7020nla_put_failure:
7021 return -1;
7022}
7023
7024
7025static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
7026{
a2e40bb6
FF
7027 struct i802_bss *bss = priv;
7028 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
7029 struct nl_msg *msg;
7030 int ret;
7031
7032 if (!drv->pending_remain_on_chan) {
7033 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
7034 "to cancel");
7035 return -1;
7036 }
7037
7038 wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
7039 "0x%llx",
7040 (long long unsigned int) drv->remain_on_chan_cookie);
7041
7042 msg = nlmsg_alloc();
7043 if (!msg)
7044 return -1;
7045
9fb04070 7046 nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
55777702
JM
7047
7048 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7049 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
7050
7051 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7052 if (ret == 0)
7053 return 0;
7054 wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
7055 "%d (%s)", ret, strerror(-ret));
7056nla_put_failure:
7057 return -1;
7058}
7059
7060
504e905c
JM
7061static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
7062{
a2e40bb6
FF
7063 struct i802_bss *bss = priv;
7064 struct wpa_driver_nl80211_data *drv = bss->drv;
504e905c 7065
5582a5d1 7066 if (!report) {
221a59c9 7067 if (bss->nl_preq.handle) {
5582a5d1 7068 eloop_unregister_read_sock(
221a59c9
JB
7069 nl_socket_get_fd(bss->nl_preq.handle));
7070 nl_destroy_handles(&bss->nl_preq);
5582a5d1
JB
7071 }
7072 return 0;
7073 }
7074
221a59c9 7075 if (bss->nl_preq.handle) {
5582a5d1
JB
7076 wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
7077 "already on!");
7078 return 0;
7079 }
7080
221a59c9 7081 if (nl_create_handles(&bss->nl_preq, drv->global->nl_cb, "preq"))
5582a5d1 7082 return -1;
5582a5d1 7083
221a59c9 7084 if (nl80211_register_frame(drv, bss->nl_preq.handle,
5582a5d1
JB
7085 (WLAN_FC_TYPE_MGMT << 2) |
7086 (WLAN_FC_STYPE_PROBE_REQ << 4),
a92dfde8
JB
7087 NULL, 0) < 0)
7088 goto out_err;
5582a5d1 7089
221a59c9 7090 eloop_register_read_sock(nl_socket_get_fd(bss->nl_preq.handle),
5582a5d1 7091 wpa_driver_nl80211_event_receive, drv,
221a59c9 7092 bss->nl_preq.handle);
5582a5d1 7093
504e905c 7094 return 0;
5582a5d1 7095
a92dfde8 7096 out_err:
221a59c9 7097 nl_destroy_handles(&bss->nl_preq);
5582a5d1 7098 return -1;
504e905c
JM
7099}
7100
7101
4e5cb1a3
JM
7102static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
7103 int ifindex, int disabled)
7104{
7105 struct nl_msg *msg;
7106 struct nlattr *bands, *band;
7107 int ret;
7108
7109 msg = nlmsg_alloc();
7110 if (!msg)
7111 return -1;
7112
9fb04070 7113 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_TX_BITRATE_MASK);
4e5cb1a3
JM
7114 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
7115
7116 bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
7117 if (!bands)
7118 goto nla_put_failure;
7119
7120 /*
7121 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
7122 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
7123 * rates. All 5 GHz rates are left enabled.
7124 */
7125 band = nla_nest_start(msg, NL80211_BAND_2GHZ);
7126 if (!band)
7127 goto nla_put_failure;
1dea5882
JM
7128 if (disabled) {
7129 NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
7130 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
7131 }
4e5cb1a3
JM
7132 nla_nest_end(msg, band);
7133
7134 nla_nest_end(msg, bands);
7135
7136 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7137 msg = NULL;
7138 if (ret) {
7139 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
7140 "(%s)", ret, strerror(-ret));
7141 }
7142
7143 return ret;
7144
7145nla_put_failure:
7146 nlmsg_free(msg);
7147 return -1;
7148}
7149
7150
af473088
JM
7151static int wpa_driver_nl80211_deinit_ap(void *priv)
7152{
a2e40bb6
FF
7153 struct i802_bss *bss = priv;
7154 struct wpa_driver_nl80211_data *drv = bss->drv;
b1f625e0 7155 if (!is_ap_interface(drv->nlmode))
af473088
JM
7156 return -1;
7157 wpa_driver_nl80211_del_beacon(drv);
b1f625e0 7158 return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
af473088
JM
7159}
7160
7161
207ef3fb
JM
7162static void wpa_driver_nl80211_resume(void *priv)
7163{
a2e40bb6
FF
7164 struct i802_bss *bss = priv;
7165 struct wpa_driver_nl80211_data *drv = bss->drv;
c81eff1a 7166 if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) {
207ef3fb
JM
7167 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on "
7168 "resume event");
7169 }
7170}
7171
7172
7b90c16a
JM
7173static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
7174 const u8 *ies, size_t ies_len)
7175{
7176 struct i802_bss *bss = priv;
7177 struct wpa_driver_nl80211_data *drv = bss->drv;
7178 int ret;
7179 u8 *data, *pos;
7180 size_t data_len;
7181 u8 own_addr[ETH_ALEN];
7182
c81eff1a
BG
7183 if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
7184 own_addr) < 0)
7b90c16a
JM
7185 return -1;
7186
7187 if (action != 1) {
7188 wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
7189 "action %d", action);
7190 return -1;
7191 }
7192
7193 /*
7194 * Action frame payload:
7195 * Category[1] = 6 (Fast BSS Transition)
7196 * Action[1] = 1 (Fast BSS Transition Request)
7197 * STA Address
7198 * Target AP Address
7199 * FT IEs
7200 */
7201
73fc617d
JM
7202 data_len = 2 + 2 * ETH_ALEN + ies_len;
7203 data = os_malloc(data_len);
7b90c16a
JM
7204 if (data == NULL)
7205 return -1;
7206 pos = data;
7207 *pos++ = 0x06; /* FT Action category */
7208 *pos++ = action;
7209 os_memcpy(pos, own_addr, ETH_ALEN);
7210 pos += ETH_ALEN;
7211 os_memcpy(pos, target_ap, ETH_ALEN);
7212 pos += ETH_ALEN;
7213 os_memcpy(pos, ies, ies_len);
7214
190b9062
JB
7215 ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, 0,
7216 drv->bssid, own_addr, drv->bssid,
b106173a 7217 data, data_len, 0);
7b90c16a
JM
7218 os_free(data);
7219
7220 return ret;
7221}
7222
7223
b625473c
JM
7224static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
7225{
7226 struct i802_bss *bss = priv;
7227 struct wpa_driver_nl80211_data *drv = bss->drv;
7228 struct nl_msg *msg, *cqm = NULL;
7229
7230 wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
7231 "hysteresis=%d", threshold, hysteresis);
7232
7233 msg = nlmsg_alloc();
7234 if (!msg)
7235 return -1;
7236
9fb04070 7237 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_CQM);
b625473c
JM
7238
7239 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
7240
7241 cqm = nlmsg_alloc();
7242 if (cqm == NULL)
7243 return -1;
7244
7245 NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
7246 NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
7247 nla_put_nested(msg, NL80211_ATTR_CQM, cqm);
7248
7249 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
7250 return 0;
7251 msg = NULL;
7252
7253nla_put_failure:
7254 if (cqm)
7255 nlmsg_free(cqm);
7256 nlmsg_free(msg);
7257 return -1;
7258}
7259
7260
1c5c7273
PS
7261static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
7262{
7263 struct i802_bss *bss = priv;
7264 struct wpa_driver_nl80211_data *drv = bss->drv;
7265 int res;
7266
7267 os_memset(si, 0, sizeof(*si));
7268 res = nl80211_get_link_signal(drv, si);
7269 if (res != 0)
7270 return res;
7271
7272 return nl80211_get_link_noise(drv, si);
7273}
7274
7275
57ebba59
JJ
7276static int wpa_driver_nl80211_shared_freq(void *priv)
7277{
7278 struct i802_bss *bss = priv;
7279 struct wpa_driver_nl80211_data *drv = bss->drv;
7280 struct wpa_driver_nl80211_data *driver;
7281 int freq = 0;
7282
7283 /*
7284 * If the same PHY is in connected state with some other interface,
7285 * then retrieve the assoc freq.
7286 */
7287 wpa_printf(MSG_DEBUG, "nl80211: Get shared freq for PHY %s",
7288 drv->phyname);
7289
7290 dl_list_for_each(driver, &drv->global->interfaces,
7291 struct wpa_driver_nl80211_data, list) {
7292 if (drv == driver ||
7293 os_strcmp(drv->phyname, driver->phyname) != 0 ||
7294 !driver->associated)
7295 continue;
7296
7297 wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s "
7298 MACSTR,
7299 driver->phyname, driver->first_bss.ifname,
7300 MAC2STR(driver->addr));
7301 freq = nl80211_get_assoc_freq(driver);
7302 wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",
7303 drv->phyname, freq);
7304 }
7305
7306 if (!freq)
7307 wpa_printf(MSG_DEBUG, "nl80211: No shared interface for "
7308 "PHY (%s) in associated state", drv->phyname);
7309
7310 return freq;
7311}
7312
7313
b91ab76e
JM
7314static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
7315 int encrypt)
7316{
7317 struct i802_bss *bss = priv;
7318 struct wpa_driver_nl80211_data *drv = bss->drv;
fab25336 7319 return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt, 0);
b91ab76e
JM
7320}
7321
7322
c55f774d
JM
7323static int nl80211_set_param(void *priv, const char *param)
7324{
c55f774d
JM
7325 wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
7326 if (param == NULL)
7327 return 0;
7328
7329#ifdef CONFIG_P2P
7330 if (os_strstr(param, "use_p2p_group_interface=1")) {
482856c8
JM
7331 struct i802_bss *bss = priv;
7332 struct wpa_driver_nl80211_data *drv = bss->drv;
7333
c55f774d
JM
7334 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
7335 "interface");
7336 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
7337 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
7338 }
7339#endif /* CONFIG_P2P */
7340
7341 return 0;
7342}
7343
7344
f2ed8023
JM
7345static void * nl80211_global_init(void)
7346{
7347 struct nl80211_global *global;
36d84860
BG
7348 struct netlink_config *cfg;
7349
f2ed8023
JM
7350 global = os_zalloc(sizeof(*global));
7351 if (global == NULL)
7352 return NULL;
c81eff1a 7353 global->ioctl_sock = -1;
f2ed8023 7354 dl_list_init(&global->interfaces);
ff6a158b 7355 global->if_add_ifindex = -1;
36d84860
BG
7356
7357 cfg = os_zalloc(sizeof(*cfg));
7358 if (cfg == NULL)
7359 goto err;
7360
7361 cfg->ctx = global;
7362 cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
7363 cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
7364 global->netlink = netlink_init(cfg);
7365 if (global->netlink == NULL) {
7366 os_free(cfg);
7367 goto err;
7368 }
7369
2a7b66f5
BG
7370 if (wpa_driver_nl80211_init_nl_global(global) < 0)
7371 goto err;
7372
c81eff1a
BG
7373 global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
7374 if (global->ioctl_sock < 0) {
7375 perror("socket(PF_INET,SOCK_DGRAM)");
7376 goto err;
7377 }
7378
f2ed8023 7379 return global;
36d84860
BG
7380
7381err:
7382 nl80211_global_deinit(global);
7383 return NULL;
f2ed8023
JM
7384}
7385
7386
7387static void nl80211_global_deinit(void *priv)
7388{
7389 struct nl80211_global *global = priv;
7390 if (global == NULL)
7391 return;
7392 if (!dl_list_empty(&global->interfaces)) {
7393 wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
7394 "nl80211_global_deinit",
7395 dl_list_len(&global->interfaces));
7396 }
36d84860
BG
7397
7398 if (global->netlink)
7399 netlink_deinit(global->netlink);
7400
276e2d67
BG
7401 nl_destroy_handles(&global->nl);
7402
2a7b66f5
BG
7403 if (global->nl_cb)
7404 nl_cb_put(global->nl_cb);
7405
c81eff1a
BG
7406 if (global->ioctl_sock >= 0)
7407 close(global->ioctl_sock);
7408
f2ed8023
JM
7409 os_free(global);
7410}
7411
7412
6859f1cb
BG
7413static const char * nl80211_get_radio_name(void *priv)
7414{
7415 struct i802_bss *bss = priv;
7416 struct wpa_driver_nl80211_data *drv = bss->drv;
7417 return drv->phyname;
7418}
7419
7420
a6efc65d
JM
7421static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
7422 const u8 *pmkid)
7423{
7424 struct nl_msg *msg;
7425
7426 msg = nlmsg_alloc();
7427 if (!msg)
7428 return -ENOMEM;
7429
9fb04070 7430 nl80211_cmd(bss->drv, msg, 0, cmd);
a6efc65d
JM
7431
7432 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
7433 if (pmkid)
7434 NLA_PUT(msg, NL80211_ATTR_PMKID, 16, pmkid);
7435 if (bssid)
7436 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
7437
7438 return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
7439 nla_put_failure:
7440 return -ENOBUFS;
7441}
7442
7443
7444static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
7445{
7446 struct i802_bss *bss = priv;
7447 wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
7448 return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
7449}
7450
7451
7452static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
7453{
7454 struct i802_bss *bss = priv;
7455 wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
7456 MAC2STR(bssid));
7457 return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
7458}
7459
7460
7461static int nl80211_flush_pmkid(void *priv)
7462{
7463 struct i802_bss *bss = priv;
7464 wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
7465 return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
7466}
7467
7468
b14a210c
JB
7469static void nl80211_set_rekey_info(void *priv, const u8 *kek, const u8 *kck,
7470 const u8 *replay_ctr)
7471{
7472 struct i802_bss *bss = priv;
7473 struct wpa_driver_nl80211_data *drv = bss->drv;
7474 struct nlattr *replay_nested;
7475 struct nl_msg *msg;
7476
7477 msg = nlmsg_alloc();
7478 if (!msg)
7479 return;
7480
9fb04070 7481 nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
b14a210c
JB
7482
7483 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
7484
7485 replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
7486 if (!replay_nested)
7487 goto nla_put_failure;
7488
7489 NLA_PUT(msg, NL80211_REKEY_DATA_KEK, NL80211_KEK_LEN, kek);
7490 NLA_PUT(msg, NL80211_REKEY_DATA_KCK, NL80211_KCK_LEN, kck);
7491 NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
7492 replay_ctr);
7493
7494 nla_nest_end(msg, replay_nested);
7495
7496 send_and_recv_msgs(drv, msg, NULL, NULL);
7497 return;
7498 nla_put_failure:
7499 nlmsg_free(msg);
7500}
7501
7502
39718852
JB
7503static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
7504 const u8 *addr, int qos)
bcf24348 7505{
39718852
JB
7506 /* send data frame to poll STA and check whether
7507 * this frame is ACKed */
bcf24348
JB
7508 struct {
7509 struct ieee80211_hdr hdr;
7510 u16 qos_ctl;
7511 } STRUCT_PACKED nulldata;
7512 size_t size;
7513
7514 /* Send data frame to poll STA and check whether this frame is ACKed */
7515
7516 os_memset(&nulldata, 0, sizeof(nulldata));
7517
7518 if (qos) {
7519 nulldata.hdr.frame_control =
7520 IEEE80211_FC(WLAN_FC_TYPE_DATA,
7521 WLAN_FC_STYPE_QOS_NULL);
7522 size = sizeof(nulldata);
7523 } else {
7524 nulldata.hdr.frame_control =
7525 IEEE80211_FC(WLAN_FC_TYPE_DATA,
7526 WLAN_FC_STYPE_NULLFUNC);
7527 size = sizeof(struct ieee80211_hdr);
7528 }
7529
7530 nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
7531 os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
7532 os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
7533 os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
7534
8cfa3527 7535 if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0) < 0)
bcf24348
JB
7536 wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
7537 "send poll frame");
7538}
7539
39718852
JB
7540static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
7541 int qos)
7542{
7543 struct i802_bss *bss = priv;
7544 struct wpa_driver_nl80211_data *drv = bss->drv;
7545 struct nl_msg *msg;
7546
7547 if (!drv->poll_command_supported) {
7548 nl80211_send_null_frame(bss, own_addr, addr, qos);
7549 return;
7550 }
7551
7552 msg = nlmsg_alloc();
7553 if (!msg)
7554 return;
7555
7556 nl80211_cmd(drv, msg, 0, NL80211_CMD_PROBE_CLIENT);
7557
7558 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
7559 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
7560
7561 send_and_recv_msgs(drv, msg, NULL, NULL);
7562 return;
7563 nla_put_failure:
7564 nlmsg_free(msg);
7565}
7566
bcf24348 7567
03ea1786
AN
7568#ifdef CONFIG_TDLS
7569
7570static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
7571 u8 dialog_token, u16 status_code,
7572 const u8 *buf, size_t len)
7573{
7574 struct i802_bss *bss = priv;
7575 struct wpa_driver_nl80211_data *drv = bss->drv;
7576 struct nl_msg *msg;
7577
7578 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
7579 return -EOPNOTSUPP;
7580
7581 if (!dst)
7582 return -EINVAL;
7583
7584 msg = nlmsg_alloc();
7585 if (!msg)
7586 return -ENOMEM;
7587
7588 nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_MGMT);
7589 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7590 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
7591 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_ACTION, action_code);
7592 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token);
7593 NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status_code);
7594 NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
7595
7596 return send_and_recv_msgs(drv, msg, NULL, NULL);
7597
7598nla_put_failure:
7599 nlmsg_free(msg);
7600 return -ENOBUFS;
7601}
7602
7603
7604static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
7605{
7606 struct i802_bss *bss = priv;
7607 struct wpa_driver_nl80211_data *drv = bss->drv;
7608 struct nl_msg *msg;
7609 enum nl80211_tdls_operation nl80211_oper;
7610
7611 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
7612 return -EOPNOTSUPP;
7613
7614 switch (oper) {
7615 case TDLS_DISCOVERY_REQ:
7616 nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
7617 break;
7618 case TDLS_SETUP:
7619 nl80211_oper = NL80211_TDLS_SETUP;
7620 break;
7621 case TDLS_TEARDOWN:
7622 nl80211_oper = NL80211_TDLS_TEARDOWN;
7623 break;
7624 case TDLS_ENABLE_LINK:
7625 nl80211_oper = NL80211_TDLS_ENABLE_LINK;
7626 break;
7627 case TDLS_DISABLE_LINK:
7628 nl80211_oper = NL80211_TDLS_DISABLE_LINK;
7629 break;
7630 case TDLS_ENABLE:
7631 return 0;
7632 case TDLS_DISABLE:
7633 return 0;
7634 default:
7635 return -EINVAL;
7636 }
7637
7638 msg = nlmsg_alloc();
7639 if (!msg)
7640 return -ENOMEM;
7641
7642 nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_OPER);
7643 NLA_PUT_U8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper);
7644 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7645 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
7646
7647 return send_and_recv_msgs(drv, msg, NULL, NULL);
7648
7649nla_put_failure:
7650 nlmsg_free(msg);
7651 return -ENOBUFS;
7652}
7653
7654#endif /* CONFIG TDLS */
7655
7656
3f5285e8
JM
7657const struct wpa_driver_ops wpa_driver_nl80211_ops = {
7658 .name = "nl80211",
7659 .desc = "Linux nl80211/cfg80211",
7660 .get_bssid = wpa_driver_nl80211_get_bssid,
7661 .get_ssid = wpa_driver_nl80211_get_ssid,
3f5285e8 7662 .set_key = wpa_driver_nl80211_set_key,
6a1063e0 7663 .scan2 = wpa_driver_nl80211_scan,
d21c63b9
LC
7664 .sched_scan = wpa_driver_nl80211_sched_scan,
7665 .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
3f5285e8
JM
7666 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
7667 .deauthenticate = wpa_driver_nl80211_deauthenticate,
7668 .disassociate = wpa_driver_nl80211_disassociate,
c2a04078 7669 .authenticate = wpa_driver_nl80211_authenticate,
3f5285e8 7670 .associate = wpa_driver_nl80211_associate,
f2ed8023
JM
7671 .global_init = nl80211_global_init,
7672 .global_deinit = nl80211_global_deinit,
7673 .init2 = wpa_driver_nl80211_init,
3f5285e8 7674 .deinit = wpa_driver_nl80211_deinit,
3f5285e8
JM
7675 .get_capa = wpa_driver_nl80211_get_capa,
7676 .set_operstate = wpa_driver_nl80211_set_operstate,
01652550 7677 .set_supp_port = wpa_driver_nl80211_set_supp_port,
6d158490 7678 .set_country = wpa_driver_nl80211_set_country,
19c3b566 7679 .set_ap = wpa_driver_nl80211_set_ap,
22a7c9d7
JM
7680 .if_add = wpa_driver_nl80211_if_add,
7681 .if_remove = wpa_driver_nl80211_if_remove,
071f8ac4 7682 .send_mlme = wpa_driver_nl80211_send_mlme,
c3965310 7683 .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
0f4e8b4f
JM
7684 .sta_add = wpa_driver_nl80211_sta_add,
7685 .sta_remove = wpa_driver_nl80211_sta_remove,
db149ac9 7686 .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
a8d6ffa4 7687 .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
c5121837
JM
7688#ifdef HOSTAPD
7689 .hapd_init = i802_init,
c5121837 7690 .hapd_deinit = i802_deinit,
f7b3920c
JM
7691 .set_wds_sta = i802_set_wds_sta,
7692#endif /* HOSTAPD */
7693#if defined(HOSTAPD) || defined(CONFIG_AP)
c5121837
JM
7694 .get_seqnum = i802_get_seqnum,
7695 .flush = i802_flush,
7696 .read_sta_data = i802_read_sta_data,
c5121837
JM
7697 .get_inact_sec = i802_get_inact_sec,
7698 .sta_clear_stats = i802_sta_clear_stats,
c5121837
JM
7699 .set_rts = i802_set_rts,
7700 .set_frag = i802_set_frag,
c5121837 7701 .set_tx_queue_params = i802_set_tx_queue_params,
c5121837 7702 .set_sta_vlan = i802_set_sta_vlan,
257da773 7703 .set_rate_sets = i802_set_rate_sets,
ee7ab173
JB
7704 .sta_deauth = i802_sta_deauth,
7705 .sta_disassoc = i802_sta_disassoc,
7706#endif /* HOSTAPD || CONFIG_AP */
e3802622 7707 .set_freq = i802_set_freq,
58f6fbe0 7708 .send_action = wpa_driver_nl80211_send_action,
5dfca53f 7709 .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
55777702
JM
7710 .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
7711 .cancel_remain_on_channel =
7712 wpa_driver_nl80211_cancel_remain_on_channel,
504e905c 7713 .probe_req_report = wpa_driver_nl80211_probe_req_report,
af473088 7714 .deinit_ap = wpa_driver_nl80211_deinit_ap,
207ef3fb 7715 .resume = wpa_driver_nl80211_resume,
7b90c16a 7716 .send_ft_action = nl80211_send_ft_action,
b625473c 7717 .signal_monitor = nl80211_signal_monitor,
1c5c7273 7718 .signal_poll = nl80211_signal_poll,
b91ab76e 7719 .send_frame = nl80211_send_frame,
57ebba59 7720 .shared_freq = wpa_driver_nl80211_shared_freq,
c55f774d 7721 .set_param = nl80211_set_param,
6859f1cb 7722 .get_radio_name = nl80211_get_radio_name,
a6efc65d
JM
7723 .add_pmkid = nl80211_add_pmkid,
7724 .remove_pmkid = nl80211_remove_pmkid,
7725 .flush_pmkid = nl80211_flush_pmkid,
b14a210c 7726 .set_rekey_info = nl80211_set_rekey_info,
bcf24348 7727 .poll_client = nl80211_poll_client,
03ea1786
AN
7728#ifdef CONFIG_TDLS
7729 .send_tdls_mgmt = nl80211_send_tdls_mgmt,
7730 .tdls_oper = nl80211_tdls_oper,
7731#endif /* CONFIG_TDLS */
3f5285e8 7732};