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