]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/drivers/driver_nl80211.c
nl80211: Add BSSID to NL80211_CMD_CONNECT assoc reject event
[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>
37b7d082 21#include <net/if.h>
3f5285e8
JM
22#include <netlink/genl/genl.h>
23#include <netlink/genl/family.h>
24#include <netlink/genl/ctrl.h>
8602b0f2 25#include <linux/rtnetlink.h>
1b648c7e
JM
26#include <netpacket/packet.h>
27#include <linux/filter.h>
7e45830a 28#include "nl80211_copy.h"
625f587b 29
3f5285e8 30#include "common.h"
1b648c7e
JM
31#include "eloop.h"
32#include "common/ieee802_11_defs.h"
e2d02c29 33#include "netlink.h"
34f2f814 34#include "linux_ioctl.h"
e2d02c29
JM
35#include "radiotap.h"
36#include "radiotap_iter.h"
8401a6b0 37#include "rfkill.h"
1b648c7e 38#include "driver.h"
0915d02c 39
c5121837
JM
40#ifdef CONFIG_LIBNL20
41/* libnl 2.0 compatibility code */
2e8eac2d 42#define nl_handle nl_sock
a65a9aed
JB
43#define nl80211_handle_alloc nl_socket_alloc_cb
44#define nl80211_handle_destroy nl_socket_free
45#else
46/*
47 * libnl 1.1 has a bug, it tries to allocate socket numbers densely
48 * but when you free a socket again it will mess up its bitmap and
49 * and use the wrong number the next time it needs a socket ID.
50 * Therefore, we wrap the handle alloc/destroy and add our own pid
51 * accounting.
52 */
53static uint32_t port_bitmap[32] = { 0 };
54
55static struct nl_handle *nl80211_handle_alloc(void *cb)
56{
57 struct nl_handle *handle;
58 uint32_t pid = getpid() & 0x3FFFFF;
59 int i;
60
61 handle = nl_handle_alloc_cb(cb);
62
63 for (i = 0; i < 1024; i++) {
64 if (port_bitmap[i / 32] & (1 << (i % 32)))
65 continue;
66 port_bitmap[i / 32] |= 1 << (i % 32);
67 pid += i << 22;
68 break;
69 }
70
71 nl_socket_set_local_port(handle, pid);
72
73 return handle;
74}
75
76static void nl80211_handle_destroy(struct nl_handle *handle)
77{
78 uint32_t port = nl_socket_get_local_port(handle);
79
80 port >>= 22;
81 port_bitmap[port / 32] &= ~(1 << (port % 32));
82
83 nl_handle_destroy(handle);
84}
c5121837
JM
85#endif /* CONFIG_LIBNL20 */
86
c5121837 87
3f5285e8
JM
88#ifndef IFF_LOWER_UP
89#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
90#endif
91#ifndef IFF_DORMANT
92#define IFF_DORMANT 0x20000 /* driver signals dormant */
93#endif
94
95#ifndef IF_OPER_DORMANT
96#define IF_OPER_DORMANT 5
97#endif
98#ifndef IF_OPER_UP
99#define IF_OPER_UP 6
100#endif
101
c5121837 102struct i802_bss {
a2e40bb6 103 struct wpa_driver_nl80211_data *drv;
c5121837 104 struct i802_bss *next;
b4fd6fab 105 int ifindex;
a2e40bb6 106 char ifname[IFNAMSIZ + 1];
c5121837
JM
107 unsigned int beacon_set:1;
108};
3f5285e8
JM
109
110struct wpa_driver_nl80211_data {
111 void *ctx;
08063178 112 struct netlink_data *netlink;
c5121837 113 int ioctl_sock; /* socket for ioctl() use */
94627f6c 114 char brname[IFNAMSIZ];
3f5285e8 115 int ifindex;
7524cfb1 116 int if_removed;
a63063b4 117 int if_disabled;
8401a6b0 118 struct rfkill_data *rfkill;
c2a04078
JM
119 struct wpa_driver_capa capa;
120 int has_capability;
c2a04078 121
3f5285e8
JM
122 int operstate;
123
3f5285e8
JM
124 int scan_complete_events;
125
126 struct nl_handle *nl_handle;
335ce76b 127 struct nl_handle *nl_handle_event;
5582a5d1 128 struct nl_handle *nl_handle_preq;
3f5285e8 129 struct nl_cache *nl_cache;
335ce76b 130 struct nl_cache *nl_cache_event;
5582a5d1 131 struct nl_cache *nl_cache_preq;
3f5285e8
JM
132 struct nl_cb *nl_cb;
133 struct genl_family *nl80211;
1c873584 134
e6b8efeb 135 u8 auth_bssid[ETH_ALEN];
c2a04078
JM
136 u8 bssid[ETH_ALEN];
137 int associated;
fd05d64e
JM
138 u8 ssid[32];
139 size_t ssid_len;
ad1e68e6
JM
140 int nlmode;
141 int ap_scan_as_station;
4832ecd7 142 unsigned int assoc_freq;
d2440ba0 143
0915d02c
JM
144 int monitor_sock;
145 int monitor_ifidx;
4e5cb1a3 146 int disable_11b_rates;
7da3abe7 147
55777702 148 unsigned int pending_remain_on_chan:1;
94627f6c
JM
149 unsigned int added_bridge:1;
150 unsigned int added_if_into_bridge:1;
55777702
JM
151
152 u64 remain_on_chan_cookie;
58f6fbe0 153 u64 send_action_cookie;
c5121837 154
5582a5d1
JB
155 unsigned int last_mgmt_freq;
156
3812464c
JM
157 struct wpa_driver_scan_filter *filter_ssids;
158 size_t num_filter_ssids;
159
a2e40bb6
FF
160 struct i802_bss first_bss;
161
c5121837 162#ifdef HOSTAPD
c5121837 163 int eapol_sock; /* socket for EAPOL frames */
c5121837
JM
164
165 int default_if_indices[16];
166 int *if_indices;
167 int num_if_indices;
168
c5121837
JM
169 int last_freq;
170 int last_freq_ht;
c5121837 171#endif /* HOSTAPD */
3f5285e8
JM
172};
173
174
175static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
176 void *timeout_ctx);
ad1e68e6 177static int wpa_driver_nl80211_set_mode(void *priv, int mode);
362f781e 178static int
7524cfb1 179wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
d72aad94 180static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
77339912
JM
181 const u8 *addr, int cmd, u16 reason_code,
182 int local_state_change);
460456f8
JM
183static void nl80211_remove_monitor_interface(
184 struct wpa_driver_nl80211_data *drv);
5582a5d1
JB
185static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv,
186 unsigned int freq, const u8 *buf,
187 size_t buf_len, u64 *cookie);
188static int wpa_driver_nl80211_probe_req_report(void *priv, int report);
0915d02c 189
072ad14c 190#ifdef HOSTAPD
2135f224
JM
191static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
192static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
97cfcf64 193static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
fbbfcbac
FF
194static int wpa_driver_nl80211_if_remove(void *priv,
195 enum wpa_driver_if_type type,
196 const char *ifname);
37eb8da9
JM
197#else /* HOSTAPD */
198static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
199{
200 return 0;
201}
072ad14c
JM
202#endif /* HOSTAPD */
203
e3802622 204static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
4e5cb1a3
JM
205static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
206 int ifindex, int disabled);
504e905c 207
3f5285e8 208
6241fcb1
JM
209/* nl80211 code */
210static int ack_handler(struct nl_msg *msg, void *arg)
211{
212 int *err = arg;
213 *err = 0;
214 return NL_STOP;
215}
216
217static int finish_handler(struct nl_msg *msg, void *arg)
218{
8e8df255
JM
219 int *ret = arg;
220 *ret = 0;
6241fcb1
JM
221 return NL_SKIP;
222}
223
224static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
225 void *arg)
226{
227 int *ret = arg;
228 *ret = err->error;
229 return NL_SKIP;
230}
231
5b7b85f6
JM
232
233static int no_seq_check(struct nl_msg *msg, void *arg)
234{
235 return NL_OK;
236}
237
238
58f6fbe0
JM
239static int send_and_recv(struct wpa_driver_nl80211_data *drv,
240 struct nl_handle *nl_handle, struct nl_msg *msg,
241 int (*valid_handler)(struct nl_msg *, void *),
242 void *valid_data)
6241fcb1
JM
243{
244 struct nl_cb *cb;
245 int err = -ENOMEM;
246
247 cb = nl_cb_clone(drv->nl_cb);
248 if (!cb)
249 goto out;
250
58f6fbe0 251 err = nl_send_auto_complete(nl_handle, msg);
6241fcb1
JM
252 if (err < 0)
253 goto out;
254
255 err = 1;
256
257 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
8e8df255 258 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
6241fcb1
JM
259 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
260
261 if (valid_handler)
262 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
263 valid_handler, valid_data);
264
265 while (err > 0)
58f6fbe0 266 nl_recvmsgs(nl_handle, cb);
6241fcb1
JM
267 out:
268 nl_cb_put(cb);
269 nlmsg_free(msg);
270 return err;
271}
272
273
58f6fbe0
JM
274static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
275 struct nl_msg *msg,
276 int (*valid_handler)(struct nl_msg *, void *),
277 void *valid_data)
278{
279 return send_and_recv(drv, drv->nl_handle, msg, valid_handler,
280 valid_data);
281}
282
283
97865538
JM
284struct family_data {
285 const char *group;
286 int id;
287};
288
289
290static int family_handler(struct nl_msg *msg, void *arg)
291{
292 struct family_data *res = arg;
293 struct nlattr *tb[CTRL_ATTR_MAX + 1];
294 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
295 struct nlattr *mcgrp;
296 int i;
297
298 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
299 genlmsg_attrlen(gnlh, 0), NULL);
300 if (!tb[CTRL_ATTR_MCAST_GROUPS])
301 return NL_SKIP;
302
303 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
304 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
305 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
306 nla_len(mcgrp), NULL);
307 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
308 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
309 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
310 res->group,
311 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
312 continue;
313 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
314 break;
315 };
316
317 return NL_SKIP;
318}
319
320
321static int nl_get_multicast_id(struct wpa_driver_nl80211_data *drv,
322 const char *family, const char *group)
323{
324 struct nl_msg *msg;
325 int ret = -1;
326 struct family_data res = { group, -ENOENT };
327
328 msg = nlmsg_alloc();
329 if (!msg)
330 return -ENOMEM;
331 genlmsg_put(msg, 0, 0, genl_ctrl_resolve(drv->nl_handle, "nlctrl"),
332 0, 0, CTRL_CMD_GETFAMILY, 0);
333 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
334
335 ret = send_and_recv_msgs(drv, msg, family_handler, &res);
336 msg = NULL;
337 if (ret == 0)
338 ret = res.id;
339
340nla_put_failure:
341 nlmsg_free(msg);
342 return ret;
343}
344
345
3f5285e8
JM
346static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
347{
a2e40bb6
FF
348 struct i802_bss *bss = priv;
349 struct wpa_driver_nl80211_data *drv = bss->drv;
c2a04078
JM
350 if (!drv->associated)
351 return -1;
352 os_memcpy(bssid, drv->bssid, ETH_ALEN);
353 return 0;
3f5285e8
JM
354}
355
356
3f5285e8
JM
357static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
358{
a2e40bb6
FF
359 struct i802_bss *bss = priv;
360 struct wpa_driver_nl80211_data *drv = bss->drv;
fd05d64e
JM
361 if (!drv->associated)
362 return -1;
363 os_memcpy(ssid, drv->ssid, drv->ssid_len);
364 return drv->ssid_len;
3f5285e8
JM
365}
366
367
7524cfb1 368static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
08063178 369 char *buf, size_t len, int del)
3f5285e8
JM
370{
371 union wpa_event_data event;
372
373 os_memset(&event, 0, sizeof(event));
374 if (len > sizeof(event.interface_status.ifname))
375 len = sizeof(event.interface_status.ifname) - 1;
376 os_memcpy(event.interface_status.ifname, buf, len);
377 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
378 EVENT_INTERFACE_ADDED;
379
380 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
381 del ? "DEL" : "NEW",
382 event.interface_status.ifname,
383 del ? "removed" : "added");
384
a2e40bb6 385 if (os_strcmp(drv->first_bss.ifname, event.interface_status.ifname) == 0) {
7524cfb1
JM
386 if (del)
387 drv->if_removed = 1;
388 else
389 drv->if_removed = 0;
390 }
391
08063178 392 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
3f5285e8
JM
393}
394
395
7524cfb1 396static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
62d680c3 397 u8 *buf, size_t len)
7524cfb1 398{
62d680c3 399 int attrlen, rta_len;
7524cfb1
JM
400 struct rtattr *attr;
401
62d680c3
JM
402 attrlen = len;
403 attr = (struct rtattr *) buf;
7524cfb1
JM
404
405 rta_len = RTA_ALIGN(sizeof(struct rtattr));
406 while (RTA_OK(attr, attrlen)) {
407 if (attr->rta_type == IFLA_IFNAME) {
a2e40bb6 408 if (os_strcmp(((char *) attr) + rta_len, drv->first_bss.ifname)
7524cfb1
JM
409 == 0)
410 return 1;
411 else
412 break;
413 }
414 attr = RTA_NEXT(attr, attrlen);
415 }
416
417 return 0;
418}
419
420
421static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
62d680c3 422 int ifindex, u8 *buf, size_t len)
7524cfb1
JM
423{
424 if (drv->ifindex == ifindex)
425 return 1;
426
62d680c3 427 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
a2e40bb6 428 drv->first_bss.ifindex = if_nametoindex(drv->first_bss.ifname);
7524cfb1
JM
429 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
430 "interface");
431 wpa_driver_nl80211_finish_drv_init(drv);
432 return 1;
433 }
434
435 return 0;
436}
437
438
62d680c3
JM
439static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
440 struct ifinfomsg *ifi,
441 u8 *buf, size_t len)
3f5285e8 442{
08063178 443 struct wpa_driver_nl80211_data *drv = ctx;
62d680c3
JM
444 int attrlen, rta_len;
445 struct rtattr *attr;
97cfcf64 446 u32 brid = 0;
3f5285e8 447
97cfcf64
B
448 if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, buf, len) &&
449 !have_ifidx(drv, ifi->ifi_index)) {
450 wpa_printf(MSG_DEBUG, "nl80211: Ignore event for foreign "
451 "ifindex %d", ifi->ifi_index);
3f5285e8
JM
452 return;
453 }
454
455 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
456 "(%s%s%s%s)",
457 drv->operstate, ifi->ifi_flags,
458 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
459 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
460 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
461 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
a63063b4
JM
462
463 if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
464 wpa_printf(MSG_DEBUG, "nl80211: Interface down");
465 drv->if_disabled = 1;
466 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
467 }
468
469 if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
470 wpa_printf(MSG_DEBUG, "nl80211: Interface up");
471 drv->if_disabled = 0;
472 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
473 }
474
3f5285e8
JM
475 /*
476 * Some drivers send the association event before the operup event--in
477 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
478 * fails. This will hit us when wpa_supplicant does not need to do
479 * IEEE 802.1X authentication
480 */
481 if (drv->operstate == 1 &&
482 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
483 !(ifi->ifi_flags & IFF_RUNNING))
08063178 484 netlink_send_oper_ifla(drv->netlink, drv->ifindex,
e2d02c29 485 -1, IF_OPER_UP);
3f5285e8 486
62d680c3
JM
487 attrlen = len;
488 attr = (struct rtattr *) buf;
3f5285e8
JM
489 rta_len = RTA_ALIGN(sizeof(struct rtattr));
490 while (RTA_OK(attr, attrlen)) {
d8816397 491 if (attr->rta_type == IFLA_IFNAME) {
7524cfb1 492 wpa_driver_nl80211_event_link(
08063178 493 drv,
7524cfb1
JM
494 ((char *) attr) + rta_len,
495 attr->rta_len - rta_len, 0);
97cfcf64
B
496 } else if (attr->rta_type == IFLA_MASTER)
497 brid = nla_get_u32((struct nlattr *) attr);
3f5285e8
JM
498 attr = RTA_NEXT(attr, attrlen);
499 }
97cfcf64 500
37eb8da9 501#ifdef HOSTAPD
97cfcf64
B
502 if (ifi->ifi_family == AF_BRIDGE && brid) {
503 /* device has been added to bridge */
504 char namebuf[IFNAMSIZ];
505 if_indextoname(brid, namebuf);
506 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
507 brid, namebuf);
508 add_ifidx(drv, brid);
509 }
37eb8da9 510#endif /* HOSTAPD */
3f5285e8
JM
511}
512
513
62d680c3
JM
514static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
515 struct ifinfomsg *ifi,
516 u8 *buf, size_t len)
3f5285e8 517{
08063178 518 struct wpa_driver_nl80211_data *drv = ctx;
62d680c3
JM
519 int attrlen, rta_len;
520 struct rtattr *attr;
97cfcf64 521 u32 brid = 0;
3f5285e8 522
62d680c3
JM
523 attrlen = len;
524 attr = (struct rtattr *) buf;
3f5285e8
JM
525
526 rta_len = RTA_ALIGN(sizeof(struct rtattr));
527 while (RTA_OK(attr, attrlen)) {
528 if (attr->rta_type == IFLA_IFNAME) {
7524cfb1 529 wpa_driver_nl80211_event_link(
08063178 530 drv,
7524cfb1
JM
531 ((char *) attr) + rta_len,
532 attr->rta_len - rta_len, 1);
97cfcf64
B
533 } else if (attr->rta_type == IFLA_MASTER)
534 brid = nla_get_u32((struct nlattr *) attr);
3f5285e8
JM
535 attr = RTA_NEXT(attr, attrlen);
536 }
97cfcf64 537
37eb8da9 538#ifdef HOSTAPD
97cfcf64
B
539 if (ifi->ifi_family == AF_BRIDGE && brid) {
540 /* device has been removed from bridge */
541 char namebuf[IFNAMSIZ];
542 if_indextoname(brid, namebuf);
543 wpa_printf(MSG_DEBUG, "nl80211: Remove ifindex %u for bridge "
544 "%s", brid, namebuf);
545 del_ifidx(drv, brid);
546 }
37eb8da9 547#endif /* HOSTAPD */
3f5285e8
JM
548}
549
550
c2a04078
JM
551static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
552 const u8 *frame, size_t len)
553{
554 const struct ieee80211_mgmt *mgmt;
555 union wpa_event_data event;
556
557 mgmt = (const struct ieee80211_mgmt *) frame;
558 if (len < 24 + sizeof(mgmt->u.auth)) {
559 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
560 "frame");
561 return;
562 }
563
e6b8efeb 564 os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
c2a04078
JM
565 os_memset(&event, 0, sizeof(event));
566 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
567 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
568 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
569 if (len > 24 + sizeof(mgmt->u.auth)) {
570 event.auth.ies = mgmt->u.auth.variable;
571 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
572 }
573
574 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
575}
576
577
578static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
579 const u8 *frame, size_t len)
580{
581 const struct ieee80211_mgmt *mgmt;
582 union wpa_event_data event;
583 u16 status;
584
585 mgmt = (const struct ieee80211_mgmt *) frame;
586 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
587 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
588 "frame");
589 return;
590 }
591
592 status = le_to_host16(mgmt->u.assoc_resp.status_code);
593 if (status != WLAN_STATUS_SUCCESS) {
efa46078 594 os_memset(&event, 0, sizeof(event));
59ddf221 595 event.assoc_reject.bssid = mgmt->bssid;
efa46078
JM
596 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
597 event.assoc_reject.resp_ies =
598 (u8 *) mgmt->u.assoc_resp.variable;
599 event.assoc_reject.resp_ies_len =
600 len - 24 - sizeof(mgmt->u.assoc_resp);
601 }
602 event.assoc_reject.status_code = status;
603
604 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
c2a04078
JM
605 return;
606 }
607
608 drv->associated = 1;
609 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
610
611 os_memset(&event, 0, sizeof(event));
612 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
613 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
614 event.assoc_info.resp_ies_len =
efa46078 615 len - 24 - sizeof(mgmt->u.assoc_resp);
c2a04078
JM
616 }
617
4832ecd7
JM
618 event.assoc_info.freq = drv->assoc_freq;
619
c2a04078
JM
620 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
621}
622
c1bb3e0a 623
da72a1c1
ZY
624static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
625 enum nl80211_commands cmd, struct nlattr *status,
626 struct nlattr *addr, struct nlattr *req_ie,
627 struct nlattr *resp_ie)
628{
629 union wpa_event_data event;
630
7da2c527
JM
631 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
632 /*
633 * Avoid reporting two association events that would confuse
634 * the core code.
635 */
636 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
637 "when using userspace SME", cmd);
638 return;
639 }
640
da72a1c1
ZY
641 os_memset(&event, 0, sizeof(event));
642 if (cmd == NL80211_CMD_CONNECT &&
643 nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
df89c1c8
JM
644 if (addr)
645 event.assoc_reject.bssid = nla_data(addr);
da72a1c1
ZY
646 if (resp_ie) {
647 event.assoc_reject.resp_ies = nla_data(resp_ie);
648 event.assoc_reject.resp_ies_len = nla_len(resp_ie);
649 }
650 event.assoc_reject.status_code = nla_get_u16(status);
651 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
652 return;
653 }
654
655 drv->associated = 1;
656 if (addr)
657 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
658
659 if (req_ie) {
660 event.assoc_info.req_ies = nla_data(req_ie);
661 event.assoc_info.req_ies_len = nla_len(req_ie);
662 }
663 if (resp_ie) {
664 event.assoc_info.resp_ies = nla_data(resp_ie);
665 event.assoc_info.resp_ies_len = nla_len(resp_ie);
666 }
667
668 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
669}
c2a04078 670
c1bb3e0a 671
da1fb17c
JM
672static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
673 enum nl80211_commands cmd, struct nlattr *addr)
674{
675 union wpa_event_data event;
676 enum wpa_event_type ev;
677
678 if (nla_len(addr) != ETH_ALEN)
679 return;
680
681 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
682 cmd, MAC2STR((u8 *) nla_data(addr)));
683
684 if (cmd == NL80211_CMD_AUTHENTICATE)
685 ev = EVENT_AUTH_TIMED_OUT;
686 else if (cmd == NL80211_CMD_ASSOCIATE)
687 ev = EVENT_ASSOC_TIMED_OUT;
688 else
689 return;
690
691 os_memset(&event, 0, sizeof(event));
692 os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
693 wpa_supplicant_event(drv->ctx, ev, &event);
694}
695
696
5582a5d1
JB
697static void mlme_event_mgmt(struct wpa_driver_nl80211_data *drv,
698 struct nlattr *freq, const u8 *frame, size_t len)
58f6fbe0
JM
699{
700 const struct ieee80211_mgmt *mgmt;
701 union wpa_event_data event;
702 u16 fc, stype;
703
704 mgmt = (const struct ieee80211_mgmt *) frame;
705 if (len < 24) {
706 wpa_printf(MSG_DEBUG, "nl80211: Too short action frame");
707 return;
708 }
709
710 fc = le_to_host16(mgmt->frame_control);
711 stype = WLAN_FC_GET_STYPE(fc);
712
713 os_memset(&event, 0, sizeof(event));
5582a5d1 714 if (freq) {
58f6fbe0 715 event.rx_action.freq = nla_get_u32(freq);
5582a5d1
JB
716 drv->last_mgmt_freq = event.rx_action.freq;
717 }
718 if (stype == WLAN_FC_STYPE_ACTION) {
719 event.rx_action.da = mgmt->da;
720 event.rx_action.sa = mgmt->sa;
721 event.rx_action.bssid = mgmt->bssid;
722 event.rx_action.category = mgmt->u.action.category;
723 event.rx_action.data = &mgmt->u.action.category + 1;
724 event.rx_action.len = frame + len - event.rx_action.data;
725 wpa_supplicant_event(drv->ctx, EVENT_RX_ACTION, &event);
726 } else {
727 event.rx_mgmt.frame = frame;
728 event.rx_mgmt.frame_len = len;
729 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
730 }
58f6fbe0
JM
731}
732
733
734static void mlme_event_action_tx_status(struct wpa_driver_nl80211_data *drv,
735 struct nlattr *cookie, const u8 *frame,
736 size_t len, struct nlattr *ack)
737{
738 union wpa_event_data event;
739 const struct ieee80211_hdr *hdr;
740 u16 fc;
741 u64 cookie_val;
742
743 if (!cookie)
744 return;
745
746 cookie_val = nla_get_u64(cookie);
4796272f
JM
747 wpa_printf(MSG_DEBUG, "nl80211: Action TX status: cookie=0%llx%s "
748 "(ack=%d)",
58f6fbe0
JM
749 (long long unsigned int) cookie_val,
750 cookie_val == drv->send_action_cookie ?
4796272f 751 " (match)" : " (unknown)", ack != NULL);
58f6fbe0
JM
752 if (cookie_val != drv->send_action_cookie)
753 return;
754
755 hdr = (const struct ieee80211_hdr *) frame;
756 fc = le_to_host16(hdr->frame_control);
757
758 os_memset(&event, 0, sizeof(event));
759 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
760 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
761 event.tx_status.dst = hdr->addr1;
762 event.tx_status.data = frame;
763 event.tx_status.data_len = len;
764 event.tx_status.ack = ack != NULL;
765 wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
766}
767
768
0544b242
JM
769static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
770 enum wpa_event_type type,
771 const u8 *frame, size_t len)
772{
773 const struct ieee80211_mgmt *mgmt;
774 union wpa_event_data event;
775 const u8 *bssid = NULL;
776 u16 reason_code = 0;
777
cb30b297
PS
778 mgmt = (const struct ieee80211_mgmt *) frame;
779 if (len >= 24) {
780 bssid = mgmt->bssid;
781
782 if (drv->associated != 0 &&
783 os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
784 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
785 /*
786 * We have presumably received this deauth as a
787 * response to a clear_state_mismatch() outgoing
788 * deauth. Don't let it take us offline!
789 */
790 wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
791 "from Unknown BSSID " MACSTR " -- ignoring",
792 MAC2STR(bssid));
793 return;
794 }
795 }
796
0544b242
JM
797 drv->associated = 0;
798 os_memset(&event, 0, sizeof(event));
799
0544b242
JM
800 /* Note: Same offset for Reason Code in both frame subtypes */
801 if (len >= 24 + sizeof(mgmt->u.deauth))
802 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
803
804 if (type == EVENT_DISASSOC) {
805 event.disassoc_info.addr = bssid;
806 event.disassoc_info.reason_code = reason_code;
046b26a2
JM
807 if (frame + len > mgmt->u.disassoc.variable) {
808 event.disassoc_info.ie = mgmt->u.disassoc.variable;
809 event.disassoc_info.ie_len = frame + len -
810 mgmt->u.disassoc.variable;
811 }
0544b242
JM
812 } else {
813 event.deauth_info.addr = bssid;
814 event.deauth_info.reason_code = reason_code;
046b26a2
JM
815 if (frame + len > mgmt->u.deauth.variable) {
816 event.deauth_info.ie = mgmt->u.deauth.variable;
817 event.deauth_info.ie_len = frame + len -
818 mgmt->u.deauth.variable;
819 }
0544b242
JM
820 }
821
822 wpa_supplicant_event(drv->ctx, type, &event);
823}
824
825
c2a04078 826static void mlme_event(struct wpa_driver_nl80211_data *drv,
da1fb17c 827 enum nl80211_commands cmd, struct nlattr *frame,
58f6fbe0
JM
828 struct nlattr *addr, struct nlattr *timed_out,
829 struct nlattr *freq, struct nlattr *ack,
830 struct nlattr *cookie)
c2a04078 831{
da1fb17c
JM
832 if (timed_out && addr) {
833 mlme_timeout_event(drv, cmd, addr);
834 return;
835 }
836
c2a04078
JM
837 if (frame == NULL) {
838 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
839 "data", cmd);
840 return;
841 }
842
843 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d", cmd);
844 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
845 nla_data(frame), nla_len(frame));
846
847 switch (cmd) {
848 case NL80211_CMD_AUTHENTICATE:
849 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
850 break;
851 case NL80211_CMD_ASSOCIATE:
852 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
853 break;
854 case NL80211_CMD_DEAUTHENTICATE:
0544b242
JM
855 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
856 nla_data(frame), nla_len(frame));
c2a04078
JM
857 break;
858 case NL80211_CMD_DISASSOCIATE:
0544b242
JM
859 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
860 nla_data(frame), nla_len(frame));
c2a04078 861 break;
bd94971e 862 case NL80211_CMD_FRAME:
5582a5d1 863 mlme_event_mgmt(drv, freq, nla_data(frame), nla_len(frame));
58f6fbe0 864 break;
bd94971e 865 case NL80211_CMD_FRAME_TX_STATUS:
58f6fbe0
JM
866 mlme_event_action_tx_status(drv, cookie, nla_data(frame),
867 nla_len(frame), ack);
868 break;
c2a04078
JM
869 default:
870 break;
871 }
872}
873
874
35583f3f
JM
875static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv,
876 struct nlattr *tb[])
877{
878 union wpa_event_data data;
879
880 wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
881 os_memset(&data, 0, sizeof(data));
882 if (tb[NL80211_ATTR_MAC]) {
883 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
884 nla_data(tb[NL80211_ATTR_MAC]),
885 nla_len(tb[NL80211_ATTR_MAC]));
ad1e68e6 886 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
35583f3f
JM
887 }
888 if (tb[NL80211_ATTR_KEY_SEQ]) {
889 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
890 nla_data(tb[NL80211_ATTR_KEY_SEQ]),
891 nla_len(tb[NL80211_ATTR_KEY_SEQ]));
892 }
893 if (tb[NL80211_ATTR_KEY_TYPE]) {
894 enum nl80211_key_type key_type =
895 nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
896 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
897 if (key_type == NL80211_KEYTYPE_PAIRWISE)
898 data.michael_mic_failure.unicast = 1;
899 } else
900 data.michael_mic_failure.unicast = 1;
901
902 if (tb[NL80211_ATTR_KEY_IDX]) {
903 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
904 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
905 }
906
907 wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
908}
909
910
5cc4d64b
JM
911static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
912 struct nlattr *tb[])
913{
914 if (tb[NL80211_ATTR_MAC] == NULL) {
915 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
916 "event");
917 return;
918 }
919 os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
920 drv->associated = 1;
921 wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
922 MAC2STR(drv->bssid));
923
924 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
925}
926
927
55777702
JM
928static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
929 int cancel_event, struct nlattr *tb[])
930{
931 unsigned int freq, chan_type, duration;
932 union wpa_event_data data;
933 u64 cookie;
934
935 if (tb[NL80211_ATTR_WIPHY_FREQ])
936 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
937 else
938 freq = 0;
939
940 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
941 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
942 else
943 chan_type = 0;
944
945 if (tb[NL80211_ATTR_DURATION])
946 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
947 else
948 duration = 0;
949
950 if (tb[NL80211_ATTR_COOKIE])
951 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
952 else
953 cookie = 0;
954
955 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
956 "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
957 cancel_event, freq, chan_type, duration,
958 (long long unsigned int) cookie,
959 cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
960
961 if (cookie != drv->remain_on_chan_cookie)
962 return; /* not for us */
963
964 drv->pending_remain_on_chan = !cancel_event;
965
966 os_memset(&data, 0, sizeof(data));
967 data.remain_on_channel.freq = freq;
968 data.remain_on_channel.duration = duration;
969 wpa_supplicant_event(drv->ctx, cancel_event ?
970 EVENT_CANCEL_REMAIN_ON_CHANNEL :
971 EVENT_REMAIN_ON_CHANNEL, &data);
972}
973
974
8d923a4a
JM
975static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
976 struct nlattr *tb[])
977{
978 union wpa_event_data event;
979 struct nlattr *nl;
980 int rem;
981 struct scan_info *info;
982#define MAX_REPORT_FREQS 50
983 int freqs[MAX_REPORT_FREQS];
984 int num_freqs = 0;
985
986 os_memset(&event, 0, sizeof(event));
987 info = &event.scan_info;
988 info->aborted = aborted;
989
990 if (tb[NL80211_ATTR_SCAN_SSIDS]) {
991 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
992 struct wpa_driver_scan_ssid *s =
993 &info->ssids[info->num_ssids];
994 s->ssid = nla_data(nl);
995 s->ssid_len = nla_len(nl);
996 info->num_ssids++;
997 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
998 break;
999 }
1000 }
1001 if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
1002 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
1003 {
1004 freqs[num_freqs] = nla_get_u32(nl);
1005 num_freqs++;
1006 if (num_freqs == MAX_REPORT_FREQS - 1)
1007 break;
1008 }
1009 info->freqs = freqs;
1010 info->num_freqs = num_freqs;
1011 }
1012 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
1013}
1014
1015
60a972a6
JM
1016static int get_link_signal(struct nl_msg *msg, void *arg)
1017{
1018 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1019 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1020 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
1021 static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
1022 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
1023 };
7ee35bf3
PS
1024 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
1025 static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
1026 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
1027 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
1028 [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
1029 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
1030 };
1031 struct signal_change *sig_change = arg;
60a972a6
JM
1032
1033 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1034 genlmsg_attrlen(gnlh, 0), NULL);
1035 if (!tb[NL80211_ATTR_STA_INFO] ||
1036 nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
1037 tb[NL80211_ATTR_STA_INFO], policy))
1038 return NL_SKIP;
1039 if (!sinfo[NL80211_STA_INFO_SIGNAL])
1040 return NL_SKIP;
1041
7ee35bf3
PS
1042 sig_change->current_signal =
1043 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
1044
1045 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
1046 if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
1047 sinfo[NL80211_STA_INFO_TX_BITRATE],
1048 rate_policy)) {
1049 sig_change->current_txrate = 0;
1050 } else {
1051 if (rinfo[NL80211_RATE_INFO_BITRATE]) {
1052 sig_change->current_txrate =
1053 nla_get_u16(rinfo[
1054 NL80211_RATE_INFO_BITRATE]) * 100;
1055 }
1056 }
1057 }
1058
60a972a6
JM
1059 return NL_SKIP;
1060}
1061
1062
1063static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
7ee35bf3 1064 struct signal_change *sig)
60a972a6
JM
1065{
1066 struct nl_msg *msg;
1067
7ee35bf3
PS
1068 sig->current_signal = -9999;
1069 sig->current_txrate = 0;
60a972a6
JM
1070
1071 msg = nlmsg_alloc();
1072 if (!msg)
1073 return -ENOMEM;
1074
1075 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1076 0, NL80211_CMD_GET_STATION, 0);
1077
1078 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1079 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
1080
1081 return send_and_recv_msgs(drv, msg, get_link_signal, sig);
1082 nla_put_failure:
1083 return -ENOBUFS;
1084}
1085
1086
7ee35bf3
PS
1087static int get_link_noise(struct nl_msg *msg, void *arg)
1088{
1089 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1090 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1091 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
1092 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
1093 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
1094 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
1095 };
1096 struct signal_change *sig_change = arg;
1097
1098 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1099 genlmsg_attrlen(gnlh, 0), NULL);
1100
1101 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
1102 wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
1103 return NL_SKIP;
1104 }
1105
1106 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
1107 tb[NL80211_ATTR_SURVEY_INFO],
1108 survey_policy)) {
1109 wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
1110 "attributes!");
1111 return NL_SKIP;
1112 }
1113
1114 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
1115 return NL_SKIP;
1116
1117 if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
1118 sig_change->frequency)
1119 return NL_SKIP;
1120
1121 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
1122 return NL_SKIP;
1123
1124 sig_change->current_noise =
1125 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
1126
1127 return NL_SKIP;
1128}
1129
1130
1131static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
1132 struct signal_change *sig_change)
1133{
1134 struct nl_msg *msg;
1135
1136 sig_change->current_noise = 9999;
1137 sig_change->frequency = drv->assoc_freq;
1138
1139 msg = nlmsg_alloc();
1140 if (!msg)
1141 return -ENOMEM;
1142
1143 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1144 NLM_F_DUMP, NL80211_CMD_GET_SURVEY, 0);
1145
1146 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1147
1148 return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
1149 nla_put_failure:
1150 return -ENOBUFS;
1151}
1152
1153
93910401
JM
1154static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
1155 struct nlattr *tb[])
1156{
1157 static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
1158 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
1159 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
1160 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
1161 };
1162 struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
1163 enum nl80211_cqm_rssi_threshold_event event;
b625473c 1164 union wpa_event_data ed;
7ee35bf3
PS
1165 struct signal_change sig;
1166 int res;
93910401
JM
1167
1168 if (tb[NL80211_ATTR_CQM] == NULL ||
1169 nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
1170 cqm_policy)) {
1171 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
1172 return;
1173 }
1174
1175 if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
1176 return;
1177 event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
b625473c
JM
1178
1179 os_memset(&ed, 0, sizeof(ed));
1180
93910401
JM
1181 if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
1182 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1183 "event: RSSI high");
b625473c 1184 ed.signal_change.above_threshold = 1;
93910401
JM
1185 } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
1186 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1187 "event: RSSI low");
b625473c
JM
1188 ed.signal_change.above_threshold = 0;
1189 } else
1190 return;
1191
60a972a6
JM
1192 res = nl80211_get_link_signal(drv, &sig);
1193 if (res == 0) {
7ee35bf3
PS
1194 ed.signal_change.current_signal = sig.current_signal;
1195 ed.signal_change.current_txrate = sig.current_txrate;
1196 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm txrate: %d",
1197 sig.current_signal, sig.current_txrate);
1198 }
1199
1200 res = nl80211_get_link_noise(drv, &sig);
1201 if (res == 0) {
1202 ed.signal_change.current_noise = sig.current_noise;
1203 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
1204 sig.current_noise);
60a972a6
JM
1205 }
1206
b625473c 1207 wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
93910401
JM
1208}
1209
1210
97865538
JM
1211static int process_event(struct nl_msg *msg, void *arg)
1212{
1213 struct wpa_driver_nl80211_data *drv = arg;
1214 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1215 struct nlattr *tb[NL80211_ATTR_MAX + 1];
0544b242 1216 union wpa_event_data data;
97865538
JM
1217
1218 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1219 genlmsg_attrlen(gnlh, 0), NULL);
1220
1221 if (tb[NL80211_ATTR_IFINDEX]) {
1222 int ifindex = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
97cfcf64 1223 if (ifindex != drv->ifindex && !have_ifidx(drv, ifindex)) {
97865538
JM
1224 wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d)"
1225 " for foreign interface (ifindex %d)",
1226 gnlh->cmd, ifindex);
1227 return NL_SKIP;
1228 }
1229 }
1230
ad1e68e6
JM
1231 if (drv->ap_scan_as_station &&
1232 (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
1233 gnlh->cmd == NL80211_CMD_SCAN_ABORTED)) {
a2e40bb6
FF
1234 wpa_driver_nl80211_set_mode(&drv->first_bss,
1235 IEEE80211_MODE_AP);
ad1e68e6
JM
1236 drv->ap_scan_as_station = 0;
1237 }
1238
97865538 1239 switch (gnlh->cmd) {
d942a79e
JM
1240 case NL80211_CMD_TRIGGER_SCAN:
1241 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger");
1242 break;
97865538
JM
1243 case NL80211_CMD_NEW_SCAN_RESULTS:
1244 wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
1245 drv->scan_complete_events = 1;
1246 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
1247 drv->ctx);
8d923a4a 1248 send_scan_event(drv, 0, tb);
97865538
JM
1249 break;
1250 case NL80211_CMD_SCAN_ABORTED:
1251 wpa_printf(MSG_DEBUG, "nl80211: Scan aborted");
1252 /*
1253 * Need to indicate that scan results are available in order
1254 * not to make wpa_supplicant stop its scanning.
1255 */
1256 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
1257 drv->ctx);
8d923a4a 1258 send_scan_event(drv, 1, tb);
97865538 1259 break;
c2a04078
JM
1260 case NL80211_CMD_AUTHENTICATE:
1261 case NL80211_CMD_ASSOCIATE:
1262 case NL80211_CMD_DEAUTHENTICATE:
1263 case NL80211_CMD_DISASSOCIATE:
bd94971e
JB
1264 case NL80211_CMD_FRAME:
1265 case NL80211_CMD_FRAME_TX_STATUS:
da1fb17c 1266 mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME],
58f6fbe0
JM
1267 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
1268 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
1269 tb[NL80211_ATTR_COOKIE]);
c2a04078 1270 break;
da72a1c1
ZY
1271 case NL80211_CMD_CONNECT:
1272 case NL80211_CMD_ROAM:
1273 mlme_event_connect(drv, gnlh->cmd,
1274 tb[NL80211_ATTR_STATUS_CODE],
1275 tb[NL80211_ATTR_MAC],
1276 tb[NL80211_ATTR_REQ_IE],
1277 tb[NL80211_ATTR_RESP_IE]);
1278 break;
1279 case NL80211_CMD_DISCONNECT:
7da2c527
JM
1280 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1281 /*
1282 * Avoid reporting two disassociation events that could
1283 * confuse the core code.
1284 */
1285 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1286 "event when using userspace SME");
1287 break;
1288 }
da72a1c1 1289 drv->associated = 0;
0544b242
JM
1290 os_memset(&data, 0, sizeof(data));
1291 if (tb[NL80211_ATTR_REASON_CODE])
1292 data.disassoc_info.reason_code =
1293 nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
1294 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
da72a1c1 1295 break;
35583f3f
JM
1296 case NL80211_CMD_MICHAEL_MIC_FAILURE:
1297 mlme_event_michael_mic_failure(drv, tb);
1298 break;
5cc4d64b
JM
1299 case NL80211_CMD_JOIN_IBSS:
1300 mlme_event_join_ibss(drv, tb);
1301 break;
55777702
JM
1302 case NL80211_CMD_REMAIN_ON_CHANNEL:
1303 mlme_event_remain_on_channel(drv, 0, tb);
1304 break;
1305 case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
1306 mlme_event_remain_on_channel(drv, 1, tb);
1307 break;
93910401
JM
1308 case NL80211_CMD_NOTIFY_CQM:
1309 nl80211_cqm_event(drv, tb);
1310 break;
33c5deb8
JM
1311 case NL80211_CMD_REG_CHANGE:
1312 wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
1313 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
1314 NULL);
1315 break;
1316 case NL80211_CMD_REG_BEACON_HINT:
1317 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
1318 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
1319 NULL);
1320 break;
97865538 1321 default:
c2a04078
JM
1322 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
1323 "(cmd=%d)", gnlh->cmd);
97865538
JM
1324 break;
1325 }
1326
1327 return NL_SKIP;
1328}
1329
1330
1331static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
5582a5d1 1332 void *handle)
97865538
JM
1333{
1334 struct nl_cb *cb;
1335 struct wpa_driver_nl80211_data *drv = eloop_ctx;
1336
1337 wpa_printf(MSG_DEBUG, "nl80211: Event message available");
1338
1339 cb = nl_cb_clone(drv->nl_cb);
1340 if (!cb)
1341 return;
1342 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
1343 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv);
5582a5d1 1344 nl_recvmsgs(handle, cb);
97865538
JM
1345 nl_cb_put(cb);
1346}
1347
1348
6d158490
LR
1349/**
1350 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
1351 * @priv: driver_nl80211 private data
1352 * @alpha2_arg: country to which to switch to
1353 * Returns: 0 on success, -1 on failure
1354 *
1355 * This asks nl80211 to set the regulatory domain for given
1356 * country ISO / IEC alpha2.
1357 */
1358static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
1359{
a2e40bb6
FF
1360 struct i802_bss *bss = priv;
1361 struct wpa_driver_nl80211_data *drv = bss->drv;
6d158490
LR
1362 char alpha2[3];
1363 struct nl_msg *msg;
1364
1365 msg = nlmsg_alloc();
1366 if (!msg)
e785c2ba 1367 return -ENOMEM;
6d158490
LR
1368
1369 alpha2[0] = alpha2_arg[0];
1370 alpha2[1] = alpha2_arg[1];
1371 alpha2[2] = '\0';
1372
1373 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1374 0, NL80211_CMD_REQ_SET_REG, 0);
1375
1376 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
1377 if (send_and_recv_msgs(drv, msg, NULL, NULL))
1378 return -EINVAL;
1379 return 0;
1380nla_put_failure:
1381 return -EINVAL;
1382}
1383
1384
bbaf0837 1385#ifndef HOSTAPD
80bc75f1
JM
1386struct wiphy_info_data {
1387 int max_scan_ssids;
1581b38b 1388 int ap_supported;
93d11400
ZY
1389 int auth_supported;
1390 int connect_supported;
80bc75f1
JM
1391};
1392
1393
1394static int wiphy_info_handler(struct nl_msg *msg, void *arg)
1395{
1396 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1397 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1398 struct wiphy_info_data *info = arg;
1399
1400 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1401 genlmsg_attrlen(gnlh, 0), NULL);
1402
1403 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
1404 info->max_scan_ssids =
1405 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
1406
1581b38b
JM
1407 if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
1408 struct nlattr *nl_mode;
1409 int i;
1410 nla_for_each_nested(nl_mode,
1411 tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
1412 if (nl_mode->nla_type == NL80211_IFTYPE_AP) {
1413 info->ap_supported = 1;
1414 break;
1415 }
1416 }
1417 }
1418
93d11400
ZY
1419 if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
1420 struct nlattr *nl_cmd;
1421 int i;
1422
1423 nla_for_each_nested(nl_cmd,
1424 tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
1425 u32 cmd = nla_get_u32(nl_cmd);
1426 if (cmd == NL80211_CMD_AUTHENTICATE)
1427 info->auth_supported = 1;
1428 else if (cmd == NL80211_CMD_CONNECT)
1429 info->connect_supported = 1;
1430 }
1431 }
1432
80bc75f1
JM
1433 return NL_SKIP;
1434}
1435
1436
1437static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
1438 struct wiphy_info_data *info)
1439{
1440 struct nl_msg *msg;
1441
1442 os_memset(info, 0, sizeof(*info));
1443 msg = nlmsg_alloc();
1444 if (!msg)
1445 return -1;
1446
1447 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1448 0, NL80211_CMD_GET_WIPHY, 0);
1449
a2e40bb6 1450 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->first_bss.ifindex);
80bc75f1
JM
1451
1452 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
1453 return 0;
1454 msg = NULL;
1455nla_put_failure:
1456 nlmsg_free(msg);
1457 return -1;
1458}
1459
1460
93d11400 1461static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
80bc75f1
JM
1462{
1463 struct wiphy_info_data info;
1464 if (wpa_driver_nl80211_get_info(drv, &info))
93d11400 1465 return -1;
80bc75f1 1466 drv->has_capability = 1;
1b2a72e8
JM
1467 /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
1468 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1469 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1470 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1471 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1472 drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 |
1473 WPA_DRIVER_CAPA_ENC_WEP104 |
1474 WPA_DRIVER_CAPA_ENC_TKIP |
1475 WPA_DRIVER_CAPA_ENC_CCMP;
291b6068
JM
1476 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
1477 WPA_DRIVER_AUTH_SHARED |
1478 WPA_DRIVER_AUTH_LEAP;
1b2a72e8 1479
80bc75f1 1480 drv->capa.max_scan_ssids = info.max_scan_ssids;
1581b38b
JM
1481 if (info.ap_supported)
1482 drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
93d11400
ZY
1483
1484 if (info.auth_supported)
1485 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
1486 else if (!info.connect_supported) {
1487 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
1488 "authentication/association or connect commands");
1489 return -1;
1490 }
1491
0194fedb 1492 drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
046b26a2 1493 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
814782b9 1494 drv->capa.max_remain_on_chan = 5000;
0194fedb 1495
93d11400 1496 return 0;
80bc75f1 1497}
bbaf0837 1498#endif /* HOSTAPD */
80bc75f1
JM
1499
1500
ba2d0d7d 1501static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv)
3f5285e8 1502{
9fff9fdc 1503 int ret;
3f5285e8 1504
9fff9fdc 1505 /* Initialize generic netlink and nl80211 */
3f5285e8
JM
1506
1507 drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
1508 if (drv->nl_cb == NULL) {
1509 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1510 "callbacks");
1511 goto err1;
1512 }
1513
a65a9aed 1514 drv->nl_handle = nl80211_handle_alloc(drv->nl_cb);
3f5285e8
JM
1515 if (drv->nl_handle == NULL) {
1516 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1517 "callbacks");
1518 goto err2;
1519 }
1520
a65a9aed 1521 drv->nl_handle_event = nl80211_handle_alloc(drv->nl_cb);
335ce76b
JM
1522 if (drv->nl_handle_event == NULL) {
1523 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1524 "callbacks (event)");
1525 goto err2b;
1526 }
1527
3f5285e8
JM
1528 if (genl_connect(drv->nl_handle)) {
1529 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
1530 "netlink");
1531 goto err3;
1532 }
1533
335ce76b
JM
1534 if (genl_connect(drv->nl_handle_event)) {
1535 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
1536 "netlink (event)");
1537 goto err3;
1538 }
1539
9fff9fdc
JM
1540#ifdef CONFIG_LIBNL20
1541 if (genl_ctrl_alloc_cache(drv->nl_handle, &drv->nl_cache) < 0) {
1542 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1543 "netlink cache");
1544 goto err3;
1545 }
335ce76b
JM
1546 if (genl_ctrl_alloc_cache(drv->nl_handle_event, &drv->nl_cache_event) <
1547 0) {
1548 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1549 "netlink cache (event)");
1550 goto err3b;
1551 }
9fff9fdc 1552#else /* CONFIG_LIBNL20 */
3f5285e8
JM
1553 drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);
1554 if (drv->nl_cache == NULL) {
1555 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1556 "netlink cache");
1557 goto err3;
1558 }
335ce76b
JM
1559 drv->nl_cache_event = genl_ctrl_alloc_cache(drv->nl_handle_event);
1560 if (drv->nl_cache_event == NULL) {
1561 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1562 "netlink cache (event)");
1563 goto err3b;
1564 }
9fff9fdc
JM
1565#endif /* CONFIG_LIBNL20 */
1566
3f5285e8
JM
1567 drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");
1568 if (drv->nl80211 == NULL) {
1569 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
1570 "found");
1571 goto err4;
1572 }
1573
97865538
JM
1574 ret = nl_get_multicast_id(drv, "nl80211", "scan");
1575 if (ret >= 0)
335ce76b 1576 ret = nl_socket_add_membership(drv->nl_handle_event, ret);
97865538
JM
1577 if (ret < 0) {
1578 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1579 "membership for scan events: %d (%s)",
1580 ret, strerror(-ret));
1581 goto err4;
1582 }
c2a04078
JM
1583
1584 ret = nl_get_multicast_id(drv, "nl80211", "mlme");
1585 if (ret >= 0)
335ce76b 1586 ret = nl_socket_add_membership(drv->nl_handle_event, ret);
c2a04078
JM
1587 if (ret < 0) {
1588 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1589 "membership for mlme events: %d (%s)",
1590 ret, strerror(-ret));
1591 goto err4;
1592 }
c2a04078 1593
33c5deb8
JM
1594 ret = nl_get_multicast_id(drv, "nl80211", "regulatory");
1595 if (ret >= 0)
1596 ret = nl_socket_add_membership(drv->nl_handle_event, ret);
1597 if (ret < 0) {
1598 wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
1599 "membership for regulatory events: %d (%s)",
1600 ret, strerror(-ret));
1601 /* Continue without regulatory events */
1602 }
1603
335ce76b 1604 eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle_event),
5582a5d1
JB
1605 wpa_driver_nl80211_event_receive, drv,
1606 drv->nl_handle_event);
97865538 1607
9fff9fdc
JM
1608 return 0;
1609
1610err4:
335ce76b
JM
1611 nl_cache_free(drv->nl_cache_event);
1612err3b:
9fff9fdc
JM
1613 nl_cache_free(drv->nl_cache);
1614err3:
a65a9aed 1615 nl80211_handle_destroy(drv->nl_handle_event);
335ce76b 1616err2b:
a65a9aed 1617 nl80211_handle_destroy(drv->nl_handle);
9fff9fdc
JM
1618err2:
1619 nl_cb_put(drv->nl_cb);
1620err1:
1621 return -1;
1622}
1623
1624
8401a6b0
JM
1625static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
1626{
8401a6b0 1627 wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
a63063b4
JM
1628 /*
1629 * This may be for any interface; use ifdown event to disable
1630 * interface.
1631 */
8401a6b0
JM
1632}
1633
1634
1635static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
1636{
1637 struct wpa_driver_nl80211_data *drv = ctx;
1638 wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
1639 if (linux_set_iface_flags(drv->ioctl_sock, drv->first_bss.ifname, 1)) {
1640 wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
1641 "after rfkill unblock");
1642 return;
1643 }
a63063b4 1644 /* rtnetlink ifup handler will report interface as enabled */
8401a6b0
JM
1645}
1646
1647
9fff9fdc
JM
1648/**
1649 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
1650 * @ctx: context to be used when calling wpa_supplicant functions,
1651 * e.g., wpa_supplicant_event()
1652 * @ifname: interface name, e.g., wlan0
1653 * Returns: Pointer to private data, %NULL on failure
1654 */
1655static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
1656{
9fff9fdc 1657 struct wpa_driver_nl80211_data *drv;
08063178 1658 struct netlink_config *cfg;
8401a6b0 1659 struct rfkill_config *rcfg;
a2e40bb6 1660 struct i802_bss *bss;
9fff9fdc
JM
1661
1662 drv = os_zalloc(sizeof(*drv));
1663 if (drv == NULL)
1664 return NULL;
1665 drv->ctx = ctx;
a2e40bb6
FF
1666 bss = &drv->first_bss;
1667 bss->drv = drv;
1668 os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
9fff9fdc
JM
1669 drv->monitor_ifidx = -1;
1670 drv->monitor_sock = -1;
bbaf0837 1671 drv->ioctl_sock = -1;
9fff9fdc 1672
ba2d0d7d 1673 if (wpa_driver_nl80211_init_nl(drv)) {
bbaf0837
JM
1674 os_free(drv);
1675 return NULL;
1676 }
9fff9fdc 1677
3f5285e8
JM
1678 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
1679 if (drv->ioctl_sock < 0) {
1680 perror("socket(PF_INET,SOCK_DGRAM)");
bbaf0837 1681 goto failed;
3f5285e8
JM
1682 }
1683
08063178
JM
1684 cfg = os_zalloc(sizeof(*cfg));
1685 if (cfg == NULL)
1686 goto failed;
1687 cfg->ctx = drv;
1688 cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
1689 cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
1690 drv->netlink = netlink_init(cfg);
1691 if (drv->netlink == NULL) {
1692 os_free(cfg);
1693 goto failed;
1694 }
8401a6b0
JM
1695
1696 rcfg = os_zalloc(sizeof(*rcfg));
1697 if (rcfg == NULL)
1698 goto failed;
1699 rcfg->ctx = drv;
1700 os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
1701 rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
1702 rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
1703 drv->rfkill = rfkill_init(rcfg);
52169389 1704 if (drv->rfkill == NULL) {
8401a6b0 1705 wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
52169389
JM
1706 os_free(rcfg);
1707 }
8401a6b0 1708
08063178 1709 if (wpa_driver_nl80211_finish_drv_init(drv))
bbaf0837 1710 goto failed;
7524cfb1 1711
a2e40bb6 1712 return bss;
7524cfb1 1713
bbaf0837 1714failed:
8401a6b0 1715 rfkill_deinit(drv->rfkill);
08063178 1716 netlink_deinit(drv->netlink);
bbaf0837
JM
1717 if (drv->ioctl_sock >= 0)
1718 close(drv->ioctl_sock);
1719
7524cfb1 1720 genl_family_put(drv->nl80211);
7524cfb1 1721 nl_cache_free(drv->nl_cache);
a65a9aed 1722 nl80211_handle_destroy(drv->nl_handle);
7524cfb1 1723 nl_cb_put(drv->nl_cb);
05ba8690 1724 eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle_event));
bbaf0837 1725
7524cfb1
JM
1726 os_free(drv);
1727 return NULL;
1728}
1729
1730
bd94971e 1731static int nl80211_register_frame(struct wpa_driver_nl80211_data *drv,
5582a5d1 1732 struct nl_handle *nl_handle,
bd94971e 1733 u16 type, const u8 *match, size_t match_len)
58f6fbe0
JM
1734{
1735 struct nl_msg *msg;
1736 int ret = -1;
1737
1738 msg = nlmsg_alloc();
1739 if (!msg)
1740 return -1;
1741
1742 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1743 NL80211_CMD_REGISTER_ACTION, 0);
1744
1745 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
bd94971e 1746 NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type);
58f6fbe0
JM
1747 NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
1748
5582a5d1 1749 ret = send_and_recv(drv, nl_handle, msg, NULL, NULL);
58f6fbe0
JM
1750 msg = NULL;
1751 if (ret) {
5582a5d1
JB
1752 wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
1753 "failed (type=%u): ret=%d (%s)",
1754 type, ret, strerror(-ret));
1755 wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
58f6fbe0
JM
1756 match, match_len);
1757 goto nla_put_failure;
1758 }
1759 ret = 0;
1760nla_put_failure:
1761 nlmsg_free(msg);
1762 return ret;
1763}
1764
1765
bd94971e
JB
1766static int nl80211_register_action_frame(struct wpa_driver_nl80211_data *drv,
1767 const u8 *match, size_t match_len)
1768{
1769 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
5582a5d1
JB
1770 return nl80211_register_frame(drv, drv->nl_handle_event,
1771 type, match, match_len);
bd94971e
JB
1772}
1773
1774
58f6fbe0
JM
1775static int nl80211_register_action_frames(struct wpa_driver_nl80211_data *drv)
1776{
046b26a2
JM
1777#ifdef CONFIG_P2P
1778 /* GAS Initial Request */
1779 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0a", 2) < 0)
1780 return -1;
1781 /* GAS Initial Response */
1782 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0b", 2) < 0)
1783 return -1;
18708aad
JM
1784 /* GAS Comeback Request */
1785 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0c", 2) < 0)
1786 return -1;
1787 /* GAS Comeback Response */
1788 if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0d", 2) < 0)
1789 return -1;
046b26a2
JM
1790 /* P2P Public Action */
1791 if (nl80211_register_action_frame(drv,
1792 (u8 *) "\x04\x09\x50\x6f\x9a\x09",
1793 6) < 0)
1794 return -1;
1795 /* P2P Action */
1796 if (nl80211_register_action_frame(drv,
1797 (u8 *) "\x7f\x50\x6f\x9a\x09",
1798 5) < 0)
1799 return -1;
1800#endif /* CONFIG_P2P */
1801
7b90c16a
JM
1802 /* FT Action frames */
1803 if (nl80211_register_action_frame(drv, (u8 *) "\x06", 1) < 0)
1804 return -1;
1805 else
1806 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
1807 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
1808
58f6fbe0
JM
1809 return 0;
1810}
1811
1812
8401a6b0
JM
1813static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
1814{
1815 wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
1816}
1817
1818
362f781e 1819static int
7524cfb1
JM
1820wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
1821{
a2e40bb6 1822 struct i802_bss *bss = &drv->first_bss;
8401a6b0 1823 int send_rfkill_event = 0;
a2e40bb6
FF
1824
1825 drv->ifindex = if_nametoindex(bss->ifname);
1826 drv->first_bss.ifindex = drv->ifindex;
a87c9d96 1827
bbaf0837 1828#ifndef HOSTAPD
a2e40bb6 1829 if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA) < 0) {
a87c9d96
JM
1830 wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
1831 "use managed mode");
1832 }
1833
a2e40bb6 1834 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1)) {
8401a6b0
JM
1835 if (rfkill_is_blocked(drv->rfkill)) {
1836 wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
1837 "interface '%s' due to rfkill",
1838 bss->ifname);
a63063b4 1839 drv->if_disabled = 1;
8401a6b0
JM
1840 send_rfkill_event = 1;
1841 } else {
1842 wpa_printf(MSG_ERROR, "nl80211: Could not set "
1843 "interface '%s' UP", bss->ifname);
1844 return -1;
1845 }
362f781e 1846 }
3f5285e8 1847
93d11400
ZY
1848 if (wpa_driver_nl80211_capa(drv))
1849 return -1;
80bc75f1 1850
08063178 1851 netlink_send_oper_ifla(drv->netlink, drv->ifindex,
e2d02c29 1852 1, IF_OPER_DORMANT);
bbaf0837 1853#endif /* HOSTAPD */
362f781e 1854
7b90c16a
JM
1855 if (nl80211_register_action_frames(drv) < 0) {
1856 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
1857 "frame processing - ignore for now");
1858 /*
1859 * Older kernel versions did not support this, so ignore the
1860 * error for now. Some functionality may not be available
1861 * because of this.
1862 */
1863 }
58f6fbe0 1864
8401a6b0
JM
1865 if (send_rfkill_event) {
1866 eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
1867 drv, drv->ctx);
1868 }
1869
362f781e 1870 return 0;
3f5285e8
JM
1871}
1872
1873
8a27af5c
JM
1874static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
1875{
1876 struct nl_msg *msg;
1877
1878 msg = nlmsg_alloc();
1879 if (!msg)
1880 return -ENOMEM;
1881
1882 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1883 0, NL80211_CMD_DEL_BEACON, 0);
1884 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1885
1886 return send_and_recv_msgs(drv, msg, NULL, NULL);
1887 nla_put_failure:
1888 return -ENOBUFS;
1889}
8a27af5c
JM
1890
1891
3f5285e8 1892/**
7e5ba1b9
JM
1893 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
1894 * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
3f5285e8
JM
1895 *
1896 * Shut down driver interface and processing of driver events. Free
1897 * private data buffer if one was allocated in wpa_driver_nl80211_init().
1898 */
7e5ba1b9 1899static void wpa_driver_nl80211_deinit(void *priv)
3f5285e8 1900{
a2e40bb6
FF
1901 struct i802_bss *bss = priv;
1902 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 1903
5582a5d1
JB
1904 if (drv->nl_handle_preq)
1905 wpa_driver_nl80211_probe_req_report(bss, 0);
94627f6c 1906 if (drv->added_if_into_bridge) {
a2e40bb6 1907 if (linux_br_del_if(drv->ioctl_sock, drv->brname, bss->ifname)
94627f6c
JM
1908 < 0)
1909 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
1910 "interface %s from bridge %s: %s",
a2e40bb6 1911 bss->ifname, drv->brname, strerror(errno));
94627f6c
JM
1912 }
1913 if (drv->added_bridge) {
1914 if (linux_br_del(drv->ioctl_sock, drv->brname) < 0)
1915 wpa_printf(MSG_INFO, "nl80211: Failed to remove "
1916 "bridge %s: %s",
1917 drv->brname, strerror(errno));
1918 }
1919
460456f8 1920 nl80211_remove_monitor_interface(drv);
8a27af5c
JM
1921
1922 if (drv->nlmode == NL80211_IFTYPE_AP)
1923 wpa_driver_nl80211_del_beacon(drv);
0915d02c 1924
bbaf0837
JM
1925#ifdef HOSTAPD
1926 if (drv->last_freq_ht) {
1927 /* Clear HT flags from the driver */
1928 struct hostapd_freq_params freq;
1929 os_memset(&freq, 0, sizeof(freq));
1930 freq.freq = drv->last_freq;
1931 i802_set_freq(priv, &freq);
1932 }
1933
bbaf0837
JM
1934 if (drv->eapol_sock >= 0) {
1935 eloop_unregister_read_sock(drv->eapol_sock);
1936 close(drv->eapol_sock);
1937 }
1938
1939 if (drv->if_indices != drv->default_if_indices)
1940 os_free(drv->if_indices);
1b648c7e 1941#endif /* HOSTAPD */
3f5285e8 1942
4e5cb1a3
JM
1943 if (drv->disable_11b_rates)
1944 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
1945
08063178
JM
1946 netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP);
1947 netlink_deinit(drv->netlink);
8401a6b0 1948 rfkill_deinit(drv->rfkill);
3f5285e8 1949
bbaf0837
JM
1950 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
1951
a2e40bb6
FF
1952 (void) linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
1953 wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA);
3f5285e8 1954
bbaf0837
JM
1955 if (drv->ioctl_sock >= 0)
1956 close(drv->ioctl_sock);
3f5285e8 1957
335ce76b 1958 eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle_event));
3f5285e8
JM
1959 genl_family_put(drv->nl80211);
1960 nl_cache_free(drv->nl_cache);
335ce76b 1961 nl_cache_free(drv->nl_cache_event);
a65a9aed
JB
1962 nl80211_handle_destroy(drv->nl_handle);
1963 nl80211_handle_destroy(drv->nl_handle_event);
3f5285e8
JM
1964 nl_cb_put(drv->nl_cb);
1965
3812464c
JM
1966 os_free(drv->filter_ssids);
1967
3f5285e8
JM
1968 os_free(drv);
1969}
1970
1971
1972/**
1973 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
ad1e68e6 1974 * @eloop_ctx: Driver private data
3f5285e8
JM
1975 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
1976 *
1977 * This function can be used as registered timeout when starting a scan to
1978 * generate a scan completed event if the driver does not report this.
1979 */
1980static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1981{
ad1e68e6
JM
1982 struct wpa_driver_nl80211_data *drv = eloop_ctx;
1983 if (drv->ap_scan_as_station) {
a2e40bb6
FF
1984 wpa_driver_nl80211_set_mode(&drv->first_bss,
1985 IEEE80211_MODE_AP);
ad1e68e6
JM
1986 drv->ap_scan_as_station = 0;
1987 }
3f5285e8
JM
1988 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
1989 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
1990}
1991
1992
1993/**
1994 * wpa_driver_nl80211_scan - Request the driver to initiate scan
ad1e68e6 1995 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
6a1063e0 1996 * @params: Scan parameters
3f5285e8
JM
1997 * Returns: 0 on success, -1 on failure
1998 */
6a1063e0
JM
1999static int wpa_driver_nl80211_scan(void *priv,
2000 struct wpa_driver_scan_params *params)
3f5285e8 2001{
a2e40bb6
FF
2002 struct i802_bss *bss = priv;
2003 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8 2004 int ret = 0, timeout;
d3a98225 2005 struct nl_msg *msg, *ssids, *freqs;
6a1063e0 2006 size_t i;
3f5285e8 2007
0e75527f
JM
2008 msg = nlmsg_alloc();
2009 ssids = nlmsg_alloc();
d3a98225
JM
2010 freqs = nlmsg_alloc();
2011 if (!msg || !ssids || !freqs) {
0e75527f
JM
2012 nlmsg_free(msg);
2013 nlmsg_free(ssids);
d3a98225 2014 nlmsg_free(freqs);
3f5285e8
JM
2015 return -1;
2016 }
2017
3812464c
JM
2018 os_free(drv->filter_ssids);
2019 drv->filter_ssids = params->filter_ssids;
2020 params->filter_ssids = NULL;
2021 drv->num_filter_ssids = params->num_filter_ssids;
2022
0e75527f
JM
2023 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
2024 NL80211_CMD_TRIGGER_SCAN, 0);
2025
2026 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3f5285e8 2027
6a1063e0 2028 for (i = 0; i < params->num_ssids; i++) {
9fad706c
JM
2029 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
2030 params->ssids[i].ssid,
2031 params->ssids[i].ssid_len);
6a1063e0
JM
2032 NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
2033 params->ssids[i].ssid);
3f5285e8 2034 }
6a1063e0
JM
2035 if (params->num_ssids)
2036 nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
3f5285e8 2037
d173df52 2038 if (params->extra_ies) {
9fad706c
JM
2039 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan extra IEs",
2040 params->extra_ies, params->extra_ies_len);
d173df52
JM
2041 NLA_PUT(msg, NL80211_ATTR_IE, params->extra_ies_len,
2042 params->extra_ies);
2043 }
2044
d3a98225 2045 if (params->freqs) {
9fad706c
JM
2046 for (i = 0; params->freqs[i]; i++) {
2047 wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
2048 "MHz", params->freqs[i]);
d3a98225 2049 NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
9fad706c 2050 }
d3a98225
JM
2051 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
2052 }
2053
0e75527f
JM
2054 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2055 msg = NULL;
2056 if (ret) {
2057 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
2058 "(%s)", ret, strerror(-ret));
ad1e68e6
JM
2059#ifdef HOSTAPD
2060 if (drv->nlmode == NL80211_IFTYPE_AP) {
2061 /*
2062 * mac80211 does not allow scan requests in AP mode, so
2063 * try to do this in station mode.
2064 */
a2e40bb6 2065 if (wpa_driver_nl80211_set_mode(bss,
ad1e68e6
JM
2066 IEEE80211_MODE_INFRA))
2067 goto nla_put_failure;
2068
2069 if (wpa_driver_nl80211_scan(drv, params)) {
a2e40bb6 2070 wpa_driver_nl80211_set_mode(bss,
ad1e68e6
JM
2071 IEEE80211_MODE_AP);
2072 goto nla_put_failure;
2073 }
2074
2075 /* Restore AP mode when processing scan results */
2076 drv->ap_scan_as_station = 1;
2077 ret = 0;
2078 } else
2079 goto nla_put_failure;
2080#else /* HOSTAPD */
0e75527f 2081 goto nla_put_failure;
ad1e68e6 2082#endif /* HOSTAPD */
3f5285e8
JM
2083 }
2084
2085 /* Not all drivers generate "scan completed" wireless event, so try to
2086 * read results after a timeout. */
0e75527f 2087 timeout = 10;
3f5285e8
JM
2088 if (drv->scan_complete_events) {
2089 /*
d173df52
JM
2090 * The driver seems to deliver events to notify when scan is
2091 * complete, so use longer timeout to avoid race conditions
2092 * with scanning and following association request.
3f5285e8
JM
2093 */
2094 timeout = 30;
2095 }
2096 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
2097 "seconds", ret, timeout);
2098 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
0e75527f
JM
2099 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
2100 drv, drv->ctx);
3f5285e8 2101
0e75527f
JM
2102nla_put_failure:
2103 nlmsg_free(ssids);
2104 nlmsg_free(msg);
d3a98225 2105 nlmsg_free(freqs);
3f5285e8
JM
2106 return ret;
2107}
2108
2109
3812464c
JM
2110static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
2111{
2112 const u8 *end, *pos;
2113
2114 if (ies == NULL)
2115 return NULL;
2116
2117 pos = ies;
2118 end = ies + ies_len;
2119
2120 while (pos + 1 < end) {
2121 if (pos + 2 + pos[1] > end)
2122 break;
2123 if (pos[0] == ie)
2124 return pos;
2125 pos += 2 + pos[1];
2126 }
2127
2128 return NULL;
2129}
2130
2131
2132static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
2133 const u8 *ie, size_t ie_len)
2134{
2135 const u8 *ssid;
2136 size_t i;
2137
2138 if (drv->filter_ssids == NULL)
2139 return 0;
2140
2141 ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
2142 if (ssid == NULL)
2143 return 1;
2144
2145 for (i = 0; i < drv->num_filter_ssids; i++) {
2146 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
2147 os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
2148 0)
2149 return 0;
2150 }
2151
2152 return 1;
2153}
2154
2155
2156struct nl80211_bss_info_arg {
2157 struct wpa_driver_nl80211_data *drv;
2158 struct wpa_scan_results *res;
2159};
2160
b3db1e1c 2161static int bss_info_handler(struct nl_msg *msg, void *arg)
3f5285e8 2162{
b3db1e1c
JM
2163 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2164 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2165 struct nlattr *bss[NL80211_BSS_MAX + 1];
2166 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
2167 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
2168 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
2169 [NL80211_BSS_TSF] = { .type = NLA_U64 },
2170 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
2171 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
2172 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
2173 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
2174 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
e6b8efeb 2175 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
b3ad11bb 2176 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
8c090654 2177 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
b3db1e1c 2178 };
3812464c
JM
2179 struct nl80211_bss_info_arg *_arg = arg;
2180 struct wpa_scan_results *res = _arg->res;
3f5285e8
JM
2181 struct wpa_scan_res **tmp;
2182 struct wpa_scan_res *r;
8c090654
JM
2183 const u8 *ie, *beacon_ie;
2184 size_t ie_len, beacon_ie_len;
2185 u8 *pos;
3f5285e8 2186
b3db1e1c
JM
2187 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2188 genlmsg_attrlen(gnlh, 0), NULL);
2189 if (!tb[NL80211_ATTR_BSS])
2190 return NL_SKIP;
2191 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
2192 bss_policy))
2193 return NL_SKIP;
2194 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
2195 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
2196 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
2197 } else {
2198 ie = NULL;
2199 ie_len = 0;
2200 }
8c090654
JM
2201 if (bss[NL80211_BSS_BEACON_IES]) {
2202 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
2203 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
2204 } else {
2205 beacon_ie = NULL;
2206 beacon_ie_len = 0;
2207 }
3f5285e8 2208
3812464c
JM
2209 if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
2210 ie ? ie_len : beacon_ie_len))
2211 return NL_SKIP;
2212
8c090654 2213 r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
3f5285e8 2214 if (r == NULL)
b3db1e1c
JM
2215 return NL_SKIP;
2216 if (bss[NL80211_BSS_BSSID])
2217 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
2218 ETH_ALEN);
2219 if (bss[NL80211_BSS_FREQUENCY])
2220 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
2221 if (bss[NL80211_BSS_BEACON_INTERVAL])
2222 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
2223 if (bss[NL80211_BSS_CAPABILITY])
2224 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
7c2849d2
JM
2225 r->flags |= WPA_SCAN_NOISE_INVALID;
2226 if (bss[NL80211_BSS_SIGNAL_MBM]) {
b3db1e1c 2227 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
7c2849d2
JM
2228 r->level /= 100; /* mBm to dBm */
2229 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
2230 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
2231 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
2232 r->flags |= WPA_SCAN_LEVEL_INVALID;
2233 } else
2234 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
b3db1e1c
JM
2235 if (bss[NL80211_BSS_TSF])
2236 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
b3ad11bb
JM
2237 if (bss[NL80211_BSS_SEEN_MS_AGO])
2238 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
b3db1e1c 2239 r->ie_len = ie_len;
8c090654
JM
2240 pos = (u8 *) (r + 1);
2241 if (ie) {
2242 os_memcpy(pos, ie, ie_len);
2243 pos += ie_len;
2244 }
2245 r->beacon_ie_len = beacon_ie_len;
2246 if (beacon_ie)
2247 os_memcpy(pos, beacon_ie, beacon_ie_len);
3f5285e8 2248
e6b8efeb
JM
2249 if (bss[NL80211_BSS_STATUS]) {
2250 enum nl80211_bss_status status;
2251 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
2252 switch (status) {
2253 case NL80211_BSS_STATUS_AUTHENTICATED:
2254 r->flags |= WPA_SCAN_AUTHENTICATED;
2255 break;
2256 case NL80211_BSS_STATUS_ASSOCIATED:
2257 r->flags |= WPA_SCAN_ASSOCIATED;
2258 break;
2259 default:
2260 break;
2261 }
2262 }
2263
3f5285e8
JM
2264 tmp = os_realloc(res->res,
2265 (res->num + 1) * sizeof(struct wpa_scan_res *));
2266 if (tmp == NULL) {
2267 os_free(r);
b3db1e1c 2268 return NL_SKIP;
3f5285e8
JM
2269 }
2270 tmp[res->num++] = r;
2271 res->res = tmp;
b3db1e1c
JM
2272
2273 return NL_SKIP;
3f5285e8 2274}
b3db1e1c 2275
3f5285e8 2276
d72aad94
JM
2277static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
2278 const u8 *addr)
2279{
2280 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
2281 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
582507be 2282 "mismatch (" MACSTR ")", MAC2STR(addr));
d72aad94
JM
2283 wpa_driver_nl80211_mlme(drv, addr,
2284 NL80211_CMD_DEAUTHENTICATE,
77339912 2285 WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
d72aad94
JM
2286 }
2287}
2288
2289
e6b8efeb
JM
2290static void wpa_driver_nl80211_check_bss_status(
2291 struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
2292{
2293 size_t i;
2294
2295 for (i = 0; i < res->num; i++) {
2296 struct wpa_scan_res *r = res->res[i];
2297 if (r->flags & WPA_SCAN_AUTHENTICATED) {
2298 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
2299 "indicates BSS status with " MACSTR
2300 " as authenticated",
2301 MAC2STR(r->bssid));
2302 if (drv->nlmode == NL80211_IFTYPE_STATION &&
2303 os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
2304 os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
2305 0) {
2306 wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
2307 " in local state (auth=" MACSTR
2308 " assoc=" MACSTR ")",
2309 MAC2STR(drv->auth_bssid),
2310 MAC2STR(drv->bssid));
582507be 2311 clear_state_mismatch(drv, r->bssid);
e6b8efeb
JM
2312 }
2313 }
2314
2315 if (r->flags & WPA_SCAN_ASSOCIATED) {
2316 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
2317 "indicate BSS status with " MACSTR
2318 " as associated",
2319 MAC2STR(r->bssid));
2320 if (drv->nlmode == NL80211_IFTYPE_STATION &&
2321 !drv->associated) {
2322 wpa_printf(MSG_DEBUG, "nl80211: Local state "
2323 "(not associated) does not match "
2324 "with BSS state");
d72aad94 2325 clear_state_mismatch(drv, r->bssid);
e6b8efeb
JM
2326 } else if (drv->nlmode == NL80211_IFTYPE_STATION &&
2327 os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
2328 0) {
2329 wpa_printf(MSG_DEBUG, "nl80211: Local state "
2330 "(associated with " MACSTR ") does "
2331 "not match with BSS state",
d72aad94
JM
2332 MAC2STR(drv->bssid));
2333 clear_state_mismatch(drv, r->bssid);
2334 clear_state_mismatch(drv, drv->bssid);
e6b8efeb
JM
2335 }
2336 }
2337 }
2338}
2339
2340
d1f9c410
JM
2341static void wpa_scan_results_free(struct wpa_scan_results *res)
2342{
2343 size_t i;
2344
2345 if (res == NULL)
2346 return;
2347
2348 for (i = 0; i < res->num; i++)
2349 os_free(res->res[i]);
2350 os_free(res->res);
2351 os_free(res);
2352}
2353
2354
7e5ba1b9 2355static struct wpa_scan_results *
8856462d 2356nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
3f5285e8 2357{
b3db1e1c 2358 struct nl_msg *msg;
3f5285e8 2359 struct wpa_scan_results *res;
b3db1e1c 2360 int ret;
3812464c 2361 struct nl80211_bss_info_arg arg;
3f5285e8
JM
2362
2363 res = os_zalloc(sizeof(*res));
b3db1e1c 2364 if (res == NULL)
8e2c104f 2365 return NULL;
b3db1e1c
JM
2366 msg = nlmsg_alloc();
2367 if (!msg)
2368 goto nla_put_failure;
3f5285e8 2369
b3db1e1c
JM
2370 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP,
2371 NL80211_CMD_GET_SCAN, 0);
2372 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3f5285e8 2373
3812464c
JM
2374 arg.drv = drv;
2375 arg.res = res;
2376 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
b3db1e1c
JM
2377 msg = NULL;
2378 if (ret == 0) {
2379 wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)",
2380 (unsigned long) res->num);
2381 return res;
3f5285e8 2382 }
b3db1e1c
JM
2383 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
2384 "(%s)", ret, strerror(-ret));
2385nla_put_failure:
2386 nlmsg_free(msg);
2387 wpa_scan_results_free(res);
2388 return NULL;
3f5285e8
JM
2389}
2390
2391
8856462d
JM
2392/**
2393 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
2394 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
2395 * Returns: Scan results on success, -1 on failure
2396 */
2397static struct wpa_scan_results *
2398wpa_driver_nl80211_get_scan_results(void *priv)
2399{
a2e40bb6
FF
2400 struct i802_bss *bss = priv;
2401 struct wpa_driver_nl80211_data *drv = bss->drv;
8856462d
JM
2402 struct wpa_scan_results *res;
2403
2404 res = nl80211_get_scan_results(drv);
2405 if (res)
2406 wpa_driver_nl80211_check_bss_status(drv, res);
2407 return res;
2408}
2409
2410
2411static void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
2412{
2413 struct wpa_scan_results *res;
2414 size_t i;
2415
2416 res = nl80211_get_scan_results(drv);
2417 if (res == NULL) {
2418 wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
2419 return;
2420 }
2421
2422 wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
2423 for (i = 0; i < res->num; i++) {
2424 struct wpa_scan_res *r = res->res[i];
2425 wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s%s",
2426 (int) i, (int) res->num, MAC2STR(r->bssid),
2427 r->flags & WPA_SCAN_AUTHENTICATED ? " [auth]" : "",
2428 r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
2429 }
2430
2431 wpa_scan_results_free(res);
2432}
2433
2434
642187d6 2435static int wpa_driver_nl80211_set_key(const char *ifname, void *priv,
71934751
JM
2436 enum wpa_alg alg, const u8 *addr,
2437 int key_idx, int set_tx,
642187d6
JM
2438 const u8 *seq, size_t seq_len,
2439 const u8 *key, size_t key_len)
3f5285e8 2440{
a2e40bb6
FF
2441 struct i802_bss *bss = priv;
2442 struct wpa_driver_nl80211_data *drv = bss->drv;
642187d6 2443 int ifindex = if_nametoindex(ifname);
3f5285e8 2444 struct nl_msg *msg;
1ad1cdc2 2445 int ret;
3f5285e8 2446
1ad1cdc2
JM
2447 wpa_printf(MSG_DEBUG, "%s: ifindex=%d alg=%d addr=%p key_idx=%d "
2448 "set_tx=%d seq_len=%lu key_len=%lu",
2449 __func__, ifindex, alg, addr, key_idx, set_tx,
3f5285e8
JM
2450 (unsigned long) seq_len, (unsigned long) key_len);
2451
2452 msg = nlmsg_alloc();
1ad1cdc2
JM
2453 if (!msg)
2454 return -ENOMEM;
3f5285e8
JM
2455
2456 if (alg == WPA_ALG_NONE) {
1ad1cdc2
JM
2457 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2458 0, NL80211_CMD_DEL_KEY, 0);
3f5285e8 2459 } else {
1ad1cdc2
JM
2460 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2461 0, NL80211_CMD_NEW_KEY, 0);
3f5285e8 2462 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
d723bab4
JM
2463 switch (alg) {
2464 case WPA_ALG_WEP:
2465 if (key_len == 5)
2466 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
2467 WLAN_CIPHER_SUITE_WEP40);
2468 else
2469 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
2470 WLAN_CIPHER_SUITE_WEP104);
2471 break;
2472 case WPA_ALG_TKIP:
2473 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
2474 WLAN_CIPHER_SUITE_TKIP);
2475 break;
2476 case WPA_ALG_CCMP:
2477 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
2478 WLAN_CIPHER_SUITE_CCMP);
2479 break;
2480 case WPA_ALG_IGTK:
2481 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
2482 WLAN_CIPHER_SUITE_AES_CMAC);
2483 break;
2484 default:
2485 wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
2486 "algorithm %d", __func__, alg);
3f5285e8
JM
2487 nlmsg_free(msg);
2488 return -1;
2489 }
2490 }
2491
849ef835 2492 if (seq && seq_len)
1ad1cdc2
JM
2493 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
2494
3f5285e8
JM
2495 if (addr && os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
2496 {
2497 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
2498 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
2499 }
2500 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1ad1cdc2 2501 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
3f5285e8 2502
1ad1cdc2 2503 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
15664ad0 2504 if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
1ad1cdc2
JM
2505 ret = 0;
2506 if (ret)
2507 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
2508 ret, strerror(-ret));
3f5285e8 2509
1ad1cdc2
JM
2510 /*
2511 * If we failed or don't need to set the default TX key (below),
2512 * we're done here.
2513 */
2514 if (ret || !set_tx || alg == WPA_ALG_NONE)
2515 return ret;
de12717a 2516#ifdef HOSTAPD
1ad1cdc2
JM
2517 if (addr)
2518 return ret;
de12717a
JM
2519#else /* HOSTAPD */
2520 if (drv->nlmode == NL80211_IFTYPE_AP && addr)
2521 return ret;
1ad1cdc2 2522#endif /* HOSTAPD */
3f5285e8 2523
1ad1cdc2
JM
2524 msg = nlmsg_alloc();
2525 if (!msg)
2526 return -ENOMEM;
3f5285e8 2527
1ad1cdc2
JM
2528 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2529 0, NL80211_CMD_SET_KEY, 0);
2530 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
2531 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
2532 if (alg == WPA_ALG_IGTK)
2533 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
2534 else
2535 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
3f5285e8 2536
1ad1cdc2
JM
2537 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2538 if (ret == -ENOENT)
2539 ret = 0;
2540 if (ret)
2541 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
2542 "err=%d %s)", ret, strerror(-ret));
2543 return ret;
3f5285e8
JM
2544
2545nla_put_failure:
6241fcb1 2546 return -ENOBUFS;
3f5285e8
JM
2547}
2548
2549
71934751 2550static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
0194fedb
JB
2551 int key_idx, int defkey,
2552 const u8 *seq, size_t seq_len,
2553 const u8 *key, size_t key_len)
2554{
2555 struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
2556 if (!key_attr)
2557 return -1;
2558
2559 if (defkey && alg == WPA_ALG_IGTK)
2560 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
2561 else if (defkey)
2562 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
2563
2564 NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
2565
d723bab4
JM
2566 switch (alg) {
2567 case WPA_ALG_WEP:
2568 if (key_len == 5)
2aa5f847
JM
2569 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
2570 WLAN_CIPHER_SUITE_WEP40);
d723bab4 2571 else
2aa5f847
JM
2572 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
2573 WLAN_CIPHER_SUITE_WEP104);
d723bab4
JM
2574 break;
2575 case WPA_ALG_TKIP:
2aa5f847 2576 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_TKIP);
d723bab4
JM
2577 break;
2578 case WPA_ALG_CCMP:
2aa5f847 2579 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_CCMP);
d723bab4
JM
2580 break;
2581 case WPA_ALG_IGTK:
2aa5f847
JM
2582 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
2583 WLAN_CIPHER_SUITE_AES_CMAC);
d723bab4
JM
2584 break;
2585 default:
2586 wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
2587 "algorithm %d", __func__, alg);
0194fedb 2588 return -1;
d723bab4 2589 }
0194fedb
JB
2590
2591 if (seq && seq_len)
2592 NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
2593
2594 NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
2595
2596 nla_nest_end(msg, key_attr);
2597
2598 return 0;
2599 nla_put_failure:
2600 return -1;
2601}
2602
c811d5bc 2603
cfaab580
ZY
2604static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
2605 struct nl_msg *msg)
2606{
2607 int i, privacy = 0;
2608 struct nlattr *nl_keys, *nl_key;
2609
2610 for (i = 0; i < 4; i++) {
2611 if (!params->wep_key[i])
2612 continue;
2613 privacy = 1;
2614 break;
2615 }
ce04af5a
JM
2616 if (params->wps == WPS_MODE_PRIVACY)
2617 privacy = 1;
2618 if (params->pairwise_suite &&
2619 params->pairwise_suite != WPA_CIPHER_NONE)
2620 privacy = 1;
2621
cfaab580
ZY
2622 if (!privacy)
2623 return 0;
2624
2625 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
2626
2627 nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
2628 if (!nl_keys)
2629 goto nla_put_failure;
2630
2631 for (i = 0; i < 4; i++) {
2632 if (!params->wep_key[i])
2633 continue;
2634
2635 nl_key = nla_nest_start(msg, i);
2636 if (!nl_key)
2637 goto nla_put_failure;
2638
2639 NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
2640 params->wep_key[i]);
2641 if (params->wep_key_len[i] == 5)
2642 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
2643 WLAN_CIPHER_SUITE_WEP40);
2644 else
2645 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
2646 WLAN_CIPHER_SUITE_WEP104);
2647
2648 NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
2649
2650 if (i == params->wep_tx_keyidx)
2651 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
2652
2653 nla_nest_end(msg, nl_key);
2654 }
2655 nla_nest_end(msg, nl_keys);
2656
2657 return 0;
2658
2659nla_put_failure:
2660 return -ENOBUFS;
2661}
2662
2663
c2a04078 2664static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
77339912
JM
2665 const u8 *addr, int cmd, u16 reason_code,
2666 int local_state_change)
c2a04078
JM
2667{
2668 int ret = -1;
2669 struct nl_msg *msg;
2670
2671 msg = nlmsg_alloc();
2672 if (!msg)
2673 return -1;
2674
2675 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, cmd, 0);
2676
2677 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2678 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
2679 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
77339912
JM
2680 if (local_state_change)
2681 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
c2a04078
JM
2682
2683 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2684 msg = NULL;
2685 if (ret) {
2686 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
2687 "(%s)", ret, strerror(-ret));
2688 goto nla_put_failure;
2689 }
2690 ret = 0;
2691
2692nla_put_failure:
2693 nlmsg_free(msg);
2694 return ret;
2695}
3f5285e8
JM
2696
2697
cfaab580
ZY
2698static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
2699 const u8 *addr, int reason_code)
2700{
2e75a2b3
JM
2701 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
2702 __func__, MAC2STR(addr), reason_code);
cfaab580
ZY
2703 drv->associated = 0;
2704 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISCONNECT,
77339912 2705 reason_code, 0);
cfaab580
ZY
2706}
2707
2708
3f5285e8 2709static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,
c2a04078 2710 int reason_code)
3f5285e8 2711{
a2e40bb6
FF
2712 struct i802_bss *bss = priv;
2713 struct wpa_driver_nl80211_data *drv = bss->drv;
cfaab580
ZY
2714 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
2715 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
2e75a2b3
JM
2716 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
2717 __func__, MAC2STR(addr), reason_code);
13405f35 2718 drv->associated = 0;
c2a04078 2719 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
77339912 2720 reason_code, 0);
3f5285e8
JM
2721}
2722
2723
2724static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,
c2a04078 2725 int reason_code)
3f5285e8 2726{
a2e40bb6
FF
2727 struct i802_bss *bss = priv;
2728 struct wpa_driver_nl80211_data *drv = bss->drv;
cfaab580
ZY
2729 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
2730 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
c2a04078 2731 wpa_printf(MSG_DEBUG, "%s", __func__);
13405f35 2732 drv->associated = 0;
c2a04078 2733 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISASSOCIATE,
77339912 2734 reason_code, 0);
3f5285e8
JM
2735}
2736
2737
c2a04078
JM
2738static int wpa_driver_nl80211_authenticate(
2739 void *priv, struct wpa_driver_auth_params *params)
2740{
a2e40bb6
FF
2741 struct i802_bss *bss = priv;
2742 struct wpa_driver_nl80211_data *drv = bss->drv;
a0b2f99b 2743 int ret = -1, i;
c2a04078
JM
2744 struct nl_msg *msg;
2745 enum nl80211_auth_type type;
6d6f4bb8 2746 int count = 0;
c2a04078
JM
2747
2748 drv->associated = 0;
e6b8efeb 2749 os_memset(drv->auth_bssid, 0, ETH_ALEN);
af473088
JM
2750 /* FIX: IBSS mode */
2751 if (drv->nlmode != NL80211_IFTYPE_STATION)
2752 wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
c2a04078 2753
a2e40bb6 2754 if (wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA) < 0)
4a867032
JM
2755 return -1;
2756
6d6f4bb8 2757retry:
c2a04078
JM
2758 msg = nlmsg_alloc();
2759 if (!msg)
2760 return -1;
2761
2762 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
2763 drv->ifindex);
a0b2f99b 2764
0194fedb
JB
2765 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
2766 NL80211_CMD_AUTHENTICATE, 0);
2767
a0b2f99b
JM
2768 for (i = 0; i < 4; i++) {
2769 if (!params->wep_key[i])
2770 continue;
2ea2fcc7
HS
2771 wpa_driver_nl80211_set_key(bss->ifname, priv, WPA_ALG_WEP,
2772 NULL, i,
a0b2f99b
JM
2773 i == params->wep_tx_keyidx, NULL, 0,
2774 params->wep_key[i],
2775 params->wep_key_len[i]);
0194fedb
JB
2776 if (params->wep_tx_keyidx != i)
2777 continue;
2778 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
2779 params->wep_key[i], params->wep_key_len[i])) {
2780 nlmsg_free(msg);
2781 return -1;
2782 }
a0b2f99b
JM
2783 }
2784
c2a04078
JM
2785 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2786 if (params->bssid) {
2787 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
2788 MAC2STR(params->bssid));
2789 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
2790 }
2791 if (params->freq) {
2792 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
2793 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
2794 }
2795 if (params->ssid) {
2796 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
2797 params->ssid, params->ssid_len);
2798 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
2799 params->ssid);
2800 }
2801 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
2802 if (params->ie)
2803 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
abd9fafa 2804 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
c2a04078 2805 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
abd9fafa 2806 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
c2a04078 2807 type = NL80211_AUTHTYPE_SHARED_KEY;
abd9fafa 2808 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
c2a04078 2809 type = NL80211_AUTHTYPE_NETWORK_EAP;
abd9fafa 2810 else if (params->auth_alg & WPA_AUTH_ALG_FT)
c2a04078
JM
2811 type = NL80211_AUTHTYPE_FT;
2812 else
2813 goto nla_put_failure;
2814 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
2815 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
77339912
JM
2816 if (params->local_state_change) {
2817 wpa_printf(MSG_DEBUG, " * Local state change only");
2818 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
2819 }
c2a04078
JM
2820
2821 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2822 msg = NULL;
2823 if (ret) {
2824 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
2825 "(%s)", ret, strerror(-ret));
6d6f4bb8 2826 count++;
77339912
JM
2827 if (ret == -EALREADY && count == 1 && params->bssid &&
2828 !params->local_state_change) {
6d6f4bb8
JM
2829 /*
2830 * mac80211 does not currently accept new
2831 * authentication if we are already authenticated. As a
2832 * workaround, force deauthentication and try again.
2833 */
2834 wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
2835 "after forced deauthentication");
2836 wpa_driver_nl80211_deauthenticate(
5205c4f9 2837 bss, params->bssid,
6d6f4bb8
JM
2838 WLAN_REASON_PREV_AUTH_NOT_VALID);
2839 nlmsg_free(msg);
2840 goto retry;
2841 }
c2a04078
JM
2842 goto nla_put_failure;
2843 }
2844 ret = 0;
2845 wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
2846 "successfully");
2847
2848nla_put_failure:
2849 nlmsg_free(msg);
2850 return ret;
2851}
2852
2853
282d5590
JM
2854struct phy_info_arg {
2855 u16 *num_modes;
2856 struct hostapd_hw_modes *modes;
2857};
2858
2859static int phy_info_handler(struct nl_msg *msg, void *arg)
2860{
2861 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
2862 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2863 struct phy_info_arg *phy_info = arg;
2864
2865 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
2866
2867 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
2868 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
2869 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
2870 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
2871 [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
2872 [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },
2873 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
2874 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
2875 };
2876
2877 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
2878 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
2879 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
2880 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG },
2881 };
2882
2883 struct nlattr *nl_band;
2884 struct nlattr *nl_freq;
2885 struct nlattr *nl_rate;
2886 int rem_band, rem_freq, rem_rate;
2887 struct hostapd_hw_modes *mode;
2888 int idx, mode_is_set;
2889
2890 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2891 genlmsg_attrlen(gnlh, 0), NULL);
2892
2893 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
2894 return NL_SKIP;
2895
2896 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) {
e62fb0a0 2897 mode = os_realloc(phy_info->modes, (*phy_info->num_modes + 1) * sizeof(*mode));
282d5590
JM
2898 if (!mode)
2899 return NL_SKIP;
2900 phy_info->modes = mode;
2901
2902 mode_is_set = 0;
2903
2904 mode = &phy_info->modes[*(phy_info->num_modes)];
2905 memset(mode, 0, sizeof(*mode));
2906 *(phy_info->num_modes) += 1;
2907
2908 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
2909 nla_len(nl_band), NULL);
2910
2911 if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
2912 mode->ht_capab = nla_get_u16(
2913 tb_band[NL80211_BAND_ATTR_HT_CAPA]);
2914 }
2915
be8eb8ab
JM
2916 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) {
2917 mode->a_mpdu_params |= nla_get_u8(
2918 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) &
2919 0x03;
2920 }
2921
2922 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) {
2923 mode->a_mpdu_params |= nla_get_u8(
2924 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) <<
2925 2;
2926 }
2927
08eb154d
JM
2928 if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] &&
2929 nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET])) {
2930 u8 *mcs;
2931 mcs = nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
2932 os_memcpy(mode->mcs_set, mcs, 16);
2933 }
2934
282d5590
JM
2935 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
2936 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
2937 nla_len(nl_freq), freq_policy);
2938 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
2939 continue;
2940 mode->num_channels++;
2941 }
2942
e62fb0a0 2943 mode->channels = os_zalloc(mode->num_channels * sizeof(struct hostapd_channel_data));
282d5590
JM
2944 if (!mode->channels)
2945 return NL_SKIP;
2946
2947 idx = 0;
2948
2949 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
2950 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
2951 nla_len(nl_freq), freq_policy);
2952 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
2953 continue;
2954
2955 mode->channels[idx].freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
2956 mode->channels[idx].flag = 0;
2957
2958 if (!mode_is_set) {
2959 /* crude heuristic */
2960 if (mode->channels[idx].freq < 4000)
2961 mode->mode = HOSTAPD_MODE_IEEE80211B;
2962 else
2963 mode->mode = HOSTAPD_MODE_IEEE80211A;
2964 mode_is_set = 1;
2965 }
2966
2967 /* crude heuristic */
2968 if (mode->channels[idx].freq < 4000)
5a0ffb5f 2969 if (mode->channels[idx].freq == 2484)
282d5590
JM
2970 mode->channels[idx].chan = 14;
2971 else
2972 mode->channels[idx].chan = (mode->channels[idx].freq - 2407) / 5;
2973 else
2974 mode->channels[idx].chan = mode->channels[idx].freq/5 - 1000;
2975
2976 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
2977 mode->channels[idx].flag |=
2978 HOSTAPD_CHAN_DISABLED;
2979 if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
2980 mode->channels[idx].flag |=
2981 HOSTAPD_CHAN_PASSIVE_SCAN;
2982 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])
2983 mode->channels[idx].flag |=
2984 HOSTAPD_CHAN_NO_IBSS;
2985 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
2986 mode->channels[idx].flag |=
2987 HOSTAPD_CHAN_RADAR;
2988
2989 if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] &&
2990 !tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
2991 mode->channels[idx].max_tx_power =
2992 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) / 100;
2993
2994 idx++;
2995 }
2996
2997 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
2998 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
2999 nla_len(nl_rate), rate_policy);
3000 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
3001 continue;
3002 mode->num_rates++;
3003 }
3004
e62fb0a0 3005 mode->rates = os_zalloc(mode->num_rates * sizeof(int));
282d5590
JM
3006 if (!mode->rates)
3007 return NL_SKIP;
3008
3009 idx = 0;
3010
3011 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
3012 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
3013 nla_len(nl_rate), rate_policy);
3014 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
3015 continue;
fb7842aa 3016 mode->rates[idx] = nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE]);
282d5590
JM
3017
3018 /* crude heuristic */
3019 if (mode->mode == HOSTAPD_MODE_IEEE80211B &&
fb7842aa 3020 mode->rates[idx] > 200)
282d5590
JM
3021 mode->mode = HOSTAPD_MODE_IEEE80211G;
3022
282d5590
JM
3023 idx++;
3024 }
3025 }
3026
3027 return NL_SKIP;
3028}
3029
3030static struct hostapd_hw_modes *
3031wpa_driver_nl80211_add_11b(struct hostapd_hw_modes *modes, u16 *num_modes)
3032{
3033 u16 m;
3034 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
3035 int i, mode11g_idx = -1;
3036
3037 /* If only 802.11g mode is included, use it to construct matching
3038 * 802.11b mode data. */
3039
3040 for (m = 0; m < *num_modes; m++) {
3041 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
3042 return modes; /* 802.11b already included */
3043 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
3044 mode11g_idx = m;
3045 }
3046
3047 if (mode11g_idx < 0)
3048 return modes; /* 2.4 GHz band not supported at all */
3049
3050 nmodes = os_realloc(modes, (*num_modes + 1) * sizeof(*nmodes));
3051 if (nmodes == NULL)
3052 return modes; /* Could not add 802.11b mode */
3053
3054 mode = &nmodes[*num_modes];
3055 os_memset(mode, 0, sizeof(*mode));
3056 (*num_modes)++;
3057 modes = nmodes;
3058
3059 mode->mode = HOSTAPD_MODE_IEEE80211B;
3060
3061 mode11g = &modes[mode11g_idx];
3062 mode->num_channels = mode11g->num_channels;
3063 mode->channels = os_malloc(mode11g->num_channels *
3064 sizeof(struct hostapd_channel_data));
3065 if (mode->channels == NULL) {
3066 (*num_modes)--;
3067 return modes; /* Could not add 802.11b mode */
3068 }
3069 os_memcpy(mode->channels, mode11g->channels,
3070 mode11g->num_channels * sizeof(struct hostapd_channel_data));
3071
3072 mode->num_rates = 0;
fb7842aa 3073 mode->rates = os_malloc(4 * sizeof(int));
282d5590
JM
3074 if (mode->rates == NULL) {
3075 os_free(mode->channels);
3076 (*num_modes)--;
3077 return modes; /* Could not add 802.11b mode */
3078 }
3079
3080 for (i = 0; i < mode11g->num_rates; i++) {
fb7842aa
JM
3081 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
3082 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
282d5590
JM
3083 continue;
3084 mode->rates[mode->num_rates] = mode11g->rates[i];
3085 mode->num_rates++;
3086 if (mode->num_rates == 4)
3087 break;
3088 }
3089
3090 if (mode->num_rates == 0) {
3091 os_free(mode->channels);
3092 os_free(mode->rates);
3093 (*num_modes)--;
3094 return modes; /* No 802.11b rates */
3095 }
3096
3097 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
3098 "information");
3099
3100 return modes;
3101}
3102
3103
d8e66e80
JM
3104static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
3105 int end)
3106{
3107 int c;
3108
3109 for (c = 0; c < mode->num_channels; c++) {
3110 struct hostapd_channel_data *chan = &mode->channels[c];
3111 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
3112 chan->flag |= HOSTAPD_CHAN_HT40;
3113 }
3114}
3115
3116
3117static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
3118 int end)
3119{
3120 int c;
3121
3122 for (c = 0; c < mode->num_channels; c++) {
3123 struct hostapd_channel_data *chan = &mode->channels[c];
3124 if (!(chan->flag & HOSTAPD_CHAN_HT40))
3125 continue;
3126 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
3127 chan->flag |= HOSTAPD_CHAN_HT40MINUS;
3128 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
3129 chan->flag |= HOSTAPD_CHAN_HT40PLUS;
3130 }
3131}
3132
3133
3134static void nl80211_reg_rule_ht40(struct nlattr *tb[],
3135 struct phy_info_arg *results)
3136{
3137 u32 start, end, max_bw;
3138 u16 m;
3139
3140 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
3141 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
3142 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
3143 return;
3144
3145 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
3146 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
3147 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
3148
3149 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz",
3150 start, end, max_bw);
3151 if (max_bw < 40)
3152 return;
3153
3154 for (m = 0; m < *results->num_modes; m++) {
3155 if (!(results->modes[m].ht_capab &
3156 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
3157 continue;
3158 nl80211_set_ht40_mode(&results->modes[m], start, end);
3159 }
3160}
3161
3162
3163static void nl80211_reg_rule_sec(struct nlattr *tb[],
3164 struct phy_info_arg *results)
3165{
3166 u32 start, end, max_bw;
3167 u16 m;
3168
3169 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
3170 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
3171 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
3172 return;
3173
3174 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
3175 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
3176 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
3177
3178 if (max_bw < 20)
3179 return;
3180
3181 for (m = 0; m < *results->num_modes; m++) {
3182 if (!(results->modes[m].ht_capab &
3183 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
3184 continue;
3185 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
3186 }
3187}
3188
3189
3190static int nl80211_get_reg(struct nl_msg *msg, void *arg)
3191{
3192 struct phy_info_arg *results = arg;
3193 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3194 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3195 struct nlattr *nl_rule;
3196 struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
3197 int rem_rule;
3198 static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
3199 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
3200 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
3201 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
3202 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
3203 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
3204 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
3205 };
3206
3207 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3208 genlmsg_attrlen(gnlh, 0), NULL);
3209 if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
3210 !tb_msg[NL80211_ATTR_REG_RULES]) {
3211 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
3212 "available");
3213 return NL_SKIP;
3214 }
3215
3216 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
3217 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
3218
3219 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
3220 {
3221 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
3222 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
3223 nl80211_reg_rule_ht40(tb_rule, results);
3224 }
3225
3226 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
3227 {
3228 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
3229 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
3230 nl80211_reg_rule_sec(tb_rule, results);
3231 }
3232
3233 return NL_SKIP;
3234}
3235
3236
3237static int nl80211_set_ht40_flags(struct wpa_driver_nl80211_data *drv,
3238 struct phy_info_arg *results)
3239{
3240 struct nl_msg *msg;
3241
3242 msg = nlmsg_alloc();
3243 if (!msg)
3244 return -ENOMEM;
3245
3246 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3247 0, NL80211_CMD_GET_REG, 0);
3248 return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
3249}
3250
3251
282d5590
JM
3252static struct hostapd_hw_modes *
3253wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
3254{
a2e40bb6
FF
3255 struct i802_bss *bss = priv;
3256 struct wpa_driver_nl80211_data *drv = bss->drv;
282d5590
JM
3257 struct nl_msg *msg;
3258 struct phy_info_arg result = {
3259 .num_modes = num_modes,
3260 .modes = NULL,
3261 };
3262
3263 *num_modes = 0;
3264 *flags = 0;
3265
3266 msg = nlmsg_alloc();
3267 if (!msg)
3268 return NULL;
3269
3270 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3271 0, NL80211_CMD_GET_WIPHY, 0);
3272
3273 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3274
d8e66e80
JM
3275 if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
3276 nl80211_set_ht40_flags(drv, &result);
282d5590 3277 return wpa_driver_nl80211_add_11b(result.modes, num_modes);
d8e66e80 3278 }
282d5590
JM
3279 nla_put_failure:
3280 return NULL;
3281}
3282
3283
2c2010ac
JM
3284static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
3285 const void *data, size_t len,
3286 int encrypt)
3287{
3288 __u8 rtap_hdr[] = {
3289 0x00, 0x00, /* radiotap version */
3290 0x0e, 0x00, /* radiotap length */
3291 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
3292 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
3293 0x00, /* padding */
3294 0x00, 0x00, /* RX and TX flags to indicate that */
3295 0x00, 0x00, /* this is the injected frame directly */
3296 };
3297 struct iovec iov[2] = {
3298 {
3299 .iov_base = &rtap_hdr,
3300 .iov_len = sizeof(rtap_hdr),
3301 },
3302 {
3303 .iov_base = (void *) data,
3304 .iov_len = len,
3305 }
3306 };
3307 struct msghdr msg = {
3308 .msg_name = NULL,
3309 .msg_namelen = 0,
3310 .msg_iov = iov,
3311 .msg_iovlen = 2,
3312 .msg_control = NULL,
3313 .msg_controllen = 0,
3314 .msg_flags = 0,
3315 };
ebbec8b2 3316 int res;
2c2010ac
JM
3317
3318 if (encrypt)
3319 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
3320
ebbec8b2
JM
3321 res = sendmsg(drv->monitor_sock, &msg, 0);
3322 if (res < 0) {
3323 wpa_printf(MSG_INFO, "nl80211: sendmsg: %s", strerror(errno));
3324 return -1;
3325 }
3326 return 0;
2c2010ac
JM
3327}
3328
3329
3330static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
3331 size_t data_len)
3332{
a2e40bb6
FF
3333 struct i802_bss *bss = priv;
3334 struct wpa_driver_nl80211_data *drv = bss->drv;
2c2010ac 3335 struct ieee80211_mgmt *mgmt;
7a47d567 3336 int encrypt = 1;
2c2010ac
JM
3337 u16 fc;
3338
3339 mgmt = (struct ieee80211_mgmt *) data;
3340 fc = le_to_host16(mgmt->frame_control);
3341
5582a5d1
JB
3342 if (drv->nlmode == NL80211_IFTYPE_STATION &&
3343 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3344 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
3345 /*
3346 * The use of last_mgmt_freq is a bit of a hack,
3347 * but it works due to the single-threaded nature
3348 * of wpa_supplicant.
3349 */
3350 return nl80211_send_frame_cmd(drv, drv->last_mgmt_freq,
3351 data, data_len, NULL);
3352 }
3353
2c2010ac
JM
3354 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3355 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
3356 /*
3357 * Only one of the authentication frame types is encrypted.
3358 * In order for static WEP encryption to work properly (i.e.,
3359 * to not encrypt the frame), we need to tell mac80211 about
3360 * the frames that must not be encrypted.
3361 */
3362 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
3363 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
7a47d567
JB
3364 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
3365 encrypt = 0;
2c2010ac
JM
3366 }
3367
7a47d567 3368 return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt);
2c2010ac
JM
3369}
3370
3371
8b897f5a 3372static int wpa_driver_nl80211_set_beacon(void *priv,
5d674872
JM
3373 const u8 *head, size_t head_len,
3374 const u8 *tail, size_t tail_len,
3375 int dtim_period, int beacon_int)
d2440ba0 3376{
a2e40bb6
FF
3377 struct i802_bss *bss = priv;
3378 struct wpa_driver_nl80211_data *drv = bss->drv;
d2440ba0
JM
3379 struct nl_msg *msg;
3380 u8 cmd = NL80211_CMD_NEW_BEACON;
3381 int ret;
b4fd6fab 3382 int beacon_set;
8b897f5a 3383 int ifindex = if_nametoindex(bss->ifname);
b4fd6fab 3384
b4fd6fab 3385 beacon_set = bss->beacon_set;
d2440ba0
JM
3386
3387 msg = nlmsg_alloc();
3388 if (!msg)
3389 return -ENOMEM;
3390
3391 wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
b4fd6fab
JM
3392 beacon_set);
3393 if (beacon_set)
d2440ba0
JM
3394 cmd = NL80211_CMD_SET_BEACON;
3395
3396 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3397 0, cmd, 0);
3398 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);
3399 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);
b4fd6fab 3400 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5d674872 3401 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, beacon_int);
d2440ba0
JM
3402 NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, dtim_period);
3403
3404 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3405 if (ret) {
3406 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
3407 ret, strerror(-ret));
b4fd6fab 3408 } else {
b4fd6fab 3409 bss->beacon_set = 1;
b4fd6fab 3410 }
d2440ba0
JM
3411 return ret;
3412 nla_put_failure:
3413 return -ENOBUFS;
3414}
3415
3416
f019981a
JM
3417static int wpa_driver_nl80211_set_freq(struct wpa_driver_nl80211_data *drv,
3418 int freq, int ht_enabled,
3419 int sec_channel_offset)
1581b38b
JM
3420{
3421 struct nl_msg *msg;
d2440ba0 3422 int ret;
1581b38b
JM
3423
3424 msg = nlmsg_alloc();
3425 if (!msg)
3426 return -1;
3427
3428 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
3429 NL80211_CMD_SET_WIPHY, 0);
3430
3431 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
f019981a
JM
3432 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
3433 if (ht_enabled) {
3434 switch (sec_channel_offset) {
3435 case -1:
3436 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3437 NL80211_CHAN_HT40MINUS);
3438 break;
3439 case 1:
3440 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3441 NL80211_CHAN_HT40PLUS);
3442 break;
3443 default:
3444 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3445 NL80211_CHAN_HT20);
3446 break;
3447 }
3448 }
1581b38b 3449
d2440ba0
JM
3450 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3451 if (ret == 0)
1581b38b 3452 return 0;
f019981a
JM
3453 wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
3454 "%d (%s)", freq, ret, strerror(-ret));
1581b38b
JM
3455nla_put_failure:
3456 return -1;
3457}
3458
0f4e8b4f 3459
62847751 3460static int wpa_driver_nl80211_sta_add(void *priv,
0f4e8b4f
JM
3461 struct hostapd_sta_add_params *params)
3462{
a2e40bb6
FF
3463 struct i802_bss *bss = priv;
3464 struct wpa_driver_nl80211_data *drv = bss->drv;
0f4e8b4f
JM
3465 struct nl_msg *msg;
3466 int ret = -ENOBUFS;
3467
3468 msg = nlmsg_alloc();
3469 if (!msg)
3470 return -ENOMEM;
3471
3472 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3473 0, NL80211_CMD_NEW_STATION, 0);
3474
62847751 3475 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
0f4e8b4f
JM
3476 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
3477 NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
3478 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
3479 params->supp_rates);
3480 NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
3481 params->listen_interval);
0f4e8b4f
JM
3482 if (params->ht_capabilities) {
3483 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
fc4e2d95
JM
3484 sizeof(*params->ht_capabilities),
3485 params->ht_capabilities);
0f4e8b4f 3486 }
0f4e8b4f
JM
3487
3488 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3489 if (ret)
3490 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_NEW_STATION "
3491 "result: %d (%s)", ret, strerror(-ret));
3492 if (ret == -EEXIST)
3493 ret = 0;
3494 nla_put_failure:
3495 return ret;
3496}
3497
3498
3499static int wpa_driver_nl80211_sta_remove(void *priv, const u8 *addr)
3500{
a2e40bb6
FF
3501 struct i802_bss *bss = priv;
3502 struct wpa_driver_nl80211_data *drv = bss->drv;
0f4e8b4f
JM
3503 struct nl_msg *msg;
3504 int ret;
3505
3506 msg = nlmsg_alloc();
3507 if (!msg)
3508 return -ENOMEM;
3509
3510 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3511 0, NL80211_CMD_DEL_STATION, 0);
3512
3513 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 3514 if_nametoindex(bss->ifname));
0f4e8b4f
JM
3515 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3516
3517 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3518 if (ret == -ENOENT)
3519 return 0;
3520 return ret;
3521 nla_put_failure:
3522 return -ENOBUFS;
3523}
3524
1581b38b 3525
0915d02c
JM
3526static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
3527 int ifidx)
3528{
3529 struct nl_msg *msg;
3530
c6e8e8e4
JM
3531 wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
3532
2135f224
JM
3533#ifdef HOSTAPD
3534 /* stop listening for EAPOL on this interface */
3535 del_ifidx(drv, ifidx);
3536#endif /* HOSTAPD */
3537
0915d02c
JM
3538 msg = nlmsg_alloc();
3539 if (!msg)
3540 goto nla_put_failure;
3541
3542 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3543 0, NL80211_CMD_DEL_INTERFACE, 0);
3544 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
3545
3546 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
3547 return;
3548 nla_put_failure:
e748062b 3549 wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
0915d02c
JM
3550}
3551
3552
a35187e7
KH
3553static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
3554 const char *ifname,
3555 enum nl80211_iftype iftype,
fbbfcbac 3556 const u8 *addr, int wds)
0915d02c
JM
3557{
3558 struct nl_msg *msg, *flags = NULL;
3559 int ifidx;
3560 int ret = -ENOBUFS;
3561
3562 msg = nlmsg_alloc();
3563 if (!msg)
3564 return -1;
3565
3566 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3567 0, NL80211_CMD_NEW_INTERFACE, 0);
3568 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3569 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
3570 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
3571
3572 if (iftype == NL80211_IFTYPE_MONITOR) {
3573 int err;
3574
3575 flags = nlmsg_alloc();
3576 if (!flags)
3577 goto nla_put_failure;
3578
3579 NLA_PUT_FLAG(flags, NL80211_MNTR_FLAG_COOK_FRAMES);
3580
3581 err = nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);
3582
3583 nlmsg_free(flags);
3584
3585 if (err)
3586 goto nla_put_failure;
fbbfcbac
FF
3587 } else if (wds) {
3588 NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
0915d02c
JM
3589 }
3590
3591 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3592 if (ret) {
3593 nla_put_failure:
a35187e7
KH
3594 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
3595 ifname, ret, strerror(-ret));
0915d02c
JM
3596 return ret;
3597 }
3598
3599 ifidx = if_nametoindex(ifname);
c6e8e8e4
JM
3600 wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
3601 ifname, ifidx);
0915d02c
JM
3602
3603 if (ifidx <= 0)
3604 return -1;
3605
2135f224
JM
3606#ifdef HOSTAPD
3607 /* start listening for EAPOL on this interface */
3608 add_ifidx(drv, ifidx);
7bfc47c3 3609#endif /* HOSTAPD */
2135f224 3610
7bfc47c3 3611 if (addr && iftype != NL80211_IFTYPE_MONITOR &&
2ac9688e 3612 linux_set_ifhwaddr(drv->ioctl_sock, ifname, addr)) {
41d931ee
JM
3613 nl80211_remove_iface(drv, ifidx);
3614 return -1;
2135f224 3615 }
2135f224 3616
0915d02c
JM
3617 return ifidx;
3618}
22a7c9d7
JM
3619
3620
a35187e7
KH
3621static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
3622 const char *ifname, enum nl80211_iftype iftype,
fbbfcbac 3623 const u8 *addr, int wds)
a35187e7
KH
3624{
3625 int ret;
3626
fbbfcbac 3627 ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds);
a35187e7
KH
3628
3629 /* if error occured and interface exists already */
3630 if (ret == -ENFILE && if_nametoindex(ifname)) {
3631 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
3632
3633 /* Try to remove the interface that was already there. */
3634 nl80211_remove_iface(drv, if_nametoindex(ifname));
3635
3636 /* Try to create the interface again */
fbbfcbac
FF
3637 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
3638 wds);
a35187e7
KH
3639 }
3640
4e5cb1a3
JM
3641 if (ret >= 0 && drv->disable_11b_rates)
3642 nl80211_disable_11b_rates(drv, ret, 1);
3643
a35187e7
KH
3644 return ret;
3645}
0915d02c 3646
2135f224 3647
0915d02c
JM
3648static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
3649{
3650 struct ieee80211_hdr *hdr;
f8b1f695
JM
3651 u16 fc;
3652 union wpa_event_data event;
0915d02c
JM
3653
3654 hdr = (struct ieee80211_hdr *) buf;
3655 fc = le_to_host16(hdr->frame_control);
3656
f8b1f695
JM
3657 os_memset(&event, 0, sizeof(event));
3658 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
3659 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
3660 event.tx_status.dst = hdr->addr1;
3661 event.tx_status.data = buf;
3662 event.tx_status.data_len = len;
3663 event.tx_status.ack = ok;
3664 wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event);
0915d02c
JM
3665}
3666
3667
4b9841d3 3668static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
0d9fc3d8 3669 u8 *buf, size_t len)
0915d02c 3670{
f8b1f695
JM
3671 union wpa_event_data event;
3672 os_memset(&event, 0, sizeof(event));
0d9fc3d8 3673 event.rx_from_unknown.frame = buf;
f8b1f695
JM
3674 event.rx_from_unknown.len = len;
3675 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
4b9841d3 3676}
0915d02c 3677
4b9841d3
JM
3678
3679static void handle_frame(struct wpa_driver_nl80211_data *drv,
2a8b7416 3680 u8 *buf, size_t len, int datarate, int ssi_signal)
4b9841d3
JM
3681{
3682 struct ieee80211_hdr *hdr;
f8b1f695
JM
3683 u16 fc;
3684 union wpa_event_data event;
0915d02c
JM
3685
3686 hdr = (struct ieee80211_hdr *) buf;
3687 fc = le_to_host16(hdr->frame_control);
0915d02c 3688
4b9841d3 3689 switch (WLAN_FC_GET_TYPE(fc)) {
0915d02c 3690 case WLAN_FC_TYPE_MGMT:
f8b1f695
JM
3691 os_memset(&event, 0, sizeof(event));
3692 event.rx_mgmt.frame = buf;
3693 event.rx_mgmt.frame_len = len;
2a8b7416
JM
3694 event.rx_mgmt.datarate = datarate;
3695 event.rx_mgmt.ssi_signal = ssi_signal;
f8b1f695 3696 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
0915d02c
JM
3697 break;
3698 case WLAN_FC_TYPE_CTRL:
3699 /* can only get here with PS-Poll frames */
3700 wpa_printf(MSG_DEBUG, "CTRL");
0d9fc3d8 3701 from_unknown_sta(drv, buf, len);
0915d02c
JM
3702 break;
3703 case WLAN_FC_TYPE_DATA:
0d9fc3d8 3704 from_unknown_sta(drv, buf, len);
0915d02c
JM
3705 break;
3706 }
3707}
3708
3709
3710static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
3711{
3712 struct wpa_driver_nl80211_data *drv = eloop_ctx;
3713 int len;
3714 unsigned char buf[3000];
3715 struct ieee80211_radiotap_iterator iter;
3716 int ret;
2a8b7416 3717 int datarate = 0, ssi_signal = 0;
4b9841d3 3718 int injected = 0, failed = 0, rxflags = 0;
0915d02c
JM
3719
3720 len = recv(sock, buf, sizeof(buf), 0);
3721 if (len < 0) {
3722 perror("recv");
3723 return;
3724 }
3725
3726 if (ieee80211_radiotap_iterator_init(&iter, (void*)buf, len)) {
3727 printf("received invalid radiotap frame\n");
3728 return;
3729 }
3730
0915d02c
JM
3731 while (1) {
3732 ret = ieee80211_radiotap_iterator_next(&iter);
3733 if (ret == -ENOENT)
3734 break;
3735 if (ret) {
3736 printf("received invalid radiotap frame (%d)\n", ret);
3737 return;
3738 }
3739 switch (iter.this_arg_index) {
3740 case IEEE80211_RADIOTAP_FLAGS:
3741 if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
3742 len -= 4;
3743 break;
3744 case IEEE80211_RADIOTAP_RX_FLAGS:
3745 rxflags = 1;
3746 break;
3747 case IEEE80211_RADIOTAP_TX_FLAGS:
3748 injected = 1;
3749 failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
3750 IEEE80211_RADIOTAP_F_TX_FAIL;
3751 break;
3752 case IEEE80211_RADIOTAP_DATA_RETRIES:
3753 break;
3754 case IEEE80211_RADIOTAP_CHANNEL:
2a8b7416 3755 /* TODO: convert from freq/flags to channel number */
0915d02c
JM
3756 break;
3757 case IEEE80211_RADIOTAP_RATE:
2a8b7416 3758 datarate = *iter.this_arg * 5;
0915d02c
JM
3759 break;
3760 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
2a8b7416 3761 ssi_signal = *iter.this_arg;
0915d02c
JM
3762 break;
3763 }
3764 }
3765
3766 if (rxflags && injected)
3767 return;
3768
3769 if (!injected)
4b9841d3 3770 handle_frame(drv, buf + iter.max_length,
2a8b7416 3771 len - iter.max_length, datarate, ssi_signal);
0915d02c 3772 else
4b9841d3
JM
3773 handle_tx_callback(drv->ctx, buf + iter.max_length,
3774 len - iter.max_length, !failed);
0915d02c
JM
3775}
3776
3777
3778/*
3779 * we post-process the filter code later and rewrite
3780 * this to the offset to the last instruction
3781 */
3782#define PASS 0xFF
3783#define FAIL 0xFE
3784
3785static struct sock_filter msock_filter_insns[] = {
3786 /*
3787 * do a little-endian load of the radiotap length field
3788 */
3789 /* load lower byte into A */
3790 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
3791 /* put it into X (== index register) */
3792 BPF_STMT(BPF_MISC| BPF_TAX, 0),
3793 /* load upper byte into A */
3794 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 3),
3795 /* left-shift it by 8 */
3796 BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
3797 /* or with X */
3798 BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
3799 /* put result into X */
3800 BPF_STMT(BPF_MISC| BPF_TAX, 0),
3801
3802 /*
3803 * Allow management frames through, this also gives us those
3804 * management frames that we sent ourselves with status
3805 */
3806 /* load the lower byte of the IEEE 802.11 frame control field */
3807 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
3808 /* mask off frame type and version */
3809 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
3810 /* accept frame if it's both 0, fall through otherwise */
3811 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
3812
3813 /*
3814 * TODO: add a bit to radiotap RX flags that indicates
3815 * that the sending station is not associated, then
3816 * add a filter here that filters on our DA and that flag
3817 * to allow us to deauth frames to that bad station.
3818 *
65ae1afd 3819 * For now allow all To DS data frames through.
0915d02c 3820 */
65ae1afd
HS
3821 /* load the IEEE 802.11 frame control field */
3822 BPF_STMT(BPF_LD | BPF_H | BPF_IND, 0),
3823 /* mask off frame type, version and DS status */
3824 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0F03),
3825 /* accept frame if version 0, type 2 and To DS, fall through otherwise
3826 */
3827 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0801, PASS, 0),
0915d02c
JM
3828
3829#if 0
3830 /*
fbbfcbac 3831 * drop non-data frames
0915d02c
JM
3832 */
3833 /* load the lower byte of the frame control field */
3834 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
3835 /* mask off QoS bit */
3836 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0c),
3837 /* drop non-data frames */
3838 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 8, 0, FAIL),
fbbfcbac 3839#endif
0915d02c 3840 /* load the upper byte of the frame control field */
fbbfcbac 3841 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
0915d02c
JM
3842 /* mask off toDS/fromDS */
3843 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x03),
fbbfcbac
FF
3844 /* accept WDS frames */
3845 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 3, PASS, 0),
0915d02c
JM
3846
3847 /*
3848 * add header length to index
3849 */
3850 /* load the lower byte of the frame control field */
3851 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
3852 /* mask off QoS bit */
3853 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80),
3854 /* right shift it by 6 to give 0 or 2 */
3855 BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 6),
3856 /* add data frame header length */
3857 BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 24),
3858 /* add index, was start of 802.11 header */
3859 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
3860 /* move to index, now start of LL header */
3861 BPF_STMT(BPF_MISC | BPF_TAX, 0),
3862
3863 /*
3864 * Accept empty data frames, we use those for
3865 * polling activity.
3866 */
3867 BPF_STMT(BPF_LD | BPF_W | BPF_LEN, 0),
3868 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
3869
3870 /*
3871 * Accept EAPOL frames
3872 */
3873 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 0),
3874 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
3875 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 4),
3876 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
3877
3878 /* keep these last two statements or change the code below */
3879 /* return 0 == "DROP" */
3880 BPF_STMT(BPF_RET | BPF_K, 0),
3881 /* return ~0 == "keep all" */
3882 BPF_STMT(BPF_RET | BPF_K, ~0),
3883};
3884
3885static struct sock_fprog msock_filter = {
3886 .len = sizeof(msock_filter_insns)/sizeof(msock_filter_insns[0]),
3887 .filter = msock_filter_insns,
3888};
3889
3890
3891static int add_monitor_filter(int s)
3892{
3893 int idx;
3894
3895 /* rewrite all PASS/FAIL jump offsets */
3896 for (idx = 0; idx < msock_filter.len; idx++) {
3897 struct sock_filter *insn = &msock_filter_insns[idx];
3898
3899 if (BPF_CLASS(insn->code) == BPF_JMP) {
3900 if (insn->code == (BPF_JMP|BPF_JA)) {
3901 if (insn->k == PASS)
3902 insn->k = msock_filter.len - idx - 2;
3903 else if (insn->k == FAIL)
3904 insn->k = msock_filter.len - idx - 3;
3905 }
3906
3907 if (insn->jt == PASS)
3908 insn->jt = msock_filter.len - idx - 2;
3909 else if (insn->jt == FAIL)
3910 insn->jt = msock_filter.len - idx - 3;
3911
3912 if (insn->jf == PASS)
3913 insn->jf = msock_filter.len - idx - 2;
3914 else if (insn->jf == FAIL)
3915 insn->jf = msock_filter.len - idx - 3;
3916 }
3917 }
3918
3919 if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
3920 &msock_filter, sizeof(msock_filter))) {
3921 perror("SO_ATTACH_FILTER");
3922 return -1;
3923 }
3924
3925 return 0;
3926}
3927
3928
460456f8
JM
3929static void nl80211_remove_monitor_interface(
3930 struct wpa_driver_nl80211_data *drv)
3931{
3932 if (drv->monitor_ifidx >= 0) {
3933 nl80211_remove_iface(drv, drv->monitor_ifidx);
3934 drv->monitor_ifidx = -1;
3935 }
504e905c
JM
3936 if (drv->monitor_sock >= 0) {
3937 eloop_unregister_read_sock(drv->monitor_sock);
3938 close(drv->monitor_sock);
3939 drv->monitor_sock = -1;
3940 }
460456f8
JM
3941}
3942
3943
0915d02c
JM
3944static int
3945nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
3946{
3947 char buf[IFNAMSIZ];
3948 struct sockaddr_ll ll;
3949 int optval;
3950 socklen_t optlen;
0915d02c 3951
a2e40bb6 3952 snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss.ifname);
0915d02c
JM
3953 buf[IFNAMSIZ - 1] = '\0';
3954
3955 drv->monitor_ifidx =
fbbfcbac
FF
3956 nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
3957 0);
0915d02c
JM
3958
3959 if (drv->monitor_ifidx < 0)
3960 return -1;
3961
34f2f814 3962 if (linux_set_iface_flags(drv->ioctl_sock, buf, 1))
0915d02c 3963 goto error;
0915d02c
JM
3964
3965 memset(&ll, 0, sizeof(ll));
3966 ll.sll_family = AF_PACKET;
3967 ll.sll_ifindex = drv->monitor_ifidx;
3968 drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
3969 if (drv->monitor_sock < 0) {
3970 perror("socket[PF_PACKET,SOCK_RAW]");
3971 goto error;
3972 }
3973
3974 if (add_monitor_filter(drv->monitor_sock)) {
3975 wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
3976 "interface; do filtering in user space");
3977 /* This works, but will cost in performance. */
3978 }
3979
2135f224 3980 if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
0915d02c
JM
3981 perror("monitor socket bind");
3982 goto error;
3983 }
3984
3985 optlen = sizeof(optval);
3986 optval = 20;
3987 if (setsockopt
3988 (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
3989 perror("Failed to set socket priority");
3990 goto error;
3991 }
3992
3993 if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
3994 drv, NULL)) {
3995 printf("Could not register monitor read socket\n");
3996 goto error;
3997 }
3998
3999 return 0;
4000 error:
460456f8 4001 nl80211_remove_monitor_interface(drv);
0915d02c
JM
4002 return -1;
4003}
4004
db149ac9
JM
4005
4006static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
4007
4008static int wpa_driver_nl80211_hapd_send_eapol(
4009 void *priv, const u8 *addr, const u8 *data,
4010 size_t data_len, int encrypt, const u8 *own_addr)
4011{
a2e40bb6
FF
4012 struct i802_bss *bss = priv;
4013 struct wpa_driver_nl80211_data *drv = bss->drv;
db149ac9
JM
4014 struct ieee80211_hdr *hdr;
4015 size_t len;
4016 u8 *pos;
4017 int res;
4018#if 0 /* FIX */
0de39516 4019 int qos = sta->flags & WPA_STA_WMM;
db149ac9
JM
4020#else
4021 int qos = 0;
4022#endif
4023
4024 len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
4025 data_len;
4026 hdr = os_zalloc(len);
4027 if (hdr == NULL) {
4028 printf("malloc() failed for i802_send_data(len=%lu)\n",
4029 (unsigned long) len);
4030 return -1;
4031 }
4032
4033 hdr->frame_control =
4034 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
4035 hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
4036 if (encrypt)
4037 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
4038#if 0 /* To be enabled if qos determination is added above */
4039 if (qos) {
4040 hdr->frame_control |=
4041 host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
4042 }
4043#endif
4044
4045 memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
4046 memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
4047 memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
4048 pos = (u8 *) (hdr + 1);
4049
4050#if 0 /* To be enabled if qos determination is added above */
4051 if (qos) {
4052 /* add an empty QoS header if needed */
4053 pos[0] = 0;
4054 pos[1] = 0;
4055 pos += 2;
4056 }
4057#endif
4058
4059 memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
4060 pos += sizeof(rfc1042_header);
4061 WPA_PUT_BE16(pos, ETH_P_PAE);
4062 pos += 2;
4063 memcpy(pos, data, data_len);
4064
4065 res = wpa_driver_nl80211_send_frame(drv, (u8 *) hdr, len, encrypt);
4066 if (res < 0) {
4067 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
4068 "failed: %d (%s)",
4069 (unsigned long) len, errno, strerror(errno));
4070 }
7bf12757 4071 os_free(hdr);
db149ac9
JM
4072
4073 return res;
4074}
4075
a8d6ffa4 4076
7e76ee9c
JM
4077static u32 sta_flags_nl80211(int flags)
4078{
4079 u32 f = 0;
4080
0de39516 4081 if (flags & WPA_STA_AUTHORIZED)
7e76ee9c 4082 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
0de39516 4083 if (flags & WPA_STA_WMM)
7e76ee9c 4084 f |= BIT(NL80211_STA_FLAG_WME);
0de39516 4085 if (flags & WPA_STA_SHORT_PREAMBLE)
7e76ee9c 4086 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
0de39516 4087 if (flags & WPA_STA_MFP)
7e76ee9c
JM
4088 f |= BIT(NL80211_STA_FLAG_MFP);
4089
4090 return f;
4091}
4092
4093
3234cba4
JM
4094static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
4095 int total_flags,
4c32757d 4096 int flags_or, int flags_and)
a8d6ffa4 4097{
a2e40bb6
FF
4098 struct i802_bss *bss = priv;
4099 struct wpa_driver_nl80211_data *drv = bss->drv;
a8d6ffa4 4100 struct nl_msg *msg, *flags = NULL;
7e76ee9c 4101 struct nl80211_sta_flag_update upd;
a8d6ffa4
JM
4102
4103 msg = nlmsg_alloc();
4104 if (!msg)
4105 return -ENOMEM;
4106
4107 flags = nlmsg_alloc();
4108 if (!flags) {
4109 nlmsg_free(msg);
4110 return -ENOMEM;
4111 }
4112
4113 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4114 0, NL80211_CMD_SET_STATION, 0);
4115
4116 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
3234cba4 4117 if_nametoindex(bss->ifname));
a8d6ffa4
JM
4118 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
4119
7e76ee9c
JM
4120 /*
4121 * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
4122 * can be removed eventually.
4123 */
0de39516 4124 if (total_flags & WPA_STA_AUTHORIZED)
a8d6ffa4
JM
4125 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);
4126
0de39516 4127 if (total_flags & WPA_STA_WMM)
a8d6ffa4
JM
4128 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);
4129
0de39516 4130 if (total_flags & WPA_STA_SHORT_PREAMBLE)
a8d6ffa4
JM
4131 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);
4132
0de39516 4133 if (total_flags & WPA_STA_MFP)
a8d6ffa4
JM
4134 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_MFP);
4135
4136 if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))
4137 goto nla_put_failure;
4138
7e76ee9c
JM
4139 os_memset(&upd, 0, sizeof(upd));
4140 upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
4141 upd.set = sta_flags_nl80211(flags_or);
4142 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
4143
a8d6ffa4
JM
4144 nlmsg_free(flags);
4145
4146 return send_and_recv_msgs(drv, msg, NULL, NULL);
4147 nla_put_failure:
4148 nlmsg_free(flags);
4149 return -ENOBUFS;
4150}
4151
0915d02c 4152
1581b38b
JM
4153static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
4154 struct wpa_driver_associate_params *params)
4155{
046b26a2
JM
4156 if (params->p2p)
4157 wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
4158 "group (GO)");
a2e40bb6 4159 if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode) ||
f019981a 4160 wpa_driver_nl80211_set_freq(drv, params->freq, 0, 0)) {
460456f8 4161 nl80211_remove_monitor_interface(drv);
1581b38b 4162 return -1;
0915d02c 4163 }
1581b38b
JM
4164
4165 /* TODO: setup monitor interface (and add code somewhere to remove this
4166 * when AP mode is stopped; associate with mode != 2 or drv_deinit) */
1581b38b
JM
4167
4168 return 0;
4169}
1581b38b
JM
4170
4171
5cc4d64b
JM
4172static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
4173{
4174 struct nl_msg *msg;
4175 int ret = -1;
4176
4177 msg = nlmsg_alloc();
4178 if (!msg)
4179 return -1;
4180
4181 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
4182 NL80211_CMD_LEAVE_IBSS, 0);
4183 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4184 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4185 msg = NULL;
4186 if (ret) {
4187 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
4188 "(%s)", ret, strerror(-ret));
4189 goto nla_put_failure;
4190 }
4191
4192 ret = 0;
4193 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
4194
4195nla_put_failure:
4196 nlmsg_free(msg);
4197 return ret;
4198}
4199
4200
4201static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
4202 struct wpa_driver_associate_params *params)
4203{
4204 struct nl_msg *msg;
4205 int ret = -1;
4206 int count = 0;
4207
4208 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
4209
a2e40bb6 4210 if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode)) {
5cc4d64b
JM
4211 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
4212 "IBSS mode");
4213 return -1;
4214 }
4215
4216retry:
4217 msg = nlmsg_alloc();
4218 if (!msg)
4219 return -1;
4220
4221 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
4222 NL80211_CMD_JOIN_IBSS, 0);
4223 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4224
4225 if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
4226 goto nla_put_failure;
4227
4228 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
4229 params->ssid, params->ssid_len);
4230 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
4231 params->ssid);
4232 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
4233 drv->ssid_len = params->ssid_len;
4234
4235 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
4236 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
4237
4238 ret = nl80211_set_conn_keys(params, msg);
4239 if (ret)
4240 goto nla_put_failure;
4241
a95795ad
JM
4242 if (params->wpa_ie) {
4243 wpa_hexdump(MSG_DEBUG,
4244 " * Extra IEs for Beacon/Probe Response frames",
4245 params->wpa_ie, params->wpa_ie_len);
4246 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
4247 params->wpa_ie);
4248 }
4249
5cc4d64b
JM
4250 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4251 msg = NULL;
4252 if (ret) {
4253 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
4254 ret, strerror(-ret));
4255 count++;
4256 if (ret == -EALREADY && count == 1) {
4257 wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
4258 "forced leave");
4259 nl80211_leave_ibss(drv);
4260 nlmsg_free(msg);
4261 goto retry;
4262 }
4263
4264 goto nla_put_failure;
4265 }
4266 ret = 0;
4267 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
4268
4269nla_put_failure:
4270 nlmsg_free(msg);
4271 return ret;
4272}
4273
4274
cfaab580
ZY
4275static int wpa_driver_nl80211_connect(
4276 struct wpa_driver_nl80211_data *drv,
4277 struct wpa_driver_associate_params *params)
4278{
4279 struct nl_msg *msg;
4280 enum nl80211_auth_type type;
4281 int ret = 0;
4282
4283 msg = nlmsg_alloc();
4284 if (!msg)
4285 return -1;
4286
4287 wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
4288 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
4289 NL80211_CMD_CONNECT, 0);
4290
4291 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4292 if (params->bssid) {
4293 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
4294 MAC2STR(params->bssid));
4295 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
4296 }
4297 if (params->freq) {
4298 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
4299 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
4300 }
4301 if (params->ssid) {
4302 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
4303 params->ssid, params->ssid_len);
4304 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
4305 params->ssid);
4306 if (params->ssid_len > sizeof(drv->ssid))
4307 goto nla_put_failure;
4308 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
4309 drv->ssid_len = params->ssid_len;
4310 }
4311 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
4312 if (params->wpa_ie)
4313 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
4314 params->wpa_ie);
4315
abd9fafa 4316 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
cfaab580 4317 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
abd9fafa 4318 else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
cfaab580 4319 type = NL80211_AUTHTYPE_SHARED_KEY;
abd9fafa 4320 else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
cfaab580 4321 type = NL80211_AUTHTYPE_NETWORK_EAP;
abd9fafa 4322 else if (params->auth_alg & WPA_AUTH_ALG_FT)
cfaab580
ZY
4323 type = NL80211_AUTHTYPE_FT;
4324 else
4325 goto nla_put_failure;
4326
4327 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
4328 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
4329
4330 if (params->wpa_ie && params->wpa_ie_len) {
4331 enum nl80211_wpa_versions ver;
4332
4333 if (params->wpa_ie[0] == WLAN_EID_RSN)
4334 ver = NL80211_WPA_VERSION_2;
4335 else
4336 ver = NL80211_WPA_VERSION_1;
4337
4338 wpa_printf(MSG_DEBUG, " * WPA Version %d", ver);
4339 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
4340 }
4341
4342 if (params->pairwise_suite != CIPHER_NONE) {
c1bb3e0a 4343 int cipher;
cfaab580
ZY
4344
4345 switch (params->pairwise_suite) {
4346 case CIPHER_WEP40:
4347 cipher = WLAN_CIPHER_SUITE_WEP40;
4348 break;
4349 case CIPHER_WEP104:
4350 cipher = WLAN_CIPHER_SUITE_WEP104;
4351 break;
4352 case CIPHER_CCMP:
4353 cipher = WLAN_CIPHER_SUITE_CCMP;
4354 break;
4355 case CIPHER_TKIP:
4356 default:
4357 cipher = WLAN_CIPHER_SUITE_TKIP;
4358 break;
4359 }
4360 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
4361 }
4362
4363 if (params->group_suite != CIPHER_NONE) {
c1bb3e0a 4364 int cipher;
cfaab580
ZY
4365
4366 switch (params->group_suite) {
4367 case CIPHER_WEP40:
4368 cipher = WLAN_CIPHER_SUITE_WEP40;
4369 break;
4370 case CIPHER_WEP104:
4371 cipher = WLAN_CIPHER_SUITE_WEP104;
4372 break;
4373 case CIPHER_CCMP:
4374 cipher = WLAN_CIPHER_SUITE_CCMP;
4375 break;
4376 case CIPHER_TKIP:
4377 default:
4378 cipher = WLAN_CIPHER_SUITE_TKIP;
4379 break;
4380 }
4381 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
4382 }
4383
4384 if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
4385 params->key_mgmt_suite == KEY_MGMT_PSK) {
4386 int mgmt = WLAN_AKM_SUITE_PSK;
4387
4388 switch (params->key_mgmt_suite) {
4389 case KEY_MGMT_802_1X:
4390 mgmt = WLAN_AKM_SUITE_8021X;
4391 break;
4392 case KEY_MGMT_PSK:
4393 default:
4394 mgmt = WLAN_AKM_SUITE_PSK;
4395 break;
4396 }
4397 NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
4398 }
4399
4400 ret = nl80211_set_conn_keys(params, msg);
4401 if (ret)
4402 goto nla_put_failure;
4403
4404 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4405 msg = NULL;
4406 if (ret) {
4407 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
4408 "(%s)", ret, strerror(-ret));
4409 goto nla_put_failure;
4410 }
4411 ret = 0;
4412 wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
4413
4414nla_put_failure:
4415 nlmsg_free(msg);
4416 return ret;
4417
4418}
4419
4420
c2a04078
JM
4421static int wpa_driver_nl80211_associate(
4422 void *priv, struct wpa_driver_associate_params *params)
4423{
a2e40bb6
FF
4424 struct i802_bss *bss = priv;
4425 struct wpa_driver_nl80211_data *drv = bss->drv;
c2a04078
JM
4426 int ret = -1;
4427 struct nl_msg *msg;
4428
5cc4d64b 4429 if (params->mode == IEEE80211_MODE_AP)
1581b38b 4430 return wpa_driver_nl80211_ap(drv, params);
1581b38b 4431
5cc4d64b
JM
4432 if (params->mode == IEEE80211_MODE_IBSS)
4433 return wpa_driver_nl80211_ibss(drv, params);
4434
4a867032 4435 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
a2e40bb6 4436 if (wpa_driver_nl80211_set_mode(priv, params->mode) < 0)
4a867032 4437 return -1;
cfaab580 4438 return wpa_driver_nl80211_connect(drv, params);
4a867032 4439 }
cfaab580 4440
c2a04078
JM
4441 drv->associated = 0;
4442
4443 msg = nlmsg_alloc();
4444 if (!msg)
4445 return -1;
4446
4447 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
4448 drv->ifindex);
4449 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
4450 NL80211_CMD_ASSOCIATE, 0);
4451
4452 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4453 if (params->bssid) {
4454 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
4455 MAC2STR(params->bssid));
4456 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
4457 }
4458 if (params->freq) {
4459 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
4460 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
4832ecd7
JM
4461 drv->assoc_freq = params->freq;
4462 } else
4463 drv->assoc_freq = 0;
c2a04078
JM
4464 if (params->ssid) {
4465 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
4466 params->ssid, params->ssid_len);
4467 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
4468 params->ssid);
fd05d64e
JM
4469 if (params->ssid_len > sizeof(drv->ssid))
4470 goto nla_put_failure;
4471 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
4472 drv->ssid_len = params->ssid_len;
c2a04078
JM
4473 }
4474 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
4475 if (params->wpa_ie)
4476 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
4477 params->wpa_ie);
4478
e572fa33
JM
4479#ifdef CONFIG_IEEE80211W
4480 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
4481 NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
4482#endif /* CONFIG_IEEE80211W */
4483
01652550
JM
4484 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
4485
62fa124c
JM
4486 if (params->prev_bssid) {
4487 wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
4488 MAC2STR(params->prev_bssid));
4489 NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
4490 params->prev_bssid);
4491 }
4492
046b26a2
JM
4493 if (params->p2p)
4494 wpa_printf(MSG_DEBUG, " * P2P group");
4495
c2a04078
JM
4496 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4497 msg = NULL;
4498 if (ret) {
4499 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
4500 "(%s)", ret, strerror(-ret));
8856462d 4501 nl80211_dump_scan(drv);
c2a04078
JM
4502 goto nla_put_failure;
4503 }
4504 ret = 0;
4505 wpa_printf(MSG_DEBUG, "nl80211: Association request send "
4506 "successfully");
4507
4508nla_put_failure:
4509 nlmsg_free(msg);
4510 return ret;
4511}
3f5285e8
JM
4512
4513
ad1e68e6
JM
4514static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
4515 int ifindex, int mode)
3f5285e8 4516{
3f5285e8 4517 struct nl_msg *msg;
ad1e68e6
JM
4518 int ret = -ENOBUFS;
4519
4520 msg = nlmsg_alloc();
4521 if (!msg)
4522 return -ENOMEM;
4523
4524 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4525 0, NL80211_CMD_SET_INTERFACE, 0);
4526 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
4527 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
4528
4529 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4530 if (!ret)
4531 return 0;
4532nla_put_failure:
4533 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
4534 " %d (%s)", ifindex, mode, ret, strerror(-ret));
4535 return ret;
4536}
4537
4538
4539static int wpa_driver_nl80211_set_mode(void *priv, int mode)
4540{
a2e40bb6
FF
4541 struct i802_bss *bss = priv;
4542 struct wpa_driver_nl80211_data *drv = bss->drv;
ad1e68e6 4543 int ret = -1;
1581b38b 4544 int nlmode;
26af9dca 4545 int i;
1581b38b
JM
4546
4547 switch (mode) {
4548 case 0:
4549 nlmode = NL80211_IFTYPE_STATION;
4550 break;
4551 case 1:
4552 nlmode = NL80211_IFTYPE_ADHOC;
4553 break;
4554 case 2:
4555 nlmode = NL80211_IFTYPE_AP;
4556 break;
4557 default:
4558 return -1;
4559 }
3f5285e8 4560
ad1e68e6
JM
4561 if (nl80211_set_mode(drv, drv->ifindex, nlmode) == 0) {
4562 drv->nlmode = nlmode;
460456f8
JM
4563 ret = 0;
4564 goto done;
ad1e68e6 4565 }
3f5285e8 4566
460456f8 4567 if (nlmode == drv->nlmode) {
c6e8e8e4
JM
4568 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
4569 "requested mode - ignore error");
460456f8
JM
4570 ret = 0;
4571 goto done; /* Already in the requested mode */
4572 }
3f5285e8 4573
3f5285e8
JM
4574 /* mac80211 doesn't allow mode changes while the device is up, so
4575 * take the device down, try to set the mode again, and bring the
4576 * device back up.
4577 */
26af9dca
JM
4578 wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
4579 "interface down");
4580 for (i = 0; i < 10; i++) {
4581 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0) ==
4582 0) {
4583 /* Try to set the mode again while the interface is
4584 * down */
4585 ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
4586 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname,
4587 1))
4588 ret = -1;
4589 if (!ret)
4590 break;
4591 } else
4592 wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
4593 "interface down");
4594 os_sleep(0, 100000);
3f5285e8
JM
4595 }
4596
c6e8e8e4
JM
4597 if (!ret) {
4598 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
4599 "interface is down");
ad1e68e6 4600 drv->nlmode = nlmode;
c6e8e8e4 4601 }
ad1e68e6 4602
460456f8 4603done:
460456f8
JM
4604 if (!ret && nlmode == NL80211_IFTYPE_AP) {
4605 /* Setup additional AP mode functionality if needed */
4606 if (drv->monitor_ifidx < 0 &&
4607 nl80211_create_monitor_interface(drv))
4608 return -1;
4609 } else if (!ret && nlmode != NL80211_IFTYPE_AP) {
4610 /* Remove additional AP mode functionality */
4611 nl80211_remove_monitor_interface(drv);
a2e40bb6 4612 bss->beacon_set = 0;
460456f8 4613 }
460456f8 4614
c6e8e8e4
JM
4615 if (ret)
4616 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
4617 "from %d failed", nlmode, drv->nlmode);
4618
3f5285e8
JM
4619 return ret;
4620}
4621
4622
3f5285e8
JM
4623static int wpa_driver_nl80211_get_capa(void *priv,
4624 struct wpa_driver_capa *capa)
4625{
a2e40bb6
FF
4626 struct i802_bss *bss = priv;
4627 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8
JM
4628 if (!drv->has_capability)
4629 return -1;
4630 os_memcpy(capa, &drv->capa, sizeof(*capa));
4631 return 0;
4632}
4633
4634
4635static int wpa_driver_nl80211_set_operstate(void *priv, int state)
4636{
a2e40bb6
FF
4637 struct i802_bss *bss = priv;
4638 struct wpa_driver_nl80211_data *drv = bss->drv;
3f5285e8
JM
4639
4640 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
4641 __func__, drv->operstate, state, state ? "UP" : "DORMANT");
4642 drv->operstate = state;
08063178 4643 return netlink_send_oper_ifla(drv->netlink, drv->ifindex, -1,
e2d02c29 4644 state ? IF_OPER_UP : IF_OPER_DORMANT);
3f5285e8
JM
4645}
4646
01652550
JM
4647
4648static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
4649{
a2e40bb6
FF
4650 struct i802_bss *bss = priv;
4651 struct wpa_driver_nl80211_data *drv = bss->drv;
01652550
JM
4652 struct nl_msg *msg;
4653 struct nl80211_sta_flag_update upd;
4654
4655 msg = nlmsg_alloc();
4656 if (!msg)
4657 return -ENOMEM;
4658
4659 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4660 0, NL80211_CMD_SET_STATION, 0);
4661
4662 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 4663 if_nametoindex(bss->ifname));
01652550
JM
4664 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
4665
4666 os_memset(&upd, 0, sizeof(upd));
4667 upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
4668 if (authorized)
4669 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
4670 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
4671
4672 return send_and_recv_msgs(drv, msg, NULL, NULL);
4673 nla_put_failure:
4674 return -ENOBUFS;
4675}
4676
3f5285e8 4677
c5121837
JM
4678#ifdef HOSTAPD
4679
c5121837
JM
4680static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
4681{
4682 int i;
4683 int *old;
4684
4685 wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
4686 ifidx);
4687 for (i = 0; i < drv->num_if_indices; i++) {
4688 if (drv->if_indices[i] == 0) {
4689 drv->if_indices[i] = ifidx;
4690 return;
4691 }
4692 }
4693
4694 if (drv->if_indices != drv->default_if_indices)
4695 old = drv->if_indices;
4696 else
4697 old = NULL;
4698
7bf12757
JM
4699 drv->if_indices = os_realloc(old,
4700 sizeof(int) * (drv->num_if_indices + 1));
c5121837
JM
4701 if (!drv->if_indices) {
4702 if (!old)
4703 drv->if_indices = drv->default_if_indices;
4704 else
4705 drv->if_indices = old;
4706 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
4707 "interfaces");
4708 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
4709 return;
0ab7a701
B
4710 } else if (!old)
4711 os_memcpy(drv->if_indices, drv->default_if_indices,
4712 sizeof(drv->default_if_indices));
c5121837
JM
4713 drv->if_indices[drv->num_if_indices] = ifidx;
4714 drv->num_if_indices++;
4715}
4716
4717
4718static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
4719{
4720 int i;
4721
4722 for (i = 0; i < drv->num_if_indices; i++) {
4723 if (drv->if_indices[i] == ifidx) {
4724 drv->if_indices[i] = 0;
4725 break;
4726 }
4727 }
4728}
4729
4730
4731static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
4732{
4733 int i;
4734
4735 for (i = 0; i < drv->num_if_indices; i++)
4736 if (drv->if_indices[i] == ifidx)
4737 return 1;
4738
4739 return 0;
4740}
4741
4742
c5121837
JM
4743static inline int min_int(int a, int b)
4744{
4745 if (a < b)
4746 return a;
4747 return b;
4748}
4749
4750
4751static int get_key_handler(struct nl_msg *msg, void *arg)
4752{
4753 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4754 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4755
4756 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4757 genlmsg_attrlen(gnlh, 0), NULL);
4758
4759 /*
4760 * TODO: validate the key index and mac address!
4761 * Otherwise, there's a race condition as soon as
4762 * the kernel starts sending key notifications.
4763 */
4764
4765 if (tb[NL80211_ATTR_KEY_SEQ])
4766 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
4767 min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
4768 return NL_SKIP;
4769}
4770
4771
4772static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
4773 int idx, u8 *seq)
4774{
a2e40bb6
FF
4775 struct i802_bss *bss = priv;
4776 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
4777 struct nl_msg *msg;
4778
4779 msg = nlmsg_alloc();
4780 if (!msg)
4781 return -ENOMEM;
4782
4783 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4784 0, NL80211_CMD_GET_KEY, 0);
4785
4786 if (addr)
4787 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
4788 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
4789 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
4790
4791 memset(seq, 0, 6);
4792
4793 return send_and_recv_msgs(drv, msg, get_key_handler, seq);
4794 nla_put_failure:
4795 return -ENOBUFS;
4796}
4797
4798
4799static int i802_set_rate_sets(void *priv, int *supp_rates, int *basic_rates,
4800 int mode)
4801{
a2e40bb6
FF
4802 struct i802_bss *bss = priv;
4803 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
4804 struct nl_msg *msg;
4805 u8 rates[NL80211_MAX_SUPP_RATES];
4806 u8 rates_len = 0;
4807 int i;
4808
4809 msg = nlmsg_alloc();
4810 if (!msg)
4811 return -ENOMEM;
4812
4813 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
4814 NL80211_CMD_SET_BSS, 0);
4815
4816 for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0; i++)
4817 rates[rates_len++] = basic_rates[i] / 5;
4818
4819 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
4820
a2e40bb6 4821 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
4822
4823 return send_and_recv_msgs(drv, msg, NULL, NULL);
4824 nla_put_failure:
4825 return -ENOBUFS;
4826}
4827
e3802622
JM
4828#endif /* HOSTAPD */
4829
c5121837 4830
c5121837
JM
4831/* Set kernel driver on given frequency (MHz) */
4832static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
4833{
a2e40bb6
FF
4834 struct i802_bss *bss = priv;
4835 struct wpa_driver_nl80211_data *drv = bss->drv;
f019981a
JM
4836 return wpa_driver_nl80211_set_freq(drv, freq->freq, freq->ht_enabled,
4837 freq->sec_channel_offset);
c5121837
JM
4838}
4839
4840
e3802622
JM
4841#ifdef HOSTAPD
4842
c5121837
JM
4843static int i802_set_rts(void *priv, int rts)
4844{
a2e40bb6
FF
4845 struct i802_bss *bss = priv;
4846 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
4847 struct nl_msg *msg;
4848 int ret = -ENOBUFS;
4849 u32 val;
c5121837 4850
ad649451
JM
4851 msg = nlmsg_alloc();
4852 if (!msg)
4853 return -ENOMEM;
c5121837 4854
ad649451
JM
4855 if (rts >= 2347)
4856 val = (u32) -1;
4857 else
4858 val = rts;
c5121837 4859
ad649451
JM
4860 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4861 0, NL80211_CMD_SET_WIPHY, 0);
4862 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4863 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
4864
4865 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4866 if (!ret)
4867 return 0;
4868nla_put_failure:
4869 wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
4870 "%d (%s)", rts, ret, strerror(-ret));
4871 return ret;
c5121837
JM
4872}
4873
4874
4875static int i802_set_frag(void *priv, int frag)
4876{
a2e40bb6
FF
4877 struct i802_bss *bss = priv;
4878 struct wpa_driver_nl80211_data *drv = bss->drv;
ad649451
JM
4879 struct nl_msg *msg;
4880 int ret = -ENOBUFS;
4881 u32 val;
c5121837 4882
ad649451
JM
4883 msg = nlmsg_alloc();
4884 if (!msg)
4885 return -ENOMEM;
c5121837 4886
ad649451
JM
4887 if (frag >= 2346)
4888 val = (u32) -1;
4889 else
4890 val = frag;
c5121837 4891
ad649451
JM
4892 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4893 0, NL80211_CMD_SET_WIPHY, 0);
4894 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4895 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
4896
4897 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4898 if (!ret)
4899 return 0;
4900nla_put_failure:
4901 wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
4902 "%d: %d (%s)", frag, ret, strerror(-ret));
4903 return ret;
c5121837
JM
4904}
4905
4906
c5121837
JM
4907static int i802_flush(void *priv)
4908{
a2e40bb6
FF
4909 struct i802_bss *bss = priv;
4910 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
4911 struct nl_msg *msg;
4912
4913 msg = nlmsg_alloc();
4914 if (!msg)
4915 return -1;
4916
4917 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4918 0, NL80211_CMD_DEL_STATION, 0);
4919
4920 /*
4921 * XXX: FIX! this needs to flush all VLANs too
4922 */
4923 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 4924 if_nametoindex(bss->ifname));
c5121837
JM
4925
4926 return send_and_recv_msgs(drv, msg, NULL, NULL);
4927 nla_put_failure:
4928 return -ENOBUFS;
4929}
4930
4931
4932static int get_sta_handler(struct nl_msg *msg, void *arg)
4933{
4934 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4935 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4936 struct hostap_sta_driver_data *data = arg;
4937 struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
4938 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
4939 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
4940 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
4941 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
4942 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
4943 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
4944 };
4945
4946 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4947 genlmsg_attrlen(gnlh, 0), NULL);
4948
4949 /*
4950 * TODO: validate the interface and mac address!
4951 * Otherwise, there's a race condition as soon as
4952 * the kernel starts sending station notifications.
4953 */
4954
4955 if (!tb[NL80211_ATTR_STA_INFO]) {
4956 wpa_printf(MSG_DEBUG, "sta stats missing!");
4957 return NL_SKIP;
4958 }
4959 if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
4960 tb[NL80211_ATTR_STA_INFO],
4961 stats_policy)) {
4962 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
4963 return NL_SKIP;
4964 }
4965
4966 if (stats[NL80211_STA_INFO_INACTIVE_TIME])
4967 data->inactive_msec =
4968 nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
4969 if (stats[NL80211_STA_INFO_RX_BYTES])
4970 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
4971 if (stats[NL80211_STA_INFO_TX_BYTES])
4972 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
4973 if (stats[NL80211_STA_INFO_RX_PACKETS])
4974 data->rx_packets =
4975 nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
4976 if (stats[NL80211_STA_INFO_TX_PACKETS])
4977 data->tx_packets =
4978 nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
4979
4980 return NL_SKIP;
4981}
4982
4983static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
4984 const u8 *addr)
4985{
a2e40bb6
FF
4986 struct i802_bss *bss = priv;
4987 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
4988 struct nl_msg *msg;
4989
4990 os_memset(data, 0, sizeof(*data));
4991 msg = nlmsg_alloc();
4992 if (!msg)
4993 return -ENOMEM;
4994
4995 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4996 0, NL80211_CMD_GET_STATION, 0);
4997
4998 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
a2e40bb6 4999 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
5000
5001 return send_and_recv_msgs(drv, msg, get_sta_handler, data);
5002 nla_put_failure:
5003 return -ENOBUFS;
5004}
5005
5006
c5121837
JM
5007static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
5008 int cw_min, int cw_max, int burst_time)
5009{
a2e40bb6
FF
5010 struct i802_bss *bss = priv;
5011 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
5012 struct nl_msg *msg;
5013 struct nlattr *txq, *params;
5014
5015 msg = nlmsg_alloc();
5016 if (!msg)
5017 return -1;
5018
5019 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
5020 0, NL80211_CMD_SET_WIPHY, 0);
5021
a2e40bb6 5022 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
5023
5024 txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
5025 if (!txq)
5026 goto nla_put_failure;
5027
5028 /* We are only sending parameters for a single TXQ at a time */
5029 params = nla_nest_start(msg, 1);
5030 if (!params)
5031 goto nla_put_failure;
5032
7e3c1781
JM
5033 switch (queue) {
5034 case 0:
5035 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO);
5036 break;
5037 case 1:
5038 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI);
5039 break;
5040 case 2:
5041 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE);
5042 break;
5043 case 3:
5044 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK);
5045 break;
5046 }
c5121837
JM
5047 /* Burst time is configured in units of 0.1 msec and TXOP parameter in
5048 * 32 usec, so need to convert the value here. */
5049 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
5050 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
5051 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
5052 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
5053
5054 nla_nest_end(msg, params);
5055
5056 nla_nest_end(msg, txq);
5057
5058 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
5059 return 0;
5060 nla_put_failure:
5061 return -1;
5062}
5063
5064
c5121837
JM
5065static int i802_set_bss(void *priv, int cts, int preamble, int slot)
5066{
a2e40bb6
FF
5067 struct i802_bss *bss = priv;
5068 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837
JM
5069 struct nl_msg *msg;
5070
5071 msg = nlmsg_alloc();
5072 if (!msg)
5073 return -ENOMEM;
5074
5075 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
5076 NL80211_CMD_SET_BSS, 0);
5077
5078 if (cts >= 0)
5079 NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
5080 if (preamble >= 0)
5081 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
5082 if (slot >= 0)
5083 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
5084
a2e40bb6 5085 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
c5121837
JM
5086
5087 return send_and_recv_msgs(drv, msg, NULL, NULL);
5088 nla_put_failure:
5089 return -ENOBUFS;
5090}
5091
5092
5093static int i802_set_cts_protect(void *priv, int value)
5094{
5095 return i802_set_bss(priv, value, -1, -1);
5096}
5097
5098
5099static int i802_set_preamble(void *priv, int value)
5100{
5101 return i802_set_bss(priv, -1, value, -1);
5102}
5103
5104
5105static int i802_set_short_slot_time(void *priv, int value)
5106{
5107 return i802_set_bss(priv, -1, -1, value);
5108}
5109
5110
c5121837
JM
5111static int i802_set_sta_vlan(void *priv, const u8 *addr,
5112 const char *ifname, int vlan_id)
5113{
a2e40bb6
FF
5114 struct i802_bss *bss = priv;
5115 struct wpa_driver_nl80211_data *drv = bss->drv;
c5121837 5116 struct nl_msg *msg;
cd1d72c1 5117 int ret = -ENOBUFS;
c5121837
JM
5118
5119 msg = nlmsg_alloc();
5120 if (!msg)
5121 return -ENOMEM;
5122
5123 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
5124 0, NL80211_CMD_SET_STATION, 0);
5125
5126 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
a2e40bb6 5127 if_nametoindex(bss->ifname));
c5121837 5128 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1c766b09 5129 NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
c5121837
JM
5130 if_nametoindex(ifname));
5131
cd1d72c1
JM
5132 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5133 if (ret < 0) {
5134 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
5135 MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
5136 MAC2STR(addr), ifname, vlan_id, ret,
5137 strerror(-ret));
5138 }
c5121837 5139 nla_put_failure:
cd1d72c1 5140 return ret;
c5121837
JM
5141}
5142
5143
d38ae2ea
FF
5144static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
5145 const char *bridge_ifname)
fbbfcbac 5146{
a2e40bb6
FF
5147 struct i802_bss *bss = priv;
5148 struct wpa_driver_nl80211_data *drv = bss->drv;
e748062b 5149 char name[IFNAMSIZ + 1];
fbbfcbac 5150
a2e40bb6 5151 os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
e748062b
JM
5152 wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
5153 " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
fbbfcbac 5154 if (val) {
d38ae2ea
FF
5155 if (!if_nametoindex(name)) {
5156 if (nl80211_create_iface(drv, name,
5157 NL80211_IFTYPE_AP_VLAN,
5158 NULL, 1) < 0)
5159 return -1;
5160 if (bridge_ifname &&
5161 linux_br_add_if(drv->ioctl_sock, bridge_ifname,
5162 name) < 0)
5163 return -1;
5164 }
34f2f814 5165 linux_set_iface_flags(drv->ioctl_sock, name, 1);
fbbfcbac
FF
5166 return i802_set_sta_vlan(priv, addr, name, 0);
5167 } else {
a2e40bb6 5168 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
fbbfcbac
FF
5169 return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN,
5170 name);
5171 }
5172}
5173
5174
c5121837
JM
5175static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
5176{
5177 struct wpa_driver_nl80211_data *drv = eloop_ctx;
5178 struct sockaddr_ll lladdr;
5179 unsigned char buf[3000];
5180 int len;
5181 socklen_t fromlen = sizeof(lladdr);
5182
5183 len = recvfrom(sock, buf, sizeof(buf), 0,
5184 (struct sockaddr *)&lladdr, &fromlen);
5185 if (len < 0) {
5186 perror("recv");
5187 return;
5188 }
5189
baac6490
JM
5190 if (have_ifidx(drv, lladdr.sll_ifindex))
5191 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
c5121837
JM
5192}
5193
5194
c5121837
JM
5195static int i802_get_inact_sec(void *priv, const u8 *addr)
5196{
5197 struct hostap_sta_driver_data data;
5198 int ret;
5199
5200 data.inactive_msec = (unsigned long) -1;
5201 ret = i802_read_sta_data(priv, &data, addr);
5202 if (ret || data.inactive_msec == (unsigned long) -1)
5203 return -1;
5204 return data.inactive_msec / 1000;
5205}
5206
5207
5208static int i802_sta_clear_stats(void *priv, const u8 *addr)
5209{
5210#if 0
5211 /* TODO */
5212#endif
5213 return 0;
5214}
5215
5216
731723a5
JM
5217static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
5218 int reason)
c5121837 5219{
a2e40bb6 5220 struct i802_bss *bss = priv;
c5121837
JM
5221 struct ieee80211_mgmt mgmt;
5222
5223 memset(&mgmt, 0, sizeof(mgmt));
5224 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
5225 WLAN_FC_STYPE_DEAUTH);
5226 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
5227 memcpy(mgmt.sa, own_addr, ETH_ALEN);
5228 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 5229 mgmt.u.deauth.reason_code = host_to_le16(reason);
a2e40bb6 5230 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61
JM
5231 IEEE80211_HDRLEN +
5232 sizeof(mgmt.u.deauth));
c5121837
JM
5233}
5234
5235
731723a5
JM
5236static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
5237 int reason)
c5121837 5238{
a2e40bb6 5239 struct i802_bss *bss = priv;
c5121837
JM
5240 struct ieee80211_mgmt mgmt;
5241
5242 memset(&mgmt, 0, sizeof(mgmt));
5243 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
5244 WLAN_FC_STYPE_DISASSOC);
5245 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
5246 memcpy(mgmt.sa, own_addr, ETH_ALEN);
5247 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 5248 mgmt.u.disassoc.reason_code = host_to_le16(reason);
a2e40bb6 5249 return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9f324b61
JM
5250 IEEE80211_HDRLEN +
5251 sizeof(mgmt.u.disassoc));
c5121837
JM
5252}
5253
5254
94627f6c
JM
5255static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
5256 const char *brname, const char *ifname)
5257{
5258 int ifindex;
5259 char in_br[IFNAMSIZ];
5260
5261 os_strlcpy(drv->brname, brname, IFNAMSIZ);
5262 ifindex = if_nametoindex(brname);
5263 if (ifindex == 0) {
5264 /*
5265 * Bridge was configured, but the bridge device does
5266 * not exist. Try to add it now.
5267 */
5268 if (linux_br_add(drv->ioctl_sock, brname) < 0) {
5269 wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
5270 "bridge interface %s: %s",
5271 brname, strerror(errno));
5272 return -1;
5273 }
5274 drv->added_bridge = 1;
5275 add_ifidx(drv, if_nametoindex(brname));
5276 }
5277
5278 if (linux_br_get(in_br, ifname) == 0) {
5279 if (os_strcmp(in_br, brname) == 0)
5280 return 0; /* already in the bridge */
5281
5282 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
5283 "bridge %s", ifname, in_br);
5284 if (linux_br_del_if(drv->ioctl_sock, in_br, ifname) < 0) {
5285 wpa_printf(MSG_ERROR, "nl80211: Failed to "
5286 "remove interface %s from bridge "
5287 "%s: %s",
5288 ifname, brname, strerror(errno));
5289 return -1;
5290 }
5291 }
5292
5293 wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
5294 ifname, brname);
5295 if (linux_br_add_if(drv->ioctl_sock, brname, ifname) < 0) {
5296 wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
5297 "into bridge %s: %s",
5298 ifname, brname, strerror(errno));
5299 return -1;
5300 }
5301 drv->added_if_into_bridge = 1;
5302
5303 return 0;
5304}
5305
5306
92f475b4
JM
5307static void *i802_init(struct hostapd_data *hapd,
5308 struct wpa_init_params *params)
c5121837
JM
5309{
5310 struct wpa_driver_nl80211_data *drv;
a2e40bb6 5311 struct i802_bss *bss;
c5121837 5312 size_t i;
94627f6c
JM
5313 char brname[IFNAMSIZ];
5314 int ifindex, br_ifindex;
5315 int br_added = 0;
c5121837 5316
a2e40bb6
FF
5317 bss = wpa_driver_nl80211_init(hapd, params->ifname);
5318 if (bss == NULL)
c5121837 5319 return NULL;
c5121837 5320
a2e40bb6 5321 drv = bss->drv;
94627f6c
JM
5322 if (linux_br_get(brname, params->ifname) == 0) {
5323 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
5324 params->ifname, brname);
5325 br_ifindex = if_nametoindex(brname);
5326 } else {
5327 brname[0] = '\0';
5328 br_ifindex = 0;
5329 }
5330
c5121837
JM
5331 drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
5332 drv->if_indices = drv->default_if_indices;
92f475b4 5333 for (i = 0; i < params->num_bridge; i++) {
94627f6c
JM
5334 if (params->bridge[i]) {
5335 ifindex = if_nametoindex(params->bridge[i]);
5336 if (ifindex)
5337 add_ifidx(drv, ifindex);
5338 if (ifindex == br_ifindex)
5339 br_added = 1;
5340 }
c5121837 5341 }
94627f6c
JM
5342 if (!br_added && br_ifindex &&
5343 (params->num_bridge == 0 || !params->bridge[0]))
5344 add_ifidx(drv, br_ifindex);
c5121837 5345
ad1e68e6
JM
5346 /* start listening for EAPOL on the default AP interface */
5347 add_ifidx(drv, drv->ifindex);
5348
a2e40bb6 5349 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0))
6980c191 5350 goto failed;
ad1e68e6 5351
6980c191 5352 if (params->bssid) {
a2e40bb6 5353 if (linux_set_ifhwaddr(drv->ioctl_sock, bss->ifname,
2ac9688e 5354 params->bssid))
460456f8
JM
5355 goto failed;
5356 }
ad1e68e6 5357
a2e40bb6 5358 if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_AP)) {
ad1e68e6 5359 wpa_printf(MSG_ERROR, "nl80211: Failed to set interface %s "
a2e40bb6 5360 "into AP mode", bss->ifname);
bbaf0837 5361 goto failed;
ad1e68e6
JM
5362 }
5363
94627f6c
JM
5364 if (params->num_bridge && params->bridge[0] &&
5365 i802_check_bridge(drv, params->bridge[0], params->ifname) < 0)
5366 goto failed;
5367
a2e40bb6 5368 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1))
bbaf0837 5369 goto failed;
ad1e68e6
JM
5370
5371 drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
5372 if (drv->eapol_sock < 0) {
5373 perror("socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE)");
bbaf0837 5374 goto failed;
ad1e68e6
JM
5375 }
5376
5377 if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
5378 {
5379 printf("Could not register read socket for eapol\n");
c5121837 5380 goto failed;
ad1e68e6
JM
5381 }
5382
a2e40bb6 5383 if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, params->own_addr))
bbaf0837 5384 goto failed;
c5121837 5385
a2e40bb6 5386 return bss;
c5121837
JM
5387
5388failed:
460456f8 5389 nl80211_remove_monitor_interface(drv);
c5121837
JM
5390 if (drv->ioctl_sock >= 0)
5391 close(drv->ioctl_sock);
c5121837
JM
5392
5393 genl_family_put(drv->nl80211);
5394 nl_cache_free(drv->nl_cache);
a65a9aed 5395 nl80211_handle_destroy(drv->nl_handle);
c5121837
JM
5396 nl_cb_put(drv->nl_cb);
5397
bbaf0837
JM
5398 os_free(drv);
5399 return NULL;
5400}
c5121837 5401
c5121837 5402
bbaf0837
JM
5403static void i802_deinit(void *priv)
5404{
5405 wpa_driver_nl80211_deinit(priv);
c5121837
JM
5406}
5407
5408#endif /* HOSTAPD */
5409
5410
22a7c9d7
JM
5411static enum nl80211_iftype wpa_driver_nl80211_if_type(
5412 enum wpa_driver_if_type type)
5413{
5414 switch (type) {
5415 case WPA_IF_STATION:
75bde05d
JM
5416 case WPA_IF_P2P_CLIENT:
5417 case WPA_IF_P2P_GROUP:
22a7c9d7
JM
5418 return NL80211_IFTYPE_STATION;
5419 case WPA_IF_AP_VLAN:
5420 return NL80211_IFTYPE_AP_VLAN;
5421 case WPA_IF_AP_BSS:
75bde05d 5422 case WPA_IF_P2P_GO:
22a7c9d7
JM
5423 return NL80211_IFTYPE_AP;
5424 }
5425 return -1;
5426}
5427
5428
7ab68865 5429static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
8043e725 5430 const char *ifname, const u8 *addr,
f3585c8a
JM
5431 void *bss_ctx, void **drv_priv,
5432 char *force_ifname, u8 *if_addr)
22a7c9d7 5433{
a2e40bb6
FF
5434 struct i802_bss *bss = priv;
5435 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7
JM
5436 int ifidx;
5437#ifdef HOSTAPD
a2e40bb6 5438 struct i802_bss *new_bss = NULL;
22a7c9d7
JM
5439
5440 if (type == WPA_IF_AP_BSS) {
a2e40bb6
FF
5441 new_bss = os_zalloc(sizeof(*new_bss));
5442 if (new_bss == NULL)
22a7c9d7
JM
5443 return -1;
5444 }
5445#endif /* HOSTAPD */
5446
f3585c8a
JM
5447 if (addr)
5448 os_memcpy(if_addr, addr, ETH_ALEN);
22a7c9d7 5449 ifidx = nl80211_create_iface(drv, ifname,
fbbfcbac
FF
5450 wpa_driver_nl80211_if_type(type), addr,
5451 0);
22a7c9d7
JM
5452 if (ifidx < 0) {
5453#ifdef HOSTAPD
a2e40bb6 5454 os_free(new_bss);
22a7c9d7
JM
5455#endif /* HOSTAPD */
5456 return -1;
5457 }
5458
f3585c8a 5459 if (!addr &&
c55f774d
JM
5460 linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, if_addr) < 0) {
5461 nl80211_remove_iface(drv, ifidx);
f3585c8a 5462 return -1;
c55f774d
JM
5463 }
5464
5465#ifdef CONFIG_P2P
5466 if (!addr &&
5467 (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
5468 type == WPA_IF_P2P_GO)) {
5469 /* Enforce unique P2P Interface Address */
5470 u8 new_addr[ETH_ALEN], own_addr[ETH_ALEN];
5471
5472 if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, own_addr)
5473 < 0 ||
5474 linux_get_ifhwaddr(drv->ioctl_sock, ifname, new_addr) < 0)
5475 {
5476 nl80211_remove_iface(drv, ifidx);
5477 return -1;
5478 }
5479 if (os_memcmp(own_addr, new_addr, ETH_ALEN) == 0) {
5480 wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
5481 "for P2P group interface");
5482 /* TODO: more complete implementation to handle
5483 * multiple groups etc.. */
5484 if (own_addr[0] & 0x02) {
5485 nl80211_remove_iface(drv, ifidx);
5486 return -1;
5487 }
5488 new_addr[0] |= 0x02;
5489 if (linux_set_ifhwaddr(drv->ioctl_sock, ifname,
5490 new_addr) < 0) {
5491 nl80211_remove_iface(drv, ifidx);
5492 return -1;
5493 }
5494 os_memcpy(if_addr, new_addr, ETH_ALEN);
5495 }
5496 }
5497#endif /* CONFIG_P2P */
f3585c8a 5498
22a7c9d7
JM
5499#ifdef HOSTAPD
5500 if (type == WPA_IF_AP_BSS) {
34f2f814
JM
5501 if (linux_set_iface_flags(drv->ioctl_sock, ifname, 1)) {
5502 nl80211_remove_iface(drv, ifidx);
07179987 5503 os_free(new_bss);
22a7c9d7
JM
5504 return -1;
5505 }
a2e40bb6
FF
5506 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
5507 new_bss->ifindex = ifidx;
5508 new_bss->drv = drv;
5509 new_bss->next = drv->first_bss.next;
5510 drv->first_bss.next = new_bss;
5511 if (drv_priv)
5512 *drv_priv = new_bss;
22a7c9d7
JM
5513 }
5514#endif /* HOSTAPD */
5515
5516 return 0;
5517}
5518
5519
5520static int wpa_driver_nl80211_if_remove(void *priv,
5521 enum wpa_driver_if_type type,
5522 const char *ifname)
5523{
a2e40bb6
FF
5524 struct i802_bss *bss = priv;
5525 struct wpa_driver_nl80211_data *drv = bss->drv;
22a7c9d7
JM
5526 int ifindex = if_nametoindex(ifname);
5527
e748062b
JM
5528 wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d",
5529 __func__, type, ifname, ifindex);
5530 if (ifindex <= 0)
5531 return -1;
22a7c9d7
JM
5532 nl80211_remove_iface(drv, ifindex);
5533
5534#ifdef HOSTAPD
a2e40bb6
FF
5535 if (type != WPA_IF_AP_BSS)
5536 return 0;
5537
5538 if (bss != &drv->first_bss) {
5539 struct i802_bss *tbss = &drv->first_bss;
5540
5541 while (tbss) {
5542 if (tbss->next != bss)
5543 continue;
5544
5545 tbss->next = bss->next;
5546 os_free(bss);
5547 break;
22a7c9d7
JM
5548 }
5549 }
5550#endif /* HOSTAPD */
5551
5552 return 0;
5553}
5554
5555
55777702
JM
5556static int cookie_handler(struct nl_msg *msg, void *arg)
5557{
5558 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5559 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5560 u64 *cookie = arg;
5561 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5562 genlmsg_attrlen(gnlh, 0), NULL);
5563 if (tb[NL80211_ATTR_COOKIE])
5564 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
5565 return NL_SKIP;
5566}
5567
5568
9884f9cc
JB
5569static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv,
5570 unsigned int freq, const u8 *buf,
5571 size_t buf_len, u64 *cookie_out)
5572{
5573 struct nl_msg *msg;
5574 u64 cookie;
5575 int ret = -1;
5576
5577 msg = nlmsg_alloc();
5578 if (!msg)
5579 return -1;
5580
5581 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
5582 NL80211_CMD_FRAME, 0);
5583
5584 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5585 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
5586 NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
5587
5588 cookie = 0;
5589 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
5590 msg = NULL;
5591 if (ret) {
5592 wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
5593 "(%s)", ret, strerror(-ret));
5594 goto nla_put_failure;
5595 }
5596 wpa_printf(MSG_DEBUG, "nl80211: Frame TX command accepted; "
5597 "cookie 0x%llx", (long long unsigned int) cookie);
5598
5599 if (cookie_out)
5600 *cookie_out = cookie;
5601
5602nla_put_failure:
5603 nlmsg_free(msg);
5604 return ret;
5605}
5606
5607
58f6fbe0
JM
5608static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
5609 const u8 *dst, const u8 *src,
5610 const u8 *bssid,
5611 const u8 *data, size_t data_len)
5612{
a2e40bb6
FF
5613 struct i802_bss *bss = priv;
5614 struct wpa_driver_nl80211_data *drv = bss->drv;
58f6fbe0 5615 int ret = -1;
58f6fbe0
JM
5616 u8 *buf;
5617 struct ieee80211_hdr *hdr;
58f6fbe0
JM
5618
5619 wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d)",
5620 drv->ifindex);
5621
5622 buf = os_zalloc(24 + data_len);
5623 if (buf == NULL)
5624 return ret;
5625 os_memcpy(buf + 24, data, data_len);
5626 hdr = (struct ieee80211_hdr *) buf;
5627 hdr->frame_control =
5628 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
5629 os_memcpy(hdr->addr1, dst, ETH_ALEN);
5630 os_memcpy(hdr->addr2, src, ETH_ALEN);
5631 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
5632
9884f9cc 5633 if (drv->nlmode == NL80211_IFTYPE_AP)
58f6fbe0 5634 ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len);
9884f9cc
JB
5635 else
5636 ret = nl80211_send_frame_cmd(drv, freq, buf, 24 + data_len,
5637 &drv->send_action_cookie);
58f6fbe0 5638
f8bf1421 5639 os_free(buf);
58f6fbe0
JM
5640 return ret;
5641}
5642
5643
55777702
JM
5644static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
5645 unsigned int duration)
5646{
a2e40bb6
FF
5647 struct i802_bss *bss = priv;
5648 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
5649 struct nl_msg *msg;
5650 int ret;
5651 u64 cookie;
5652
5653 msg = nlmsg_alloc();
5654 if (!msg)
5655 return -1;
5656
5657 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
5658 NL80211_CMD_REMAIN_ON_CHANNEL, 0);
5659
5660 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5661 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
5662 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
5663
5664 cookie = 0;
5665 ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
5666 if (ret == 0) {
5667 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
5668 "0x%llx for freq=%u MHz duration=%u",
5669 (long long unsigned int) cookie, freq, duration);
5670 drv->remain_on_chan_cookie = cookie;
5671 return 0;
5672 }
5673 wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
15ed5535
JM
5674 "(freq=%d duration=%u): %d (%s)",
5675 freq, duration, ret, strerror(-ret));
55777702
JM
5676nla_put_failure:
5677 return -1;
5678}
5679
5680
5681static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
5682{
a2e40bb6
FF
5683 struct i802_bss *bss = priv;
5684 struct wpa_driver_nl80211_data *drv = bss->drv;
55777702
JM
5685 struct nl_msg *msg;
5686 int ret;
5687
5688 if (!drv->pending_remain_on_chan) {
5689 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
5690 "to cancel");
5691 return -1;
5692 }
5693
5694 wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
5695 "0x%llx",
5696 (long long unsigned int) drv->remain_on_chan_cookie);
5697
5698 msg = nlmsg_alloc();
5699 if (!msg)
5700 return -1;
5701
5702 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
5703 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 0);
5704
5705 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5706 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
5707
5708 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5709 if (ret == 0)
5710 return 0;
5711 wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
5712 "%d (%s)", ret, strerror(-ret));
5713nla_put_failure:
5714 return -1;
5715}
5716
5717
504e905c
JM
5718static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
5719{
a2e40bb6
FF
5720 struct i802_bss *bss = priv;
5721 struct wpa_driver_nl80211_data *drv = bss->drv;
504e905c
JM
5722
5723 if (drv->nlmode != NL80211_IFTYPE_STATION) {
5724 wpa_printf(MSG_DEBUG, "nl80211: probe_req_report control only "
5725 "allowed in station mode (iftype=%d)",
5726 drv->nlmode);
5727 return -1;
5728 }
504e905c 5729
5582a5d1
JB
5730 if (!report) {
5731 if (drv->nl_handle_preq) {
5732 eloop_unregister_read_sock(
5733 nl_socket_get_fd(drv->nl_handle_preq));
5734 nl_cache_free(drv->nl_cache_preq);
5735 nl80211_handle_destroy(drv->nl_handle_preq);
5736 drv->nl_handle_preq = NULL;
5737 }
5738 return 0;
5739 }
5740
5741 if (drv->nl_handle_preq) {
5742 wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
5743 "already on!");
5744 return 0;
5745 }
5746
5747 drv->nl_handle_preq = nl80211_handle_alloc(drv->nl_cb);
5748 if (drv->nl_handle_preq == NULL) {
5749 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate "
5750 "netlink callbacks (preq)");
5751 goto out_err1;
5752 }
5753
5754 if (genl_connect(drv->nl_handle_preq)) {
5755 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to "
5756 "generic netlink (preq)");
5757 goto out_err2;
5758 return -1;
504e905c
JM
5759 }
5760
5582a5d1
JB
5761#ifdef CONFIG_LIBNL20
5762 if (genl_ctrl_alloc_cache(drv->nl_handle_preq,
5763 &drv->nl_cache_preq) < 0) {
5764 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
5765 "netlink cache (preq)");
5766 goto out_err2;
5767 }
5768#else /* CONFIG_LIBNL20 */
5769 drv->nl_cache_preq = genl_ctrl_alloc_cache(drv->nl_handle_preq);
5770 if (drv->nl_cache_preq == NULL) {
5771 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
5772 "netlink cache (preq)");
5773 goto out_err2;
5774 }
5775#endif /* CONFIG_LIBNL20 */
5776
5777 if (nl80211_register_frame(drv, drv->nl_handle_preq,
5778 (WLAN_FC_TYPE_MGMT << 2) |
5779 (WLAN_FC_STYPE_PROBE_REQ << 4),
5780 NULL, 0) < 0) {
5781 goto out_err3;
5782 }
5783
5784 eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle_preq),
5785 wpa_driver_nl80211_event_receive, drv,
5786 drv->nl_handle_preq);
5787
504e905c 5788 return 0;
5582a5d1
JB
5789
5790 out_err3:
5791 nl_cache_free(drv->nl_cache_preq);
5792 out_err2:
5793 nl80211_handle_destroy(drv->nl_handle_preq);
5794 drv->nl_handle_preq = NULL;
5795 out_err1:
5796 return -1;
504e905c
JM
5797}
5798
5799
4e5cb1a3
JM
5800static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
5801 int ifindex, int disabled)
5802{
5803 struct nl_msg *msg;
5804 struct nlattr *bands, *band;
5805 int ret;
5806
5807 msg = nlmsg_alloc();
5808 if (!msg)
5809 return -1;
5810
5811 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
5812 NL80211_CMD_SET_TX_BITRATE_MASK, 0);
5813 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5814
5815 bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
5816 if (!bands)
5817 goto nla_put_failure;
5818
5819 /*
5820 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
5821 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
5822 * rates. All 5 GHz rates are left enabled.
5823 */
5824 band = nla_nest_start(msg, NL80211_BAND_2GHZ);
5825 if (!band)
5826 goto nla_put_failure;
5827 NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
5828 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
5829 nla_nest_end(msg, band);
5830
5831 nla_nest_end(msg, bands);
5832
5833 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5834 msg = NULL;
5835 if (ret) {
5836 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
5837 "(%s)", ret, strerror(-ret));
5838 }
5839
5840 return ret;
5841
5842nla_put_failure:
5843 nlmsg_free(msg);
5844 return -1;
5845}
5846
5847
5848static int wpa_driver_nl80211_disable_11b_rates(void *priv, int disabled)
5849{
a2e40bb6
FF
5850 struct i802_bss *bss = priv;
5851 struct wpa_driver_nl80211_data *drv = bss->drv;
4e5cb1a3
JM
5852 drv->disable_11b_rates = disabled;
5853 return nl80211_disable_11b_rates(drv, drv->ifindex, disabled);
5854}
5855
5856
af473088
JM
5857static int wpa_driver_nl80211_deinit_ap(void *priv)
5858{
a2e40bb6
FF
5859 struct i802_bss *bss = priv;
5860 struct wpa_driver_nl80211_data *drv = bss->drv;
af473088
JM
5861 if (drv->nlmode != NL80211_IFTYPE_AP)
5862 return -1;
5863 wpa_driver_nl80211_del_beacon(drv);
a2e40bb6 5864 return wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
af473088
JM
5865}
5866
5867
207ef3fb
JM
5868static void wpa_driver_nl80211_resume(void *priv)
5869{
a2e40bb6
FF
5870 struct i802_bss *bss = priv;
5871 struct wpa_driver_nl80211_data *drv = bss->drv;
5872 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1)) {
207ef3fb
JM
5873 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on "
5874 "resume event");
5875 }
5876}
5877
5878
7b90c16a
JM
5879static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
5880 const u8 *ies, size_t ies_len)
5881{
5882 struct i802_bss *bss = priv;
5883 struct wpa_driver_nl80211_data *drv = bss->drv;
5884 int ret;
5885 u8 *data, *pos;
5886 size_t data_len;
5887 u8 own_addr[ETH_ALEN];
5888
5889 if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, own_addr) < 0)
5890 return -1;
5891
5892 if (action != 1) {
5893 wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
5894 "action %d", action);
5895 return -1;
5896 }
5897
5898 /*
5899 * Action frame payload:
5900 * Category[1] = 6 (Fast BSS Transition)
5901 * Action[1] = 1 (Fast BSS Transition Request)
5902 * STA Address
5903 * Target AP Address
5904 * FT IEs
5905 */
5906
73fc617d
JM
5907 data_len = 2 + 2 * ETH_ALEN + ies_len;
5908 data = os_malloc(data_len);
7b90c16a
JM
5909 if (data == NULL)
5910 return -1;
5911 pos = data;
5912 *pos++ = 0x06; /* FT Action category */
5913 *pos++ = action;
5914 os_memcpy(pos, own_addr, ETH_ALEN);
5915 pos += ETH_ALEN;
5916 os_memcpy(pos, target_ap, ETH_ALEN);
5917 pos += ETH_ALEN;
5918 os_memcpy(pos, ies, ies_len);
5919
5920 ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, drv->bssid,
5921 own_addr, drv->bssid,
5922 data, data_len);
5923 os_free(data);
5924
5925 return ret;
5926}
5927
5928
b625473c
JM
5929static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
5930{
5931 struct i802_bss *bss = priv;
5932 struct wpa_driver_nl80211_data *drv = bss->drv;
5933 struct nl_msg *msg, *cqm = NULL;
5934
5935 wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
5936 "hysteresis=%d", threshold, hysteresis);
5937
5938 msg = nlmsg_alloc();
5939 if (!msg)
5940 return -1;
5941
5942 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
5943 0, NL80211_CMD_SET_CQM, 0);
5944
5945 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
5946
5947 cqm = nlmsg_alloc();
5948 if (cqm == NULL)
5949 return -1;
5950
5951 NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
5952 NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
5953 nla_put_nested(msg, NL80211_ATTR_CQM, cqm);
5954
5955 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
5956 return 0;
5957 msg = NULL;
5958
5959nla_put_failure:
5960 if (cqm)
5961 nlmsg_free(cqm);
5962 nlmsg_free(msg);
5963 return -1;
5964}
5965
5966
b91ab76e
JM
5967static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
5968 int encrypt)
5969{
5970 struct i802_bss *bss = priv;
5971 struct wpa_driver_nl80211_data *drv = bss->drv;
5972 return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt);
5973}
5974
5975
6ee04cfc
JB
5976static int nl80211_set_intra_bss(void *priv, int enabled)
5977{
5978 struct i802_bss *bss = priv;
5979 struct wpa_driver_nl80211_data *drv = bss->drv;
5980 struct nl_msg *msg;
5981
5982 msg = nlmsg_alloc();
5983 if (!msg)
5984 return -ENOMEM;
5985
5986 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
5987 NL80211_CMD_SET_BSS, 0);
5988
5989 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
5990 NLA_PUT_U8(msg, NL80211_ATTR_AP_ISOLATE, !enabled);
5991
5992 return send_and_recv_msgs(drv, msg, NULL, NULL);
5993 nla_put_failure:
5994 return -ENOBUFS;
5995}
5996
5997
c55f774d
JM
5998static int nl80211_set_param(void *priv, const char *param)
5999{
6000 struct i802_bss *bss = priv;
6001 struct wpa_driver_nl80211_data *drv = bss->drv;
6002
6003 wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
6004 if (param == NULL)
6005 return 0;
6006
6007#ifdef CONFIG_P2P
6008 if (os_strstr(param, "use_p2p_group_interface=1")) {
6009 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
6010 "interface");
6011 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
6012 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
6013 }
6014#endif /* CONFIG_P2P */
6015
6016 return 0;
6017}
6018
6019
3f5285e8
JM
6020const struct wpa_driver_ops wpa_driver_nl80211_ops = {
6021 .name = "nl80211",
6022 .desc = "Linux nl80211/cfg80211",
6023 .get_bssid = wpa_driver_nl80211_get_bssid,
6024 .get_ssid = wpa_driver_nl80211_get_ssid,
3f5285e8 6025 .set_key = wpa_driver_nl80211_set_key,
6a1063e0 6026 .scan2 = wpa_driver_nl80211_scan,
3f5285e8
JM
6027 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
6028 .deauthenticate = wpa_driver_nl80211_deauthenticate,
6029 .disassociate = wpa_driver_nl80211_disassociate,
c2a04078 6030 .authenticate = wpa_driver_nl80211_authenticate,
3f5285e8 6031 .associate = wpa_driver_nl80211_associate,
3f5285e8
JM
6032 .init = wpa_driver_nl80211_init,
6033 .deinit = wpa_driver_nl80211_deinit,
3f5285e8
JM
6034 .get_capa = wpa_driver_nl80211_get_capa,
6035 .set_operstate = wpa_driver_nl80211_set_operstate,
01652550 6036 .set_supp_port = wpa_driver_nl80211_set_supp_port,
6d158490 6037 .set_country = wpa_driver_nl80211_set_country,
d2440ba0 6038 .set_beacon = wpa_driver_nl80211_set_beacon,
22a7c9d7
JM
6039 .if_add = wpa_driver_nl80211_if_add,
6040 .if_remove = wpa_driver_nl80211_if_remove,
071f8ac4 6041 .send_mlme = wpa_driver_nl80211_send_mlme,
c3965310 6042 .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
0f4e8b4f
JM
6043 .sta_add = wpa_driver_nl80211_sta_add,
6044 .sta_remove = wpa_driver_nl80211_sta_remove,
db149ac9 6045 .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
a8d6ffa4 6046 .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
c5121837
JM
6047#ifdef HOSTAPD
6048 .hapd_init = i802_init,
c5121837 6049 .hapd_deinit = i802_deinit,
c5121837
JM
6050 .get_seqnum = i802_get_seqnum,
6051 .flush = i802_flush,
6052 .read_sta_data = i802_read_sta_data,
c5121837
JM
6053 .sta_deauth = i802_sta_deauth,
6054 .sta_disassoc = i802_sta_disassoc,
c5121837
JM
6055 .get_inact_sec = i802_get_inact_sec,
6056 .sta_clear_stats = i802_sta_clear_stats,
c5121837
JM
6057 .set_rts = i802_set_rts,
6058 .set_frag = i802_set_frag,
c5121837 6059 .set_rate_sets = i802_set_rate_sets,
c5121837
JM
6060 .set_cts_protect = i802_set_cts_protect,
6061 .set_preamble = i802_set_preamble,
6062 .set_short_slot_time = i802_set_short_slot_time,
6063 .set_tx_queue_params = i802_set_tx_queue_params,
c5121837 6064 .set_sta_vlan = i802_set_sta_vlan,
fbbfcbac 6065 .set_wds_sta = i802_set_wds_sta,
c5121837 6066#endif /* HOSTAPD */
e3802622 6067 .set_freq = i802_set_freq,
58f6fbe0 6068 .send_action = wpa_driver_nl80211_send_action,
55777702
JM
6069 .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
6070 .cancel_remain_on_channel =
6071 wpa_driver_nl80211_cancel_remain_on_channel,
504e905c 6072 .probe_req_report = wpa_driver_nl80211_probe_req_report,
4e5cb1a3 6073 .disable_11b_rates = wpa_driver_nl80211_disable_11b_rates,
af473088 6074 .deinit_ap = wpa_driver_nl80211_deinit_ap,
207ef3fb 6075 .resume = wpa_driver_nl80211_resume,
7b90c16a 6076 .send_ft_action = nl80211_send_ft_action,
b625473c 6077 .signal_monitor = nl80211_signal_monitor,
b91ab76e 6078 .send_frame = nl80211_send_frame,
6ee04cfc 6079 .set_intra_bss = nl80211_set_intra_bss,
c55f774d 6080 .set_param = nl80211_set_param,
3f5285e8 6081};