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