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