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