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