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