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