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
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.
13 * Alternatively, this software may be distributed under the terms of BSD
16 * See README and COPYING for more details.
20 #include <sys/ioctl.h>
21 #include <sys/types.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 <linux/errqueue.h>
32 #include "nl80211_copy.h"
36 #include "utils/list.h"
37 #include "common/ieee802_11_defs.h"
38 #include "common/ieee802_11_common.h"
39 #include "l2_packet/l2_packet.h"
41 #include "linux_ioctl.h"
43 #include "radiotap_iter.h"
47 #ifndef SO_WIFI_STATUS
48 # if defined(__sparc__)
49 # define SO_WIFI_STATUS 0x0025
50 # elif defined(__parisc__)
51 # define SO_WIFI_STATUS 0x4022
53 # define SO_WIFI_STATUS 41
56 # define SCM_WIFI_STATUS SO_WIFI_STATUS
59 #ifndef SO_EE_ORIGIN_TXSTATUS
60 #define SO_EE_ORIGIN_TXSTATUS 4
63 #ifndef PACKET_TX_TIMESTAMP
64 #define PACKET_TX_TIMESTAMP 16
68 #include "android_drv.h"
71 /* libnl 2.0 compatibility code */
72 #define nl_handle nl_sock
73 #define nl80211_handle_alloc nl_socket_alloc_cb
74 #define nl80211_handle_destroy nl_socket_free
77 * libnl 1.1 has a bug, it tries to allocate socket numbers densely
78 * but when you free a socket again it will mess up its bitmap and
79 * and use the wrong number the next time it needs a socket ID.
80 * Therefore, we wrap the handle alloc/destroy and add our own pid
83 static uint32_t port_bitmap
[32] = { 0 };
85 static struct nl_handle
*nl80211_handle_alloc(void *cb
)
87 struct nl_handle
*handle
;
88 uint32_t pid
= getpid() & 0x3FFFFF;
91 handle
= nl_handle_alloc_cb(cb
);
93 for (i
= 0; i
< 1024; i
++) {
94 if (port_bitmap
[i
/ 32] & (1 << (i
% 32)))
96 port_bitmap
[i
/ 32] |= 1 << (i
% 32);
101 nl_socket_set_local_port(handle
, pid
);
106 static void nl80211_handle_destroy(struct nl_handle
*handle
)
108 uint32_t port
= nl_socket_get_local_port(handle
);
111 port_bitmap
[port
/ 32] &= ~(1 << (port
% 32));
113 nl_handle_destroy(handle
);
115 #endif /* CONFIG_LIBNL20 */
118 struct nl80211_handles
{
119 struct nl_handle
*handle
;
123 static int nl_create_handles(struct nl80211_handles
*handles
, struct nl_cb
*cb
,
129 handles
->handle
= nl80211_handle_alloc(cb
);
130 if (handles
->handle
== NULL
) {
131 wpa_printf(MSG_ERROR
, "nl80211: Failed to allocate netlink "
132 "callbacks (%s)", dbg
);
136 if (genl_connect(handles
->handle
)) {
137 wpa_printf(MSG_ERROR
, "nl80211: Failed to connect to generic "
138 "netlink (%s)", dbg
);
144 nl80211_handle_destroy(handles
->handle
);
149 static void nl_destroy_handles(struct nl80211_handles
*handles
)
151 if (handles
->handle
== NULL
)
153 nl80211_handle_destroy(handles
->handle
);
154 handles
->handle
= NULL
;
159 #define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
162 #define IFF_DORMANT 0x20000 /* driver signals dormant */
165 #ifndef IF_OPER_DORMANT
166 #define IF_OPER_DORMANT 5
172 struct nl80211_global
{
173 struct dl_list interfaces
;
175 struct netlink_data
*netlink
;
177 struct nl80211_handles nl
;
179 int ioctl_sock
; /* socket for ioctl() use */
182 static void nl80211_global_deinit(void *priv
);
183 static void wpa_driver_nl80211_deinit(void *priv
);
186 struct wpa_driver_nl80211_data
*drv
;
187 struct i802_bss
*next
;
189 char ifname
[IFNAMSIZ
+ 1];
190 char brname
[IFNAMSIZ
];
191 unsigned int beacon_set
:1;
192 unsigned int added_if_into_bridge
:1;
193 unsigned int added_bridge
:1;
197 struct nl80211_handles nl_preq
, nl_mgmt
;
201 struct wpa_driver_nl80211_data
{
202 struct nl80211_global
*global
;
210 int ignore_if_down_event
;
211 struct rfkill_data
*rfkill
;
212 struct wpa_driver_capa capa
;
217 int scan_complete_events
;
219 struct nl80211_handles nl_event
;
222 u8 auth_bssid
[ETH_ALEN
];
227 enum nl80211_iftype nlmode
;
228 enum nl80211_iftype ap_scan_as_station
;
229 unsigned int assoc_freq
;
233 int monitor_refcount
;
235 unsigned int disabled_11b_rates
:1;
236 unsigned int pending_remain_on_chan
:1;
237 unsigned int in_interface_list
:1;
238 unsigned int device_ap_sme
:1;
239 unsigned int poll_command_supported
:1;
240 unsigned int data_tx_status
:1;
241 unsigned int scan_for_auth
:1;
242 unsigned int retry_auth
:1;
243 unsigned int use_monitor
:1;
245 u64 remain_on_chan_cookie
;
246 u64 send_action_cookie
;
248 unsigned int last_mgmt_freq
;
250 struct wpa_driver_scan_filter
*filter_ssids
;
251 size_t num_filter_ssids
;
253 struct i802_bss first_bss
;
258 int eapol_sock
; /* socket for EAPOL frames */
260 int default_if_indices
[16];
268 /* From failed authentication command */
270 u8 auth_bssid_
[ETH_ALEN
];
272 size_t auth_ssid_len
;
276 u8 auth_wep_key
[4][16];
277 size_t auth_wep_key_len
[4];
278 int auth_wep_tx_keyidx
;
279 int auth_local_state_change
;
284 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx
,
286 static int wpa_driver_nl80211_set_mode(struct i802_bss
*bss
,
287 enum nl80211_iftype nlmode
);
289 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data
*drv
);
290 static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data
*drv
,
291 const u8
*addr
, int cmd
, u16 reason_code
,
292 int local_state_change
);
293 static void nl80211_remove_monitor_interface(
294 struct wpa_driver_nl80211_data
*drv
);
295 static int nl80211_send_frame_cmd(struct i802_bss
*bss
,
296 unsigned int freq
, unsigned int wait
,
297 const u8
*buf
, size_t buf_len
, u64
*cookie
,
298 int no_cck
, int no_ack
, int offchanok
);
299 static int wpa_driver_nl80211_probe_req_report(void *priv
, int report
);
301 static int android_pno_start(struct i802_bss
*bss
,
302 struct wpa_driver_scan_params
*params
);
303 static int android_pno_stop(struct i802_bss
*bss
);
307 static void add_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
);
308 static void del_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
);
309 static int have_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
);
310 static int wpa_driver_nl80211_if_remove(void *priv
,
311 enum wpa_driver_if_type type
,
314 static inline void add_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
)
318 static inline void del_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
)
322 static inline int have_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
)
328 static int i802_set_freq(void *priv
, struct hostapd_freq_params
*freq
);
329 static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data
*drv
,
330 int ifindex
, int disabled
);
332 static int nl80211_leave_ibss(struct wpa_driver_nl80211_data
*drv
);
333 static int wpa_driver_nl80211_authenticate_retry(
334 struct wpa_driver_nl80211_data
*drv
);
337 static int is_ap_interface(enum nl80211_iftype nlmode
)
339 return (nlmode
== NL80211_IFTYPE_AP
||
340 nlmode
== NL80211_IFTYPE_P2P_GO
);
344 static int is_sta_interface(enum nl80211_iftype nlmode
)
346 return (nlmode
== NL80211_IFTYPE_STATION
||
347 nlmode
== NL80211_IFTYPE_P2P_CLIENT
);
351 static int is_p2p_interface(enum nl80211_iftype nlmode
)
353 return (nlmode
== NL80211_IFTYPE_P2P_CLIENT
||
354 nlmode
== NL80211_IFTYPE_P2P_GO
);
358 struct nl80211_bss_info_arg
{
359 struct wpa_driver_nl80211_data
*drv
;
360 struct wpa_scan_results
*res
;
361 unsigned int assoc_freq
;
362 u8 assoc_bssid
[ETH_ALEN
];
365 static int bss_info_handler(struct nl_msg
*msg
, void *arg
);
369 static int ack_handler(struct nl_msg
*msg
, void *arg
)
376 static int finish_handler(struct nl_msg
*msg
, void *arg
)
383 static int error_handler(struct sockaddr_nl
*nla
, struct nlmsgerr
*err
,
392 static int no_seq_check(struct nl_msg
*msg
, void *arg
)
398 static int send_and_recv(struct wpa_driver_nl80211_data
*drv
,
399 struct nl_handle
*nl_handle
, struct nl_msg
*msg
,
400 int (*valid_handler
)(struct nl_msg
*, void *),
406 cb
= nl_cb_clone(drv
->global
->nl_cb
);
410 err
= nl_send_auto_complete(nl_handle
, msg
);
416 nl_cb_err(cb
, NL_CB_CUSTOM
, error_handler
, &err
);
417 nl_cb_set(cb
, NL_CB_FINISH
, NL_CB_CUSTOM
, finish_handler
, &err
);
418 nl_cb_set(cb
, NL_CB_ACK
, NL_CB_CUSTOM
, ack_handler
, &err
);
421 nl_cb_set(cb
, NL_CB_VALID
, NL_CB_CUSTOM
,
422 valid_handler
, valid_data
);
425 nl_recvmsgs(nl_handle
, cb
);
433 static int send_and_recv_msgs(struct wpa_driver_nl80211_data
*drv
,
435 int (*valid_handler
)(struct nl_msg
*, void *),
438 return send_and_recv(drv
, drv
->global
->nl
.handle
, msg
, valid_handler
,
449 static int family_handler(struct nl_msg
*msg
, void *arg
)
451 struct family_data
*res
= arg
;
452 struct nlattr
*tb
[CTRL_ATTR_MAX
+ 1];
453 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
454 struct nlattr
*mcgrp
;
457 nla_parse(tb
, CTRL_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
458 genlmsg_attrlen(gnlh
, 0), NULL
);
459 if (!tb
[CTRL_ATTR_MCAST_GROUPS
])
462 nla_for_each_nested(mcgrp
, tb
[CTRL_ATTR_MCAST_GROUPS
], i
) {
463 struct nlattr
*tb2
[CTRL_ATTR_MCAST_GRP_MAX
+ 1];
464 nla_parse(tb2
, CTRL_ATTR_MCAST_GRP_MAX
, nla_data(mcgrp
),
465 nla_len(mcgrp
), NULL
);
466 if (!tb2
[CTRL_ATTR_MCAST_GRP_NAME
] ||
467 !tb2
[CTRL_ATTR_MCAST_GRP_ID
] ||
468 os_strncmp(nla_data(tb2
[CTRL_ATTR_MCAST_GRP_NAME
]),
470 nla_len(tb2
[CTRL_ATTR_MCAST_GRP_NAME
])) != 0)
472 res
->id
= nla_get_u32(tb2
[CTRL_ATTR_MCAST_GRP_ID
]);
480 static int nl_get_multicast_id(struct wpa_driver_nl80211_data
*drv
,
481 const char *family
, const char *group
)
485 struct family_data res
= { group
, -ENOENT
};
490 genlmsg_put(msg
, 0, 0,
491 genl_ctrl_resolve(drv
->global
->nl
.handle
, "nlctrl"),
492 0, 0, CTRL_CMD_GETFAMILY
, 0);
493 NLA_PUT_STRING(msg
, CTRL_ATTR_FAMILY_NAME
, family
);
495 ret
= send_and_recv_msgs(drv
, msg
, family_handler
, &res
);
506 static void * nl80211_cmd(struct wpa_driver_nl80211_data
*drv
,
507 struct nl_msg
*msg
, int flags
, uint8_t cmd
)
509 return genlmsg_put(msg
, 0, 0, drv
->global
->nl80211_id
,
514 static int wpa_driver_nl80211_get_bssid(void *priv
, u8
*bssid
)
516 struct i802_bss
*bss
= priv
;
517 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
518 if (!drv
->associated
)
520 os_memcpy(bssid
, drv
->bssid
, ETH_ALEN
);
525 static int wpa_driver_nl80211_get_ssid(void *priv
, u8
*ssid
)
527 struct i802_bss
*bss
= priv
;
528 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
529 if (!drv
->associated
)
531 os_memcpy(ssid
, drv
->ssid
, drv
->ssid_len
);
532 return drv
->ssid_len
;
536 static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data
*drv
,
537 char *buf
, size_t len
, int del
)
539 union wpa_event_data event
;
541 os_memset(&event
, 0, sizeof(event
));
542 if (len
> sizeof(event
.interface_status
.ifname
))
543 len
= sizeof(event
.interface_status
.ifname
) - 1;
544 os_memcpy(event
.interface_status
.ifname
, buf
, len
);
545 event
.interface_status
.ievent
= del
? EVENT_INTERFACE_REMOVED
:
546 EVENT_INTERFACE_ADDED
;
548 wpa_printf(MSG_DEBUG
, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
550 event
.interface_status
.ifname
,
551 del
? "removed" : "added");
553 if (os_strcmp(drv
->first_bss
.ifname
, event
.interface_status
.ifname
) == 0) {
560 wpa_supplicant_event(drv
->ctx
, EVENT_INTERFACE_STATUS
, &event
);
564 static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data
*drv
,
567 int attrlen
, rta_len
;
571 attr
= (struct rtattr
*) buf
;
573 rta_len
= RTA_ALIGN(sizeof(struct rtattr
));
574 while (RTA_OK(attr
, attrlen
)) {
575 if (attr
->rta_type
== IFLA_IFNAME
) {
576 if (os_strcmp(((char *) attr
) + rta_len
, drv
->first_bss
.ifname
)
582 attr
= RTA_NEXT(attr
, attrlen
);
589 static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data
*drv
,
590 int ifindex
, u8
*buf
, size_t len
)
592 if (drv
->ifindex
== ifindex
)
595 if (drv
->if_removed
&& wpa_driver_nl80211_own_ifname(drv
, buf
, len
)) {
596 drv
->first_bss
.ifindex
= if_nametoindex(drv
->first_bss
.ifname
);
597 wpa_printf(MSG_DEBUG
, "nl80211: Update ifindex for a removed "
599 wpa_driver_nl80211_finish_drv_init(drv
);
607 static struct wpa_driver_nl80211_data
*
608 nl80211_find_drv(struct nl80211_global
*global
, int idx
, u8
*buf
, size_t len
)
610 struct wpa_driver_nl80211_data
*drv
;
611 dl_list_for_each(drv
, &global
->interfaces
,
612 struct wpa_driver_nl80211_data
, list
) {
613 if (wpa_driver_nl80211_own_ifindex(drv
, idx
, buf
, len
) ||
614 have_ifidx(drv
, idx
))
621 static void wpa_driver_nl80211_event_rtm_newlink(void *ctx
,
622 struct ifinfomsg
*ifi
,
625 struct nl80211_global
*global
= ctx
;
626 struct wpa_driver_nl80211_data
*drv
;
627 int attrlen
, rta_len
;
630 char namebuf
[IFNAMSIZ
];
632 drv
= nl80211_find_drv(global
, ifi
->ifi_index
, buf
, len
);
634 wpa_printf(MSG_DEBUG
, "nl80211: Ignore event for foreign "
635 "ifindex %d", ifi
->ifi_index
);
639 wpa_printf(MSG_DEBUG
, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
641 drv
->operstate
, ifi
->ifi_flags
,
642 (ifi
->ifi_flags
& IFF_UP
) ? "[UP]" : "",
643 (ifi
->ifi_flags
& IFF_RUNNING
) ? "[RUNNING]" : "",
644 (ifi
->ifi_flags
& IFF_LOWER_UP
) ? "[LOWER_UP]" : "",
645 (ifi
->ifi_flags
& IFF_DORMANT
) ? "[DORMANT]" : "");
647 if (!drv
->if_disabled
&& !(ifi
->ifi_flags
& IFF_UP
)) {
648 if (if_indextoname(ifi
->ifi_index
, namebuf
) &&
649 linux_iface_up(drv
->global
->ioctl_sock
,
650 drv
->first_bss
.ifname
) > 0) {
651 wpa_printf(MSG_DEBUG
, "nl80211: Ignore interface down "
652 "event since interface %s is up", namebuf
);
655 wpa_printf(MSG_DEBUG
, "nl80211: Interface down");
656 if (drv
->ignore_if_down_event
) {
657 wpa_printf(MSG_DEBUG
, "nl80211: Ignore interface down "
658 "event generated by mode change");
659 drv
->ignore_if_down_event
= 0;
661 drv
->if_disabled
= 1;
662 wpa_supplicant_event(drv
->ctx
,
663 EVENT_INTERFACE_DISABLED
, NULL
);
667 if (drv
->if_disabled
&& (ifi
->ifi_flags
& IFF_UP
)) {
668 if (if_indextoname(ifi
->ifi_index
, namebuf
) &&
669 linux_iface_up(drv
->global
->ioctl_sock
,
670 drv
->first_bss
.ifname
) == 0) {
671 wpa_printf(MSG_DEBUG
, "nl80211: Ignore interface up "
672 "event since interface %s is down",
675 wpa_printf(MSG_DEBUG
, "nl80211: Interface up");
676 drv
->if_disabled
= 0;
677 wpa_supplicant_event(drv
->ctx
, EVENT_INTERFACE_ENABLED
,
683 * Some drivers send the association event before the operup event--in
684 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
685 * fails. This will hit us when wpa_supplicant does not need to do
686 * IEEE 802.1X authentication
688 if (drv
->operstate
== 1 &&
689 (ifi
->ifi_flags
& (IFF_LOWER_UP
| IFF_DORMANT
)) == IFF_LOWER_UP
&&
690 !(ifi
->ifi_flags
& IFF_RUNNING
))
691 netlink_send_oper_ifla(drv
->global
->netlink
, drv
->ifindex
,
695 attr
= (struct rtattr
*) buf
;
696 rta_len
= RTA_ALIGN(sizeof(struct rtattr
));
697 while (RTA_OK(attr
, attrlen
)) {
698 if (attr
->rta_type
== IFLA_IFNAME
) {
699 wpa_driver_nl80211_event_link(
701 ((char *) attr
) + rta_len
,
702 attr
->rta_len
- rta_len
, 0);
703 } else if (attr
->rta_type
== IFLA_MASTER
)
704 brid
= nla_get_u32((struct nlattr
*) attr
);
705 attr
= RTA_NEXT(attr
, attrlen
);
708 if (ifi
->ifi_family
== AF_BRIDGE
&& brid
) {
709 /* device has been added to bridge */
710 if_indextoname(brid
, namebuf
);
711 wpa_printf(MSG_DEBUG
, "nl80211: Add ifindex %u for bridge %s",
713 add_ifidx(drv
, brid
);
718 static void wpa_driver_nl80211_event_rtm_dellink(void *ctx
,
719 struct ifinfomsg
*ifi
,
722 struct nl80211_global
*global
= ctx
;
723 struct wpa_driver_nl80211_data
*drv
;
724 int attrlen
, rta_len
;
728 drv
= nl80211_find_drv(global
, ifi
->ifi_index
, buf
, len
);
730 wpa_printf(MSG_DEBUG
, "nl80211: Ignore dellink event for "
731 "foreign ifindex %d", ifi
->ifi_index
);
736 attr
= (struct rtattr
*) buf
;
738 rta_len
= RTA_ALIGN(sizeof(struct rtattr
));
739 while (RTA_OK(attr
, attrlen
)) {
740 if (attr
->rta_type
== IFLA_IFNAME
) {
741 wpa_driver_nl80211_event_link(
743 ((char *) attr
) + rta_len
,
744 attr
->rta_len
- rta_len
, 1);
745 } else if (attr
->rta_type
== IFLA_MASTER
)
746 brid
= nla_get_u32((struct nlattr
*) attr
);
747 attr
= RTA_NEXT(attr
, attrlen
);
750 if (ifi
->ifi_family
== AF_BRIDGE
&& brid
) {
751 /* device has been removed from bridge */
752 char namebuf
[IFNAMSIZ
];
753 if_indextoname(brid
, namebuf
);
754 wpa_printf(MSG_DEBUG
, "nl80211: Remove ifindex %u for bridge "
755 "%s", brid
, namebuf
);
756 del_ifidx(drv
, brid
);
761 static void mlme_event_auth(struct wpa_driver_nl80211_data
*drv
,
762 const u8
*frame
, size_t len
)
764 const struct ieee80211_mgmt
*mgmt
;
765 union wpa_event_data event
;
767 mgmt
= (const struct ieee80211_mgmt
*) frame
;
768 if (len
< 24 + sizeof(mgmt
->u
.auth
)) {
769 wpa_printf(MSG_DEBUG
, "nl80211: Too short association event "
774 os_memcpy(drv
->auth_bssid
, mgmt
->sa
, ETH_ALEN
);
775 os_memset(&event
, 0, sizeof(event
));
776 os_memcpy(event
.auth
.peer
, mgmt
->sa
, ETH_ALEN
);
777 event
.auth
.auth_type
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
778 event
.auth
.status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
779 if (len
> 24 + sizeof(mgmt
->u
.auth
)) {
780 event
.auth
.ies
= mgmt
->u
.auth
.variable
;
781 event
.auth
.ies_len
= len
- 24 - sizeof(mgmt
->u
.auth
);
784 wpa_supplicant_event(drv
->ctx
, EVENT_AUTH
, &event
);
788 static unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data
*drv
)
792 struct nl80211_bss_info_arg arg
;
794 os_memset(&arg
, 0, sizeof(arg
));
797 goto nla_put_failure
;
799 nl80211_cmd(drv
, msg
, NLM_F_DUMP
, NL80211_CMD_GET_SCAN
);
800 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
803 ret
= send_and_recv_msgs(drv
, msg
, bss_info_handler
, &arg
);
806 wpa_printf(MSG_DEBUG
, "nl80211: Operating frequency for the "
807 "associated BSS from scan results: %u MHz",
809 return arg
.assoc_freq
? arg
.assoc_freq
: drv
->assoc_freq
;
811 wpa_printf(MSG_DEBUG
, "nl80211: Scan result fetch failed: ret=%d "
812 "(%s)", ret
, strerror(-ret
));
815 return drv
->assoc_freq
;
819 static void mlme_event_assoc(struct wpa_driver_nl80211_data
*drv
,
820 const u8
*frame
, size_t len
)
822 const struct ieee80211_mgmt
*mgmt
;
823 union wpa_event_data event
;
826 mgmt
= (const struct ieee80211_mgmt
*) frame
;
827 if (len
< 24 + sizeof(mgmt
->u
.assoc_resp
)) {
828 wpa_printf(MSG_DEBUG
, "nl80211: Too short association event "
833 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
834 if (status
!= WLAN_STATUS_SUCCESS
) {
835 os_memset(&event
, 0, sizeof(event
));
836 event
.assoc_reject
.bssid
= mgmt
->bssid
;
837 if (len
> 24 + sizeof(mgmt
->u
.assoc_resp
)) {
838 event
.assoc_reject
.resp_ies
=
839 (u8
*) mgmt
->u
.assoc_resp
.variable
;
840 event
.assoc_reject
.resp_ies_len
=
841 len
- 24 - sizeof(mgmt
->u
.assoc_resp
);
843 event
.assoc_reject
.status_code
= status
;
845 wpa_supplicant_event(drv
->ctx
, EVENT_ASSOC_REJECT
, &event
);
850 os_memcpy(drv
->bssid
, mgmt
->sa
, ETH_ALEN
);
852 os_memset(&event
, 0, sizeof(event
));
853 if (len
> 24 + sizeof(mgmt
->u
.assoc_resp
)) {
854 event
.assoc_info
.resp_ies
= (u8
*) mgmt
->u
.assoc_resp
.variable
;
855 event
.assoc_info
.resp_ies_len
=
856 len
- 24 - sizeof(mgmt
->u
.assoc_resp
);
859 event
.assoc_info
.freq
= drv
->assoc_freq
;
861 wpa_supplicant_event(drv
->ctx
, EVENT_ASSOC
, &event
);
865 static void mlme_event_connect(struct wpa_driver_nl80211_data
*drv
,
866 enum nl80211_commands cmd
, struct nlattr
*status
,
867 struct nlattr
*addr
, struct nlattr
*req_ie
,
868 struct nlattr
*resp_ie
)
870 union wpa_event_data event
;
872 if (drv
->capa
.flags
& WPA_DRIVER_FLAGS_SME
) {
874 * Avoid reporting two association events that would confuse
877 wpa_printf(MSG_DEBUG
, "nl80211: Ignore connect event (cmd=%d) "
878 "when using userspace SME", cmd
);
882 os_memset(&event
, 0, sizeof(event
));
883 if (cmd
== NL80211_CMD_CONNECT
&&
884 nla_get_u16(status
) != WLAN_STATUS_SUCCESS
) {
886 event
.assoc_reject
.bssid
= nla_data(addr
);
888 event
.assoc_reject
.resp_ies
= nla_data(resp_ie
);
889 event
.assoc_reject
.resp_ies_len
= nla_len(resp_ie
);
891 event
.assoc_reject
.status_code
= nla_get_u16(status
);
892 wpa_supplicant_event(drv
->ctx
, EVENT_ASSOC_REJECT
, &event
);
898 os_memcpy(drv
->bssid
, nla_data(addr
), ETH_ALEN
);
901 event
.assoc_info
.req_ies
= nla_data(req_ie
);
902 event
.assoc_info
.req_ies_len
= nla_len(req_ie
);
905 event
.assoc_info
.resp_ies
= nla_data(resp_ie
);
906 event
.assoc_info
.resp_ies_len
= nla_len(resp_ie
);
909 event
.assoc_info
.freq
= nl80211_get_assoc_freq(drv
);
911 wpa_supplicant_event(drv
->ctx
, EVENT_ASSOC
, &event
);
915 static void mlme_event_disconnect(struct wpa_driver_nl80211_data
*drv
,
916 struct nlattr
*reason
, struct nlattr
*addr
)
918 union wpa_event_data data
;
920 if (drv
->capa
.flags
& WPA_DRIVER_FLAGS_SME
) {
922 * Avoid reporting two disassociation events that could
923 * confuse the core code.
925 wpa_printf(MSG_DEBUG
, "nl80211: Ignore disconnect "
926 "event when using userspace SME");
931 os_memset(&data
, 0, sizeof(data
));
933 data
.disassoc_info
.reason_code
= nla_get_u16(reason
);
934 wpa_supplicant_event(drv
->ctx
, EVENT_DISASSOC
, &data
);
938 static void mlme_timeout_event(struct wpa_driver_nl80211_data
*drv
,
939 enum nl80211_commands cmd
, struct nlattr
*addr
)
941 union wpa_event_data event
;
942 enum wpa_event_type ev
;
944 if (nla_len(addr
) != ETH_ALEN
)
947 wpa_printf(MSG_DEBUG
, "nl80211: MLME event %d; timeout with " MACSTR
,
948 cmd
, MAC2STR((u8
*) nla_data(addr
)));
950 if (cmd
== NL80211_CMD_AUTHENTICATE
)
951 ev
= EVENT_AUTH_TIMED_OUT
;
952 else if (cmd
== NL80211_CMD_ASSOCIATE
)
953 ev
= EVENT_ASSOC_TIMED_OUT
;
957 os_memset(&event
, 0, sizeof(event
));
958 os_memcpy(event
.timeout_event
.addr
, nla_data(addr
), ETH_ALEN
);
959 wpa_supplicant_event(drv
->ctx
, ev
, &event
);
963 static void mlme_event_mgmt(struct wpa_driver_nl80211_data
*drv
,
964 struct nlattr
*freq
, const u8
*frame
, size_t len
)
966 const struct ieee80211_mgmt
*mgmt
;
967 union wpa_event_data event
;
970 mgmt
= (const struct ieee80211_mgmt
*) frame
;
972 wpa_printf(MSG_DEBUG
, "nl80211: Too short action frame");
976 fc
= le_to_host16(mgmt
->frame_control
);
977 stype
= WLAN_FC_GET_STYPE(fc
);
979 os_memset(&event
, 0, sizeof(event
));
981 event
.rx_action
.freq
= nla_get_u32(freq
);
982 drv
->last_mgmt_freq
= event
.rx_action
.freq
;
984 if (stype
== WLAN_FC_STYPE_ACTION
) {
985 event
.rx_action
.da
= mgmt
->da
;
986 event
.rx_action
.sa
= mgmt
->sa
;
987 event
.rx_action
.bssid
= mgmt
->bssid
;
988 event
.rx_action
.category
= mgmt
->u
.action
.category
;
989 event
.rx_action
.data
= &mgmt
->u
.action
.category
+ 1;
990 event
.rx_action
.len
= frame
+ len
- event
.rx_action
.data
;
991 wpa_supplicant_event(drv
->ctx
, EVENT_RX_ACTION
, &event
);
993 event
.rx_mgmt
.frame
= frame
;
994 event
.rx_mgmt
.frame_len
= len
;
995 wpa_supplicant_event(drv
->ctx
, EVENT_RX_MGMT
, &event
);
1000 static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data
*drv
,
1001 struct nlattr
*cookie
, const u8
*frame
,
1002 size_t len
, struct nlattr
*ack
)
1004 union wpa_event_data event
;
1005 const struct ieee80211_hdr
*hdr
;
1008 if (!is_ap_interface(drv
->nlmode
)) {
1014 cookie_val
= nla_get_u64(cookie
);
1015 wpa_printf(MSG_DEBUG
, "nl80211: Action TX status:"
1016 " cookie=0%llx%s (ack=%d)",
1017 (long long unsigned int) cookie_val
,
1018 cookie_val
== drv
->send_action_cookie
?
1019 " (match)" : " (unknown)", ack
!= NULL
);
1020 if (cookie_val
!= drv
->send_action_cookie
)
1024 hdr
= (const struct ieee80211_hdr
*) frame
;
1025 fc
= le_to_host16(hdr
->frame_control
);
1027 os_memset(&event
, 0, sizeof(event
));
1028 event
.tx_status
.type
= WLAN_FC_GET_TYPE(fc
);
1029 event
.tx_status
.stype
= WLAN_FC_GET_STYPE(fc
);
1030 event
.tx_status
.dst
= hdr
->addr1
;
1031 event
.tx_status
.data
= frame
;
1032 event
.tx_status
.data_len
= len
;
1033 event
.tx_status
.ack
= ack
!= NULL
;
1034 wpa_supplicant_event(drv
->ctx
, EVENT_TX_STATUS
, &event
);
1038 static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data
*drv
,
1039 enum wpa_event_type type
,
1040 const u8
*frame
, size_t len
)
1042 const struct ieee80211_mgmt
*mgmt
;
1043 union wpa_event_data event
;
1044 const u8
*bssid
= NULL
;
1045 u16 reason_code
= 0;
1047 mgmt
= (const struct ieee80211_mgmt
*) frame
;
1049 bssid
= mgmt
->bssid
;
1051 if (drv
->associated
!= 0 &&
1052 os_memcmp(bssid
, drv
->bssid
, ETH_ALEN
) != 0 &&
1053 os_memcmp(bssid
, drv
->auth_bssid
, ETH_ALEN
) != 0) {
1055 * We have presumably received this deauth as a
1056 * response to a clear_state_mismatch() outgoing
1057 * deauth. Don't let it take us offline!
1059 wpa_printf(MSG_DEBUG
, "nl80211: Deauth received "
1060 "from Unknown BSSID " MACSTR
" -- ignoring",
1066 drv
->associated
= 0;
1067 os_memset(&event
, 0, sizeof(event
));
1069 /* Note: Same offset for Reason Code in both frame subtypes */
1070 if (len
>= 24 + sizeof(mgmt
->u
.deauth
))
1071 reason_code
= le_to_host16(mgmt
->u
.deauth
.reason_code
);
1073 if (type
== EVENT_DISASSOC
) {
1074 event
.disassoc_info
.addr
= bssid
;
1075 event
.disassoc_info
.reason_code
= reason_code
;
1076 if (frame
+ len
> mgmt
->u
.disassoc
.variable
) {
1077 event
.disassoc_info
.ie
= mgmt
->u
.disassoc
.variable
;
1078 event
.disassoc_info
.ie_len
= frame
+ len
-
1079 mgmt
->u
.disassoc
.variable
;
1082 event
.deauth_info
.addr
= bssid
;
1083 event
.deauth_info
.reason_code
= reason_code
;
1084 if (frame
+ len
> mgmt
->u
.deauth
.variable
) {
1085 event
.deauth_info
.ie
= mgmt
->u
.deauth
.variable
;
1086 event
.deauth_info
.ie_len
= frame
+ len
-
1087 mgmt
->u
.deauth
.variable
;
1091 wpa_supplicant_event(drv
->ctx
, type
, &event
);
1095 static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data
*drv
,
1096 enum wpa_event_type type
,
1097 const u8
*frame
, size_t len
)
1099 const struct ieee80211_mgmt
*mgmt
;
1100 union wpa_event_data event
;
1101 u16 reason_code
= 0;
1106 mgmt
= (const struct ieee80211_mgmt
*) frame
;
1108 os_memset(&event
, 0, sizeof(event
));
1109 /* Note: Same offset for Reason Code in both frame subtypes */
1110 if (len
>= 24 + sizeof(mgmt
->u
.deauth
))
1111 reason_code
= le_to_host16(mgmt
->u
.deauth
.reason_code
);
1113 if (type
== EVENT_UNPROT_DISASSOC
) {
1114 event
.unprot_disassoc
.sa
= mgmt
->sa
;
1115 event
.unprot_disassoc
.da
= mgmt
->da
;
1116 event
.unprot_disassoc
.reason_code
= reason_code
;
1118 event
.unprot_deauth
.sa
= mgmt
->sa
;
1119 event
.unprot_deauth
.da
= mgmt
->da
;
1120 event
.unprot_deauth
.reason_code
= reason_code
;
1123 wpa_supplicant_event(drv
->ctx
, type
, &event
);
1127 static void mlme_event(struct wpa_driver_nl80211_data
*drv
,
1128 enum nl80211_commands cmd
, struct nlattr
*frame
,
1129 struct nlattr
*addr
, struct nlattr
*timed_out
,
1130 struct nlattr
*freq
, struct nlattr
*ack
,
1131 struct nlattr
*cookie
)
1133 if (timed_out
&& addr
) {
1134 mlme_timeout_event(drv
, cmd
, addr
);
1138 if (frame
== NULL
) {
1139 wpa_printf(MSG_DEBUG
, "nl80211: MLME event %d without frame "
1144 wpa_printf(MSG_DEBUG
, "nl80211: MLME event %d", cmd
);
1145 wpa_hexdump(MSG_MSGDUMP
, "nl80211: MLME event frame",
1146 nla_data(frame
), nla_len(frame
));
1149 case NL80211_CMD_AUTHENTICATE
:
1150 mlme_event_auth(drv
, nla_data(frame
), nla_len(frame
));
1152 case NL80211_CMD_ASSOCIATE
:
1153 mlme_event_assoc(drv
, nla_data(frame
), nla_len(frame
));
1155 case NL80211_CMD_DEAUTHENTICATE
:
1156 mlme_event_deauth_disassoc(drv
, EVENT_DEAUTH
,
1157 nla_data(frame
), nla_len(frame
));
1159 case NL80211_CMD_DISASSOCIATE
:
1160 mlme_event_deauth_disassoc(drv
, EVENT_DISASSOC
,
1161 nla_data(frame
), nla_len(frame
));
1163 case NL80211_CMD_FRAME
:
1164 mlme_event_mgmt(drv
, freq
, nla_data(frame
), nla_len(frame
));
1166 case NL80211_CMD_FRAME_TX_STATUS
:
1167 mlme_event_mgmt_tx_status(drv
, cookie
, nla_data(frame
),
1168 nla_len(frame
), ack
);
1170 case NL80211_CMD_UNPROT_DEAUTHENTICATE
:
1171 mlme_event_unprot_disconnect(drv
, EVENT_UNPROT_DEAUTH
,
1172 nla_data(frame
), nla_len(frame
));
1174 case NL80211_CMD_UNPROT_DISASSOCIATE
:
1175 mlme_event_unprot_disconnect(drv
, EVENT_UNPROT_DISASSOC
,
1176 nla_data(frame
), nla_len(frame
));
1184 static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data
*drv
,
1185 struct nlattr
*tb
[])
1187 union wpa_event_data data
;
1189 wpa_printf(MSG_DEBUG
, "nl80211: MLME event Michael MIC failure");
1190 os_memset(&data
, 0, sizeof(data
));
1191 if (tb
[NL80211_ATTR_MAC
]) {
1192 wpa_hexdump(MSG_DEBUG
, "nl80211: Source MAC address",
1193 nla_data(tb
[NL80211_ATTR_MAC
]),
1194 nla_len(tb
[NL80211_ATTR_MAC
]));
1195 data
.michael_mic_failure
.src
= nla_data(tb
[NL80211_ATTR_MAC
]);
1197 if (tb
[NL80211_ATTR_KEY_SEQ
]) {
1198 wpa_hexdump(MSG_DEBUG
, "nl80211: TSC",
1199 nla_data(tb
[NL80211_ATTR_KEY_SEQ
]),
1200 nla_len(tb
[NL80211_ATTR_KEY_SEQ
]));
1202 if (tb
[NL80211_ATTR_KEY_TYPE
]) {
1203 enum nl80211_key_type key_type
=
1204 nla_get_u32(tb
[NL80211_ATTR_KEY_TYPE
]);
1205 wpa_printf(MSG_DEBUG
, "nl80211: Key Type %d", key_type
);
1206 if (key_type
== NL80211_KEYTYPE_PAIRWISE
)
1207 data
.michael_mic_failure
.unicast
= 1;
1209 data
.michael_mic_failure
.unicast
= 1;
1211 if (tb
[NL80211_ATTR_KEY_IDX
]) {
1212 u8 key_id
= nla_get_u8(tb
[NL80211_ATTR_KEY_IDX
]);
1213 wpa_printf(MSG_DEBUG
, "nl80211: Key Id %d", key_id
);
1216 wpa_supplicant_event(drv
->ctx
, EVENT_MICHAEL_MIC_FAILURE
, &data
);
1220 static void mlme_event_join_ibss(struct wpa_driver_nl80211_data
*drv
,
1221 struct nlattr
*tb
[])
1223 if (tb
[NL80211_ATTR_MAC
] == NULL
) {
1224 wpa_printf(MSG_DEBUG
, "nl80211: No address in IBSS joined "
1228 os_memcpy(drv
->bssid
, nla_data(tb
[NL80211_ATTR_MAC
]), ETH_ALEN
);
1229 drv
->associated
= 1;
1230 wpa_printf(MSG_DEBUG
, "nl80211: IBSS " MACSTR
" joined",
1231 MAC2STR(drv
->bssid
));
1233 wpa_supplicant_event(drv
->ctx
, EVENT_ASSOC
, NULL
);
1237 static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data
*drv
,
1238 int cancel_event
, struct nlattr
*tb
[])
1240 unsigned int freq
, chan_type
, duration
;
1241 union wpa_event_data data
;
1244 if (tb
[NL80211_ATTR_WIPHY_FREQ
])
1245 freq
= nla_get_u32(tb
[NL80211_ATTR_WIPHY_FREQ
]);
1249 if (tb
[NL80211_ATTR_WIPHY_CHANNEL_TYPE
])
1250 chan_type
= nla_get_u32(tb
[NL80211_ATTR_WIPHY_CHANNEL_TYPE
]);
1254 if (tb
[NL80211_ATTR_DURATION
])
1255 duration
= nla_get_u32(tb
[NL80211_ATTR_DURATION
]);
1259 if (tb
[NL80211_ATTR_COOKIE
])
1260 cookie
= nla_get_u64(tb
[NL80211_ATTR_COOKIE
]);
1264 wpa_printf(MSG_DEBUG
, "nl80211: Remain-on-channel event (cancel=%d "
1265 "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
1266 cancel_event
, freq
, chan_type
, duration
,
1267 (long long unsigned int) cookie
,
1268 cookie
== drv
->remain_on_chan_cookie
? "match" : "unknown");
1270 if (cookie
!= drv
->remain_on_chan_cookie
)
1271 return; /* not for us */
1274 drv
->pending_remain_on_chan
= 0;
1276 os_memset(&data
, 0, sizeof(data
));
1277 data
.remain_on_channel
.freq
= freq
;
1278 data
.remain_on_channel
.duration
= duration
;
1279 wpa_supplicant_event(drv
->ctx
, cancel_event
?
1280 EVENT_CANCEL_REMAIN_ON_CHANNEL
:
1281 EVENT_REMAIN_ON_CHANNEL
, &data
);
1285 static void send_scan_event(struct wpa_driver_nl80211_data
*drv
, int aborted
,
1286 struct nlattr
*tb
[])
1288 union wpa_event_data event
;
1291 struct scan_info
*info
;
1292 #define MAX_REPORT_FREQS 50
1293 int freqs
[MAX_REPORT_FREQS
];
1296 if (drv
->scan_for_auth
) {
1297 drv
->scan_for_auth
= 0;
1298 wpa_printf(MSG_DEBUG
, "nl80211: Scan results for missing "
1299 "cfg80211 BSS entry");
1300 wpa_driver_nl80211_authenticate_retry(drv
);
1304 os_memset(&event
, 0, sizeof(event
));
1305 info
= &event
.scan_info
;
1306 info
->aborted
= aborted
;
1308 if (tb
[NL80211_ATTR_SCAN_SSIDS
]) {
1309 nla_for_each_nested(nl
, tb
[NL80211_ATTR_SCAN_SSIDS
], rem
) {
1310 struct wpa_driver_scan_ssid
*s
=
1311 &info
->ssids
[info
->num_ssids
];
1312 s
->ssid
= nla_data(nl
);
1313 s
->ssid_len
= nla_len(nl
);
1315 if (info
->num_ssids
== WPAS_MAX_SCAN_SSIDS
)
1319 if (tb
[NL80211_ATTR_SCAN_FREQUENCIES
]) {
1320 nla_for_each_nested(nl
, tb
[NL80211_ATTR_SCAN_FREQUENCIES
], rem
)
1322 freqs
[num_freqs
] = nla_get_u32(nl
);
1324 if (num_freqs
== MAX_REPORT_FREQS
- 1)
1327 info
->freqs
= freqs
;
1328 info
->num_freqs
= num_freqs
;
1330 wpa_supplicant_event(drv
->ctx
, EVENT_SCAN_RESULTS
, &event
);
1334 static int get_link_signal(struct nl_msg
*msg
, void *arg
)
1336 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
1337 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
1338 struct nlattr
*sinfo
[NL80211_STA_INFO_MAX
+ 1];
1339 static struct nla_policy policy
[NL80211_STA_INFO_MAX
+ 1] = {
1340 [NL80211_STA_INFO_SIGNAL
] = { .type
= NLA_U8
},
1342 struct nlattr
*rinfo
[NL80211_RATE_INFO_MAX
+ 1];
1343 static struct nla_policy rate_policy
[NL80211_RATE_INFO_MAX
+ 1] = {
1344 [NL80211_RATE_INFO_BITRATE
] = { .type
= NLA_U16
},
1345 [NL80211_RATE_INFO_MCS
] = { .type
= NLA_U8
},
1346 [NL80211_RATE_INFO_40_MHZ_WIDTH
] = { .type
= NLA_FLAG
},
1347 [NL80211_RATE_INFO_SHORT_GI
] = { .type
= NLA_FLAG
},
1349 struct wpa_signal_info
*sig_change
= arg
;
1351 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
1352 genlmsg_attrlen(gnlh
, 0), NULL
);
1353 if (!tb
[NL80211_ATTR_STA_INFO
] ||
1354 nla_parse_nested(sinfo
, NL80211_STA_INFO_MAX
,
1355 tb
[NL80211_ATTR_STA_INFO
], policy
))
1357 if (!sinfo
[NL80211_STA_INFO_SIGNAL
])
1360 sig_change
->current_signal
=
1361 (s8
) nla_get_u8(sinfo
[NL80211_STA_INFO_SIGNAL
]);
1363 if (sinfo
[NL80211_STA_INFO_TX_BITRATE
]) {
1364 if (nla_parse_nested(rinfo
, NL80211_RATE_INFO_MAX
,
1365 sinfo
[NL80211_STA_INFO_TX_BITRATE
],
1367 sig_change
->current_txrate
= 0;
1369 if (rinfo
[NL80211_RATE_INFO_BITRATE
]) {
1370 sig_change
->current_txrate
=
1372 NL80211_RATE_INFO_BITRATE
]) * 100;
1381 static int nl80211_get_link_signal(struct wpa_driver_nl80211_data
*drv
,
1382 struct wpa_signal_info
*sig
)
1386 sig
->current_signal
= -9999;
1387 sig
->current_txrate
= 0;
1389 msg
= nlmsg_alloc();
1393 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_GET_STATION
);
1395 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
1396 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, drv
->bssid
);
1398 return send_and_recv_msgs(drv
, msg
, get_link_signal
, sig
);
1404 static int get_link_noise(struct nl_msg
*msg
, void *arg
)
1406 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
1407 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
1408 struct nlattr
*sinfo
[NL80211_SURVEY_INFO_MAX
+ 1];
1409 static struct nla_policy survey_policy
[NL80211_SURVEY_INFO_MAX
+ 1] = {
1410 [NL80211_SURVEY_INFO_FREQUENCY
] = { .type
= NLA_U32
},
1411 [NL80211_SURVEY_INFO_NOISE
] = { .type
= NLA_U8
},
1413 struct wpa_signal_info
*sig_change
= arg
;
1415 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
1416 genlmsg_attrlen(gnlh
, 0), NULL
);
1418 if (!tb
[NL80211_ATTR_SURVEY_INFO
]) {
1419 wpa_printf(MSG_DEBUG
, "nl80211: survey data missing!");
1423 if (nla_parse_nested(sinfo
, NL80211_SURVEY_INFO_MAX
,
1424 tb
[NL80211_ATTR_SURVEY_INFO
],
1426 wpa_printf(MSG_DEBUG
, "nl80211: failed to parse nested "
1431 if (!sinfo
[NL80211_SURVEY_INFO_FREQUENCY
])
1434 if (nla_get_u32(sinfo
[NL80211_SURVEY_INFO_FREQUENCY
]) !=
1435 sig_change
->frequency
)
1438 if (!sinfo
[NL80211_SURVEY_INFO_NOISE
])
1441 sig_change
->current_noise
=
1442 (s8
) nla_get_u8(sinfo
[NL80211_SURVEY_INFO_NOISE
]);
1448 static int nl80211_get_link_noise(struct wpa_driver_nl80211_data
*drv
,
1449 struct wpa_signal_info
*sig_change
)
1453 sig_change
->current_noise
= 9999;
1454 sig_change
->frequency
= drv
->assoc_freq
;
1456 msg
= nlmsg_alloc();
1460 nl80211_cmd(drv
, msg
, NLM_F_DUMP
, NL80211_CMD_GET_SURVEY
);
1462 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
1464 return send_and_recv_msgs(drv
, msg
, get_link_noise
, sig_change
);
1470 static int get_noise_for_scan_results(struct nl_msg
*msg
, void *arg
)
1472 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
1473 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
1474 struct nlattr
*sinfo
[NL80211_SURVEY_INFO_MAX
+ 1];
1475 static struct nla_policy survey_policy
[NL80211_SURVEY_INFO_MAX
+ 1] = {
1476 [NL80211_SURVEY_INFO_FREQUENCY
] = { .type
= NLA_U32
},
1477 [NL80211_SURVEY_INFO_NOISE
] = { .type
= NLA_U8
},
1479 struct wpa_scan_results
*scan_results
= arg
;
1480 struct wpa_scan_res
*scan_res
;
1483 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
1484 genlmsg_attrlen(gnlh
, 0), NULL
);
1486 if (!tb
[NL80211_ATTR_SURVEY_INFO
]) {
1487 wpa_printf(MSG_DEBUG
, "nl80211: Survey data missing");
1491 if (nla_parse_nested(sinfo
, NL80211_SURVEY_INFO_MAX
,
1492 tb
[NL80211_ATTR_SURVEY_INFO
],
1494 wpa_printf(MSG_DEBUG
, "nl80211: Failed to parse nested "
1499 if (!sinfo
[NL80211_SURVEY_INFO_NOISE
])
1502 if (!sinfo
[NL80211_SURVEY_INFO_FREQUENCY
])
1505 for (i
= 0; i
< scan_results
->num
; ++i
) {
1506 scan_res
= scan_results
->res
[i
];
1509 if ((int) nla_get_u32(sinfo
[NL80211_SURVEY_INFO_FREQUENCY
]) !=
1512 if (!(scan_res
->flags
& WPA_SCAN_NOISE_INVALID
))
1514 scan_res
->noise
= (s8
)
1515 nla_get_u8(sinfo
[NL80211_SURVEY_INFO_NOISE
]);
1516 scan_res
->flags
&= ~WPA_SCAN_NOISE_INVALID
;
1523 static int nl80211_get_noise_for_scan_results(
1524 struct wpa_driver_nl80211_data
*drv
,
1525 struct wpa_scan_results
*scan_res
)
1529 msg
= nlmsg_alloc();
1533 nl80211_cmd(drv
, msg
, NLM_F_DUMP
, NL80211_CMD_GET_SURVEY
);
1535 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
1537 return send_and_recv_msgs(drv
, msg
, get_noise_for_scan_results
,
1544 static void nl80211_cqm_event(struct wpa_driver_nl80211_data
*drv
,
1545 struct nlattr
*tb
[])
1547 static struct nla_policy cqm_policy
[NL80211_ATTR_CQM_MAX
+ 1] = {
1548 [NL80211_ATTR_CQM_RSSI_THOLD
] = { .type
= NLA_U32
},
1549 [NL80211_ATTR_CQM_RSSI_HYST
] = { .type
= NLA_U8
},
1550 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT
] = { .type
= NLA_U32
},
1551 [NL80211_ATTR_CQM_PKT_LOSS_EVENT
] = { .type
= NLA_U32
},
1553 struct nlattr
*cqm
[NL80211_ATTR_CQM_MAX
+ 1];
1554 enum nl80211_cqm_rssi_threshold_event event
;
1555 union wpa_event_data ed
;
1556 struct wpa_signal_info sig
;
1559 if (tb
[NL80211_ATTR_CQM
] == NULL
||
1560 nla_parse_nested(cqm
, NL80211_ATTR_CQM_MAX
, tb
[NL80211_ATTR_CQM
],
1562 wpa_printf(MSG_DEBUG
, "nl80211: Ignore invalid CQM event");
1566 os_memset(&ed
, 0, sizeof(ed
));
1568 if (cqm
[NL80211_ATTR_CQM_PKT_LOSS_EVENT
]) {
1569 if (!tb
[NL80211_ATTR_MAC
])
1571 os_memcpy(ed
.low_ack
.addr
, nla_data(tb
[NL80211_ATTR_MAC
]),
1573 wpa_supplicant_event(drv
->ctx
, EVENT_STATION_LOW_ACK
, &ed
);
1577 if (cqm
[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT
] == NULL
)
1579 event
= nla_get_u32(cqm
[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT
]);
1581 if (event
== NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH
) {
1582 wpa_printf(MSG_DEBUG
, "nl80211: Connection quality monitor "
1583 "event: RSSI high");
1584 ed
.signal_change
.above_threshold
= 1;
1585 } else if (event
== NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW
) {
1586 wpa_printf(MSG_DEBUG
, "nl80211: Connection quality monitor "
1588 ed
.signal_change
.above_threshold
= 0;
1592 res
= nl80211_get_link_signal(drv
, &sig
);
1594 ed
.signal_change
.current_signal
= sig
.current_signal
;
1595 ed
.signal_change
.current_txrate
= sig
.current_txrate
;
1596 wpa_printf(MSG_DEBUG
, "nl80211: Signal: %d dBm txrate: %d",
1597 sig
.current_signal
, sig
.current_txrate
);
1600 res
= nl80211_get_link_noise(drv
, &sig
);
1602 ed
.signal_change
.current_noise
= sig
.current_noise
;
1603 wpa_printf(MSG_DEBUG
, "nl80211: Noise: %d dBm",
1607 wpa_supplicant_event(drv
->ctx
, EVENT_SIGNAL_CHANGE
, &ed
);
1611 static void nl80211_new_station_event(struct wpa_driver_nl80211_data
*drv
,
1615 union wpa_event_data data
;
1617 if (tb
[NL80211_ATTR_MAC
] == NULL
)
1619 addr
= nla_data(tb
[NL80211_ATTR_MAC
]);
1620 wpa_printf(MSG_DEBUG
, "nl80211: New station " MACSTR
, MAC2STR(addr
));
1622 if (is_ap_interface(drv
->nlmode
) && drv
->device_ap_sme
) {
1625 if (tb
[NL80211_ATTR_IE
]) {
1626 ies
= nla_data(tb
[NL80211_ATTR_IE
]);
1627 ies_len
= nla_len(tb
[NL80211_ATTR_IE
]);
1629 wpa_hexdump(MSG_DEBUG
, "nl80211: Assoc Req IEs", ies
, ies_len
);
1630 drv_event_assoc(drv
->ctx
, addr
, ies
, ies_len
, 0);
1634 if (drv
->nlmode
!= NL80211_IFTYPE_ADHOC
)
1637 os_memset(&data
, 0, sizeof(data
));
1638 os_memcpy(data
.ibss_rsn_start
.peer
, addr
, ETH_ALEN
);
1639 wpa_supplicant_event(drv
->ctx
, EVENT_IBSS_RSN_START
, &data
);
1643 static void nl80211_del_station_event(struct wpa_driver_nl80211_data
*drv
,
1647 union wpa_event_data data
;
1649 if (tb
[NL80211_ATTR_MAC
] == NULL
)
1651 addr
= nla_data(tb
[NL80211_ATTR_MAC
]);
1652 wpa_printf(MSG_DEBUG
, "nl80211: Delete station " MACSTR
,
1655 if (is_ap_interface(drv
->nlmode
) && drv
->device_ap_sme
) {
1656 drv_event_disassoc(drv
->ctx
, addr
);
1660 if (drv
->nlmode
!= NL80211_IFTYPE_ADHOC
)
1663 os_memset(&data
, 0, sizeof(data
));
1664 os_memcpy(data
.ibss_peer_lost
.peer
, addr
, ETH_ALEN
);
1665 wpa_supplicant_event(drv
->ctx
, EVENT_IBSS_PEER_LOST
, &data
);
1669 static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data
*drv
,
1672 struct nlattr
*rekey_info
[NUM_NL80211_REKEY_DATA
];
1673 static struct nla_policy rekey_policy
[NUM_NL80211_REKEY_DATA
] = {
1674 [NL80211_REKEY_DATA_KEK
] = {
1675 .minlen
= NL80211_KEK_LEN
,
1676 .maxlen
= NL80211_KEK_LEN
,
1678 [NL80211_REKEY_DATA_KCK
] = {
1679 .minlen
= NL80211_KCK_LEN
,
1680 .maxlen
= NL80211_KCK_LEN
,
1682 [NL80211_REKEY_DATA_REPLAY_CTR
] = {
1683 .minlen
= NL80211_REPLAY_CTR_LEN
,
1684 .maxlen
= NL80211_REPLAY_CTR_LEN
,
1687 union wpa_event_data data
;
1689 if (!tb
[NL80211_ATTR_MAC
])
1691 if (!tb
[NL80211_ATTR_REKEY_DATA
])
1693 if (nla_parse_nested(rekey_info
, MAX_NL80211_REKEY_DATA
,
1694 tb
[NL80211_ATTR_REKEY_DATA
], rekey_policy
))
1696 if (!rekey_info
[NL80211_REKEY_DATA_REPLAY_CTR
])
1699 os_memset(&data
, 0, sizeof(data
));
1700 data
.driver_gtk_rekey
.bssid
= nla_data(tb
[NL80211_ATTR_MAC
]);
1701 wpa_printf(MSG_DEBUG
, "nl80211: Rekey offload event for BSSID " MACSTR
,
1702 MAC2STR(data
.driver_gtk_rekey
.bssid
));
1703 data
.driver_gtk_rekey
.replay_ctr
=
1704 nla_data(rekey_info
[NL80211_REKEY_DATA_REPLAY_CTR
]);
1705 wpa_hexdump(MSG_DEBUG
, "nl80211: Rekey offload - Replay Counter",
1706 data
.driver_gtk_rekey
.replay_ctr
, NL80211_REPLAY_CTR_LEN
);
1707 wpa_supplicant_event(drv
->ctx
, EVENT_DRIVER_GTK_REKEY
, &data
);
1711 static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data
*drv
,
1714 struct nlattr
*cand
[NUM_NL80211_PMKSA_CANDIDATE
];
1715 static struct nla_policy cand_policy
[NUM_NL80211_PMKSA_CANDIDATE
] = {
1716 [NL80211_PMKSA_CANDIDATE_INDEX
] = { .type
= NLA_U32
},
1717 [NL80211_PMKSA_CANDIDATE_BSSID
] = {
1721 [NL80211_PMKSA_CANDIDATE_PREAUTH
] = { .type
= NLA_FLAG
},
1723 union wpa_event_data data
;
1725 if (!tb
[NL80211_ATTR_PMKSA_CANDIDATE
])
1727 if (nla_parse_nested(cand
, MAX_NL80211_PMKSA_CANDIDATE
,
1728 tb
[NL80211_ATTR_PMKSA_CANDIDATE
], cand_policy
))
1730 if (!cand
[NL80211_PMKSA_CANDIDATE_INDEX
] ||
1731 !cand
[NL80211_PMKSA_CANDIDATE_BSSID
])
1734 os_memset(&data
, 0, sizeof(data
));
1735 os_memcpy(data
.pmkid_candidate
.bssid
,
1736 nla_data(cand
[NL80211_PMKSA_CANDIDATE_BSSID
]), ETH_ALEN
);
1737 data
.pmkid_candidate
.index
=
1738 nla_get_u32(cand
[NL80211_PMKSA_CANDIDATE_INDEX
]);
1739 data
.pmkid_candidate
.preauth
=
1740 cand
[NL80211_PMKSA_CANDIDATE_PREAUTH
] != NULL
;
1741 wpa_supplicant_event(drv
->ctx
, EVENT_PMKID_CANDIDATE
, &data
);
1745 static void nl80211_client_probe_event(struct wpa_driver_nl80211_data
*drv
,
1748 union wpa_event_data data
;
1750 if (!tb
[NL80211_ATTR_MAC
] || !tb
[NL80211_ATTR_ACK
])
1753 os_memset(&data
, 0, sizeof(data
));
1754 os_memcpy(data
.client_poll
.addr
,
1755 nla_data(tb
[NL80211_ATTR_MAC
]), ETH_ALEN
);
1757 wpa_supplicant_event(drv
->ctx
, EVENT_DRIVER_CLIENT_POLL_OK
, &data
);
1761 static void nl80211_spurious_class3_frame(struct i802_bss
*bss
,
1764 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
1765 union wpa_event_data event
;
1768 if (!tb
[NL80211_ATTR_MAC
])
1771 if (linux_get_ifhwaddr(drv
->global
->ioctl_sock
, bss
->ifname
, bssid
) <
1775 os_memset(&event
, 0, sizeof(event
));
1776 event
.rx_from_unknown
.bssid
= bssid
;
1777 event
.rx_from_unknown
.addr
= nla_data(tb
[NL80211_ATTR_MAC
]);
1779 wpa_supplicant_event(drv
->ctx
, EVENT_RX_FROM_UNKNOWN
, &event
);
1783 static int process_drv_event(struct nl_msg
*msg
, void *arg
)
1785 struct wpa_driver_nl80211_data
*drv
= arg
;
1786 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
1787 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
1789 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
1790 genlmsg_attrlen(gnlh
, 0), NULL
);
1792 if (tb
[NL80211_ATTR_IFINDEX
]) {
1793 int ifindex
= nla_get_u32(tb
[NL80211_ATTR_IFINDEX
]);
1794 if (ifindex
!= drv
->ifindex
&& !have_ifidx(drv
, ifindex
)) {
1795 wpa_printf(MSG_DEBUG
, "nl80211: Ignored event (cmd=%d)"
1796 " for foreign interface (ifindex %d)",
1797 gnlh
->cmd
, ifindex
);
1802 if (drv
->ap_scan_as_station
!= NL80211_IFTYPE_UNSPECIFIED
&&
1803 (gnlh
->cmd
== NL80211_CMD_NEW_SCAN_RESULTS
||
1804 gnlh
->cmd
== NL80211_CMD_SCAN_ABORTED
)) {
1805 wpa_driver_nl80211_set_mode(&drv
->first_bss
,
1806 drv
->ap_scan_as_station
);
1807 drv
->ap_scan_as_station
= NL80211_IFTYPE_UNSPECIFIED
;
1810 switch (gnlh
->cmd
) {
1811 case NL80211_CMD_TRIGGER_SCAN
:
1812 wpa_printf(MSG_DEBUG
, "nl80211: Scan trigger");
1814 case NL80211_CMD_START_SCHED_SCAN
:
1815 wpa_printf(MSG_DEBUG
, "nl80211: Sched scan started");
1817 case NL80211_CMD_SCHED_SCAN_STOPPED
:
1818 wpa_printf(MSG_DEBUG
, "nl80211: Sched scan stopped");
1819 wpa_supplicant_event(drv
->ctx
, EVENT_SCHED_SCAN_STOPPED
, NULL
);
1821 case NL80211_CMD_NEW_SCAN_RESULTS
:
1822 wpa_printf(MSG_DEBUG
, "nl80211: New scan results available");
1823 drv
->scan_complete_events
= 1;
1824 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout
, drv
,
1826 send_scan_event(drv
, 0, tb
);
1828 case NL80211_CMD_SCHED_SCAN_RESULTS
:
1829 wpa_printf(MSG_DEBUG
,
1830 "nl80211: New sched scan results available");
1831 send_scan_event(drv
, 0, tb
);
1833 case NL80211_CMD_SCAN_ABORTED
:
1834 wpa_printf(MSG_DEBUG
, "nl80211: Scan aborted");
1836 * Need to indicate that scan results are available in order
1837 * not to make wpa_supplicant stop its scanning.
1839 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout
, drv
,
1841 send_scan_event(drv
, 1, tb
);
1843 case NL80211_CMD_AUTHENTICATE
:
1844 case NL80211_CMD_ASSOCIATE
:
1845 case NL80211_CMD_DEAUTHENTICATE
:
1846 case NL80211_CMD_DISASSOCIATE
:
1847 case NL80211_CMD_FRAME_TX_STATUS
:
1848 case NL80211_CMD_UNPROT_DEAUTHENTICATE
:
1849 case NL80211_CMD_UNPROT_DISASSOCIATE
:
1850 mlme_event(drv
, gnlh
->cmd
, tb
[NL80211_ATTR_FRAME
],
1851 tb
[NL80211_ATTR_MAC
], tb
[NL80211_ATTR_TIMED_OUT
],
1852 tb
[NL80211_ATTR_WIPHY_FREQ
], tb
[NL80211_ATTR_ACK
],
1853 tb
[NL80211_ATTR_COOKIE
]);
1855 case NL80211_CMD_CONNECT
:
1856 case NL80211_CMD_ROAM
:
1857 mlme_event_connect(drv
, gnlh
->cmd
,
1858 tb
[NL80211_ATTR_STATUS_CODE
],
1859 tb
[NL80211_ATTR_MAC
],
1860 tb
[NL80211_ATTR_REQ_IE
],
1861 tb
[NL80211_ATTR_RESP_IE
]);
1863 case NL80211_CMD_DISCONNECT
:
1864 mlme_event_disconnect(drv
, tb
[NL80211_ATTR_REASON_CODE
],
1865 tb
[NL80211_ATTR_MAC
]);
1867 case NL80211_CMD_MICHAEL_MIC_FAILURE
:
1868 mlme_event_michael_mic_failure(drv
, tb
);
1870 case NL80211_CMD_JOIN_IBSS
:
1871 mlme_event_join_ibss(drv
, tb
);
1873 case NL80211_CMD_REMAIN_ON_CHANNEL
:
1874 mlme_event_remain_on_channel(drv
, 0, tb
);
1876 case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL
:
1877 mlme_event_remain_on_channel(drv
, 1, tb
);
1879 case NL80211_CMD_NOTIFY_CQM
:
1880 nl80211_cqm_event(drv
, tb
);
1882 case NL80211_CMD_REG_CHANGE
:
1883 wpa_printf(MSG_DEBUG
, "nl80211: Regulatory domain change");
1884 wpa_supplicant_event(drv
->ctx
, EVENT_CHANNEL_LIST_CHANGED
,
1887 case NL80211_CMD_REG_BEACON_HINT
:
1888 wpa_printf(MSG_DEBUG
, "nl80211: Regulatory beacon hint");
1889 wpa_supplicant_event(drv
->ctx
, EVENT_CHANNEL_LIST_CHANGED
,
1892 case NL80211_CMD_NEW_STATION
:
1893 nl80211_new_station_event(drv
, tb
);
1895 case NL80211_CMD_DEL_STATION
:
1896 nl80211_del_station_event(drv
, tb
);
1898 case NL80211_CMD_SET_REKEY_OFFLOAD
:
1899 nl80211_rekey_offload_event(drv
, tb
);
1901 case NL80211_CMD_PMKSA_CANDIDATE
:
1902 nl80211_pmksa_candidate_event(drv
, tb
);
1904 case NL80211_CMD_PROBE_CLIENT
:
1905 nl80211_client_probe_event(drv
, tb
);
1908 wpa_printf(MSG_DEBUG
, "nl80211: Ignored unknown event "
1909 "(cmd=%d)", gnlh
->cmd
);
1917 static int process_bss_event(struct nl_msg
*msg
, void *arg
)
1919 struct i802_bss
*bss
= arg
;
1920 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
1921 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
1923 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
1924 genlmsg_attrlen(gnlh
, 0), NULL
);
1926 switch (gnlh
->cmd
) {
1927 case NL80211_CMD_FRAME
:
1928 case NL80211_CMD_FRAME_TX_STATUS
:
1929 mlme_event(bss
->drv
, gnlh
->cmd
, tb
[NL80211_ATTR_FRAME
],
1930 tb
[NL80211_ATTR_MAC
], tb
[NL80211_ATTR_TIMED_OUT
],
1931 tb
[NL80211_ATTR_WIPHY_FREQ
], tb
[NL80211_ATTR_ACK
],
1932 tb
[NL80211_ATTR_COOKIE
]);
1934 case NL80211_CMD_UNEXPECTED_FRAME
:
1935 nl80211_spurious_class3_frame(bss
, tb
);
1938 wpa_printf(MSG_DEBUG
, "nl80211: Ignored unknown event "
1939 "(cmd=%d)", gnlh
->cmd
);
1947 static void wpa_driver_nl80211_event_receive(int sock
, void *eloop_ctx
,
1950 struct nl_cb
*cb
= eloop_ctx
;
1952 wpa_printf(MSG_DEBUG
, "nl80211: Event message available");
1954 nl_recvmsgs(handle
, cb
);
1959 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
1960 * @priv: driver_nl80211 private data
1961 * @alpha2_arg: country to which to switch to
1962 * Returns: 0 on success, -1 on failure
1964 * This asks nl80211 to set the regulatory domain for given
1965 * country ISO / IEC alpha2.
1967 static int wpa_driver_nl80211_set_country(void *priv
, const char *alpha2_arg
)
1969 struct i802_bss
*bss
= priv
;
1970 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
1974 msg
= nlmsg_alloc();
1978 alpha2
[0] = alpha2_arg
[0];
1979 alpha2
[1] = alpha2_arg
[1];
1982 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_REQ_SET_REG
);
1984 NLA_PUT_STRING(msg
, NL80211_ATTR_REG_ALPHA2
, alpha2
);
1985 if (send_and_recv_msgs(drv
, msg
, NULL
, NULL
))
1993 struct wiphy_info_data
{
1994 struct wpa_driver_capa
*capa
;
1996 unsigned int error
:1;
1997 unsigned int device_ap_sme
:1;
1998 unsigned int poll_command_supported
:1;
1999 unsigned int data_tx_status
:1;
2003 static int wiphy_info_handler(struct nl_msg
*msg
, void *arg
)
2005 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
2006 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
2007 struct wiphy_info_data
*info
= arg
;
2008 int p2p_go_supported
= 0, p2p_client_supported
= 0;
2009 int p2p_concurrent
= 0;
2010 int auth_supported
= 0, connect_supported
= 0;
2011 struct wpa_driver_capa
*capa
= info
->capa
;
2012 static struct nla_policy
2013 iface_combination_policy
[NUM_NL80211_IFACE_COMB
] = {
2014 [NL80211_IFACE_COMB_LIMITS
] = { .type
= NLA_NESTED
},
2015 [NL80211_IFACE_COMB_MAXNUM
] = { .type
= NLA_U32
},
2016 [NL80211_IFACE_COMB_STA_AP_BI_MATCH
] = { .type
= NLA_FLAG
},
2017 [NL80211_IFACE_COMB_NUM_CHANNELS
] = { .type
= NLA_U32
},
2019 iface_limit_policy
[NUM_NL80211_IFACE_LIMIT
] = {
2020 [NL80211_IFACE_LIMIT_TYPES
] = { .type
= NLA_NESTED
},
2021 [NL80211_IFACE_LIMIT_MAX
] = { .type
= NLA_U32
},
2024 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
2025 genlmsg_attrlen(gnlh
, 0), NULL
);
2027 if (tb
[NL80211_ATTR_MAX_NUM_SCAN_SSIDS
])
2028 capa
->max_scan_ssids
=
2029 nla_get_u8(tb
[NL80211_ATTR_MAX_NUM_SCAN_SSIDS
]);
2031 if (tb
[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS
])
2032 capa
->max_sched_scan_ssids
=
2033 nla_get_u8(tb
[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS
]);
2035 if (tb
[NL80211_ATTR_MAX_MATCH_SETS
])
2036 capa
->max_match_sets
=
2037 nla_get_u8(tb
[NL80211_ATTR_MAX_MATCH_SETS
]);
2039 if (tb
[NL80211_ATTR_SUPPORTED_IFTYPES
]) {
2040 struct nlattr
*nl_mode
;
2042 nla_for_each_nested(nl_mode
,
2043 tb
[NL80211_ATTR_SUPPORTED_IFTYPES
], i
) {
2044 switch (nla_type(nl_mode
)) {
2045 case NL80211_IFTYPE_AP
:
2046 capa
->flags
|= WPA_DRIVER_FLAGS_AP
;
2048 case NL80211_IFTYPE_P2P_GO
:
2049 p2p_go_supported
= 1;
2051 case NL80211_IFTYPE_P2P_CLIENT
:
2052 p2p_client_supported
= 1;
2058 if (tb
[NL80211_ATTR_INTERFACE_COMBINATIONS
]) {
2059 struct nlattr
*nl_combi
;
2062 nla_for_each_nested(nl_combi
,
2063 tb
[NL80211_ATTR_INTERFACE_COMBINATIONS
],
2065 struct nlattr
*tb_comb
[NUM_NL80211_IFACE_COMB
];
2066 struct nlattr
*tb_limit
[NUM_NL80211_IFACE_LIMIT
];
2067 struct nlattr
*nl_limit
, *nl_mode
;
2068 int err
, rem_limit
, rem_mode
;
2069 int combination_has_p2p
= 0, combination_has_mgd
= 0;
2071 err
= nla_parse_nested(tb_comb
, MAX_NL80211_IFACE_COMB
,
2073 iface_combination_policy
);
2074 if (err
|| !tb_comb
[NL80211_IFACE_COMB_LIMITS
] ||
2075 !tb_comb
[NL80211_IFACE_COMB_MAXNUM
] ||
2076 !tb_comb
[NL80211_IFACE_COMB_NUM_CHANNELS
])
2077 goto broken_combination
;
2079 nla_for_each_nested(nl_limit
,
2080 tb_comb
[NL80211_IFACE_COMB_LIMITS
],
2082 err
= nla_parse_nested(tb_limit
,
2083 MAX_NL80211_IFACE_LIMIT
,
2085 iface_limit_policy
);
2087 !tb_limit
[NL80211_IFACE_LIMIT_TYPES
])
2088 goto broken_combination
;
2090 nla_for_each_nested(
2092 tb_limit
[NL80211_IFACE_LIMIT_TYPES
],
2094 int ift
= nla_type(nl_mode
);
2095 if (ift
== NL80211_IFTYPE_P2P_GO
||
2096 ift
== NL80211_IFTYPE_P2P_CLIENT
)
2097 combination_has_p2p
= 1;
2098 if (ift
== NL80211_IFTYPE_STATION
)
2099 combination_has_mgd
= 1;
2101 if (combination_has_p2p
&& combination_has_mgd
)
2105 if (combination_has_p2p
&& combination_has_mgd
) {
2115 if (tb
[NL80211_ATTR_SUPPORTED_COMMANDS
]) {
2116 struct nlattr
*nl_cmd
;
2119 nla_for_each_nested(nl_cmd
,
2120 tb
[NL80211_ATTR_SUPPORTED_COMMANDS
], i
) {
2121 switch (nla_get_u32(nl_cmd
)) {
2122 case NL80211_CMD_AUTHENTICATE
:
2125 case NL80211_CMD_CONNECT
:
2126 connect_supported
= 1;
2128 case NL80211_CMD_START_SCHED_SCAN
:
2129 capa
->sched_scan_supported
= 1;
2131 case NL80211_CMD_PROBE_CLIENT
:
2132 info
->poll_command_supported
= 1;
2138 if (tb
[NL80211_ATTR_OFFCHANNEL_TX_OK
]) {
2139 wpa_printf(MSG_DEBUG
, "nl80211: Using driver-based "
2141 capa
->flags
|= WPA_DRIVER_FLAGS_OFFCHANNEL_TX
;
2144 if (tb
[NL80211_ATTR_ROAM_SUPPORT
]) {
2145 wpa_printf(MSG_DEBUG
, "nl80211: Using driver-based roaming");
2146 capa
->flags
|= WPA_DRIVER_FLAGS_BSS_SELECTION
;
2149 /* default to 5000 since early versions of mac80211 don't set it */
2150 capa
->max_remain_on_chan
= 5000;
2152 if (tb
[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION
])
2153 capa
->max_remain_on_chan
=
2154 nla_get_u32(tb
[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION
]);
2157 capa
->flags
|= WPA_DRIVER_FLAGS_SME
;
2158 else if (!connect_supported
) {
2159 wpa_printf(MSG_INFO
, "nl80211: Driver does not support "
2160 "authentication/association or connect commands");
2164 if (p2p_go_supported
&& p2p_client_supported
)
2165 capa
->flags
|= WPA_DRIVER_FLAGS_P2P_CAPABLE
;
2166 if (p2p_concurrent
) {
2167 wpa_printf(MSG_DEBUG
, "nl80211: Use separate P2P group "
2168 "interface (driver advertised support)");
2169 capa
->flags
|= WPA_DRIVER_FLAGS_P2P_CONCURRENT
;
2170 capa
->flags
|= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P
;
2173 if (tb
[NL80211_ATTR_TDLS_SUPPORT
]) {
2174 wpa_printf(MSG_DEBUG
, "nl80211: TDLS supported");
2175 capa
->flags
|= WPA_DRIVER_FLAGS_TDLS_SUPPORT
;
2177 if (tb
[NL80211_ATTR_TDLS_EXTERNAL_SETUP
]) {
2178 wpa_printf(MSG_DEBUG
, "nl80211: TDLS external setup");
2180 WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP
;
2184 if (tb
[NL80211_ATTR_DEVICE_AP_SME
])
2185 info
->device_ap_sme
= 1;
2187 if (tb
[NL80211_ATTR_FEATURE_FLAGS
]) {
2188 u32 flags
= nla_get_u32(tb
[NL80211_ATTR_FEATURE_FLAGS
]);
2190 if (flags
& NL80211_FEATURE_SK_TX_STATUS
)
2191 info
->data_tx_status
= 1;
2198 static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data
*drv
,
2199 struct wiphy_info_data
*info
)
2203 os_memset(info
, 0, sizeof(*info
));
2204 info
->capa
= &drv
->capa
;
2206 msg
= nlmsg_alloc();
2210 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_GET_WIPHY
);
2212 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->first_bss
.ifindex
);
2214 if (send_and_recv_msgs(drv
, msg
, wiphy_info_handler
, info
) == 0)
2223 static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data
*drv
)
2225 struct wiphy_info_data info
;
2226 if (wpa_driver_nl80211_get_info(drv
, &info
))
2232 drv
->has_capability
= 1;
2233 /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
2234 drv
->capa
.key_mgmt
= WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2235 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
2236 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
2237 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
;
2238 drv
->capa
.enc
= WPA_DRIVER_CAPA_ENC_WEP40
|
2239 WPA_DRIVER_CAPA_ENC_WEP104
|
2240 WPA_DRIVER_CAPA_ENC_TKIP
|
2241 WPA_DRIVER_CAPA_ENC_CCMP
;
2242 drv
->capa
.auth
= WPA_DRIVER_AUTH_OPEN
|
2243 WPA_DRIVER_AUTH_SHARED
|
2244 WPA_DRIVER_AUTH_LEAP
;
2246 drv
->capa
.flags
|= WPA_DRIVER_FLAGS_SANE_ERROR_CODES
;
2247 drv
->capa
.flags
|= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE
;
2248 drv
->capa
.flags
|= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS
;
2249 drv
->capa
.flags
|= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS
;
2251 drv
->device_ap_sme
= info
.device_ap_sme
;
2252 drv
->poll_command_supported
= info
.poll_command_supported
;
2253 drv
->data_tx_status
= info
.data_tx_status
;
2256 * If poll command is supported mac80211 is new enough to
2257 * have everything we need to not need monitor interfaces.
2259 drv
->use_monitor
= !info
.poll_command_supported
;
2262 * If we aren't going to use monitor interfaces, but the
2263 * driver doesn't support data TX status, we won't get TX
2264 * status for EAPOL frames.
2266 if (!drv
->use_monitor
&& !info
.data_tx_status
)
2267 drv
->capa
.flags
&= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS
;
2273 static int wpa_driver_nl80211_init_nl_global(struct nl80211_global
*global
)
2275 global
->nl_cb
= nl_cb_alloc(NL_CB_DEFAULT
);
2276 if (global
->nl_cb
== NULL
) {
2277 wpa_printf(MSG_ERROR
, "nl80211: Failed to allocate netlink "
2282 if (nl_create_handles(&global
->nl
, global
->nl_cb
, "nl"))
2285 global
->nl80211_id
= genl_ctrl_resolve(global
->nl
.handle
, "nl80211");
2286 if (global
->nl80211_id
< 0) {
2287 wpa_printf(MSG_ERROR
, "nl80211: 'nl80211' generic netlink not "
2296 static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data
*drv
)
2298 struct nl80211_global
*global
= drv
->global
;
2301 /* Initialize generic netlink and nl80211 */
2303 if (nl_create_handles(&drv
->nl_event
, global
->nl_cb
, "event"))
2306 ret
= nl_get_multicast_id(drv
, "nl80211", "scan");
2308 ret
= nl_socket_add_membership(drv
->nl_event
.handle
, ret
);
2310 wpa_printf(MSG_ERROR
, "nl80211: Could not add multicast "
2311 "membership for scan events: %d (%s)",
2312 ret
, strerror(-ret
));
2316 ret
= nl_get_multicast_id(drv
, "nl80211", "mlme");
2318 ret
= nl_socket_add_membership(drv
->nl_event
.handle
, ret
);
2320 wpa_printf(MSG_ERROR
, "nl80211: Could not add multicast "
2321 "membership for mlme events: %d (%s)",
2322 ret
, strerror(-ret
));
2326 ret
= nl_get_multicast_id(drv
, "nl80211", "regulatory");
2328 ret
= nl_socket_add_membership(drv
->nl_event
.handle
, ret
);
2330 wpa_printf(MSG_DEBUG
, "nl80211: Could not add multicast "
2331 "membership for regulatory events: %d (%s)",
2332 ret
, strerror(-ret
));
2333 /* Continue without regulatory events */
2336 drv
->nl_cb
= nl_cb_alloc(NL_CB_DEFAULT
);
2338 wpa_printf(MSG_ERROR
, "nl80211: Failed to alloc cb struct");
2342 nl_cb_set(drv
->nl_cb
, NL_CB_SEQ_CHECK
, NL_CB_CUSTOM
,
2343 no_seq_check
, NULL
);
2344 nl_cb_set(drv
->nl_cb
, NL_CB_VALID
, NL_CB_CUSTOM
,
2345 process_drv_event
, drv
);
2347 eloop_register_read_sock(nl_socket_get_fd(drv
->nl_event
.handle
),
2348 wpa_driver_nl80211_event_receive
, drv
->nl_cb
,
2349 drv
->nl_event
.handle
);
2354 nl_destroy_handles(&drv
->nl_event
);
2360 static void wpa_driver_nl80211_rfkill_blocked(void *ctx
)
2362 wpa_printf(MSG_DEBUG
, "nl80211: RFKILL blocked");
2364 * This may be for any interface; use ifdown event to disable
2370 static void wpa_driver_nl80211_rfkill_unblocked(void *ctx
)
2372 struct wpa_driver_nl80211_data
*drv
= ctx
;
2373 wpa_printf(MSG_DEBUG
, "nl80211: RFKILL unblocked");
2374 if (linux_set_iface_flags(drv
->global
->ioctl_sock
,
2375 drv
->first_bss
.ifname
, 1)) {
2376 wpa_printf(MSG_DEBUG
, "nl80211: Could not set interface UP "
2377 "after rfkill unblock");
2380 /* rtnetlink ifup handler will report interface as enabled */
2384 static void nl80211_get_phy_name(struct wpa_driver_nl80211_data
*drv
)
2386 /* Find phy (radio) to which this interface belongs */
2390 drv
->phyname
[0] = '\0';
2391 snprintf(buf
, sizeof(buf
) - 1, "/sys/class/net/%s/phy80211/name",
2392 drv
->first_bss
.ifname
);
2393 f
= open(buf
, O_RDONLY
);
2395 wpa_printf(MSG_DEBUG
, "Could not open file %s: %s",
2396 buf
, strerror(errno
));
2400 rv
= read(f
, drv
->phyname
, sizeof(drv
->phyname
) - 1);
2403 wpa_printf(MSG_DEBUG
, "Could not read file %s: %s",
2404 buf
, strerror(errno
));
2408 drv
->phyname
[rv
] = '\0';
2409 pos
= os_strchr(drv
->phyname
, '\n');
2412 wpa_printf(MSG_DEBUG
, "nl80211: interface %s in phy %s",
2413 drv
->first_bss
.ifname
, drv
->phyname
);
2417 static void wpa_driver_nl80211_handle_eapol_tx_status(int sock
,
2421 struct wpa_driver_nl80211_data
*drv
= eloop_ctx
;
2429 struct cmsghdr
*cmsg
;
2430 int res
, found_ee
= 0, found_wifi
= 0, acked
= 0;
2431 union wpa_event_data event
;
2433 memset(&msg
, 0, sizeof(msg
));
2434 msg
.msg_iov
= &entry
;
2436 entry
.iov_base
= data
;
2437 entry
.iov_len
= sizeof(data
);
2438 msg
.msg_control
= &control
;
2439 msg
.msg_controllen
= sizeof(control
);
2441 res
= recvmsg(sock
, &msg
, MSG_ERRQUEUE
);
2442 /* if error or not fitting 802.3 header, return */
2446 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
; cmsg
= CMSG_NXTHDR(&msg
, cmsg
))
2448 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
2449 cmsg
->cmsg_type
== SCM_WIFI_STATUS
) {
2453 ack
= (void *)CMSG_DATA(cmsg
);
2457 if (cmsg
->cmsg_level
== SOL_PACKET
&&
2458 cmsg
->cmsg_type
== PACKET_TX_TIMESTAMP
) {
2459 struct sock_extended_err
*err
=
2460 (struct sock_extended_err
*)CMSG_DATA(cmsg
);
2462 if (err
->ee_origin
== SO_EE_ORIGIN_TXSTATUS
)
2467 if (!found_ee
|| !found_wifi
)
2470 memset(&event
, 0, sizeof(event
));
2471 event
.eapol_tx_status
.dst
= data
;
2472 event
.eapol_tx_status
.data
= data
+ 14;
2473 event
.eapol_tx_status
.data_len
= res
- 14;
2474 event
.eapol_tx_status
.ack
= acked
;
2475 wpa_supplicant_event(drv
->ctx
, EVENT_EAPOL_TX_STATUS
, &event
);
2479 static int nl80211_init_bss(struct i802_bss
*bss
)
2481 bss
->nl_cb
= nl_cb_alloc(NL_CB_DEFAULT
);
2485 nl_cb_set(bss
->nl_cb
, NL_CB_SEQ_CHECK
, NL_CB_CUSTOM
,
2486 no_seq_check
, NULL
);
2487 nl_cb_set(bss
->nl_cb
, NL_CB_VALID
, NL_CB_CUSTOM
,
2488 process_bss_event
, bss
);
2494 static void nl80211_destroy_bss(struct i802_bss
*bss
)
2496 nl_cb_put(bss
->nl_cb
);
2502 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
2503 * @ctx: context to be used when calling wpa_supplicant functions,
2504 * e.g., wpa_supplicant_event()
2505 * @ifname: interface name, e.g., wlan0
2506 * @global_priv: private driver global data from global_init()
2507 * Returns: Pointer to private data, %NULL on failure
2509 static void * wpa_driver_nl80211_init(void *ctx
, const char *ifname
,
2512 struct wpa_driver_nl80211_data
*drv
;
2513 struct rfkill_config
*rcfg
;
2514 struct i802_bss
*bss
;
2516 if (global_priv
== NULL
)
2518 drv
= os_zalloc(sizeof(*drv
));
2521 drv
->global
= global_priv
;
2523 bss
= &drv
->first_bss
;
2525 os_strlcpy(bss
->ifname
, ifname
, sizeof(bss
->ifname
));
2526 drv
->monitor_ifidx
= -1;
2527 drv
->monitor_sock
= -1;
2528 drv
->eapol_tx_sock
= -1;
2529 drv
->ap_scan_as_station
= NL80211_IFTYPE_UNSPECIFIED
;
2531 if (wpa_driver_nl80211_init_nl(drv
)) {
2536 if (nl80211_init_bss(bss
))
2539 nl80211_get_phy_name(drv
);
2541 rcfg
= os_zalloc(sizeof(*rcfg
));
2545 os_strlcpy(rcfg
->ifname
, ifname
, sizeof(rcfg
->ifname
));
2546 rcfg
->blocked_cb
= wpa_driver_nl80211_rfkill_blocked
;
2547 rcfg
->unblocked_cb
= wpa_driver_nl80211_rfkill_unblocked
;
2548 drv
->rfkill
= rfkill_init(rcfg
);
2549 if (drv
->rfkill
== NULL
) {
2550 wpa_printf(MSG_DEBUG
, "nl80211: RFKILL status not available");
2554 if (wpa_driver_nl80211_finish_drv_init(drv
))
2557 drv
->eapol_tx_sock
= socket(PF_PACKET
, SOCK_DGRAM
, 0);
2558 if (drv
->eapol_tx_sock
< 0)
2561 if (drv
->data_tx_status
) {
2564 if (setsockopt(drv
->eapol_tx_sock
, SOL_SOCKET
, SO_WIFI_STATUS
,
2565 &enabled
, sizeof(enabled
)) < 0) {
2566 wpa_printf(MSG_DEBUG
,
2567 "nl80211: wifi status sockopt failed\n");
2568 drv
->data_tx_status
= 0;
2569 if (!drv
->use_monitor
)
2571 ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS
;
2573 eloop_register_read_sock(drv
->eapol_tx_sock
,
2574 wpa_driver_nl80211_handle_eapol_tx_status
,
2580 dl_list_add(&drv
->global
->interfaces
, &drv
->list
);
2581 drv
->in_interface_list
= 1;
2587 wpa_driver_nl80211_deinit(bss
);
2592 static int nl80211_register_frame(struct i802_bss
*bss
,
2593 struct nl_handle
*nl_handle
,
2594 u16 type
, const u8
*match
, size_t match_len
)
2596 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
2600 msg
= nlmsg_alloc();
2604 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_REGISTER_ACTION
);
2606 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, bss
->ifindex
);
2607 NLA_PUT_U16(msg
, NL80211_ATTR_FRAME_TYPE
, type
);
2608 NLA_PUT(msg
, NL80211_ATTR_FRAME_MATCH
, match_len
, match
);
2610 ret
= send_and_recv(drv
, nl_handle
, msg
, NULL
, NULL
);
2613 wpa_printf(MSG_DEBUG
, "nl80211: Register frame command "
2614 "failed (type=%u): ret=%d (%s)",
2615 type
, ret
, strerror(-ret
));
2616 wpa_hexdump(MSG_DEBUG
, "nl80211: Register frame match",
2618 goto nla_put_failure
;
2627 static int nl80211_alloc_mgmt_handle(struct i802_bss
*bss
)
2629 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
2631 if (bss
->nl_mgmt
.handle
) {
2632 wpa_printf(MSG_DEBUG
, "nl80211: Mgmt reporting "
2637 if (nl_create_handles(&bss
->nl_mgmt
, drv
->nl_cb
, "mgmt"))
2640 eloop_register_read_sock(nl_socket_get_fd(bss
->nl_mgmt
.handle
),
2641 wpa_driver_nl80211_event_receive
, bss
->nl_cb
,
2642 bss
->nl_mgmt
.handle
);
2648 static int nl80211_register_action_frame(struct i802_bss
*bss
,
2649 const u8
*match
, size_t match_len
)
2651 u16 type
= (WLAN_FC_TYPE_MGMT
<< 2) | (WLAN_FC_STYPE_ACTION
<< 4);
2652 return nl80211_register_frame(bss
, bss
->nl_mgmt
.handle
,
2653 type
, match
, match_len
);
2657 static int nl80211_mgmt_subscribe_non_ap(struct i802_bss
*bss
)
2659 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
2661 if (nl80211_alloc_mgmt_handle(bss
))
2664 #if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
2665 /* GAS Initial Request */
2666 if (nl80211_register_action_frame(bss
, (u8
*) "\x04\x0a", 2) < 0)
2668 /* GAS Initial Response */
2669 if (nl80211_register_action_frame(bss
, (u8
*) "\x04\x0b", 2) < 0)
2671 /* GAS Comeback Request */
2672 if (nl80211_register_action_frame(bss
, (u8
*) "\x04\x0c", 2) < 0)
2674 /* GAS Comeback Response */
2675 if (nl80211_register_action_frame(bss
, (u8
*) "\x04\x0d", 2) < 0)
2677 #endif /* CONFIG_P2P || CONFIG_INTERWORKING */
2679 /* P2P Public Action */
2680 if (nl80211_register_action_frame(bss
,
2681 (u8
*) "\x04\x09\x50\x6f\x9a\x09",
2685 if (nl80211_register_action_frame(bss
,
2686 (u8
*) "\x7f\x50\x6f\x9a\x09",
2689 #endif /* CONFIG_P2P */
2690 #ifdef CONFIG_IEEE80211W
2691 /* SA Query Response */
2692 if (nl80211_register_action_frame(bss
, (u8
*) "\x08\x01", 2) < 0)
2694 #endif /* CONFIG_IEEE80211W */
2696 if ((drv
->capa
.flags
& WPA_DRIVER_FLAGS_TDLS_SUPPORT
)) {
2697 /* TDLS Discovery Response */
2698 if (nl80211_register_action_frame(drv
, (u8
*) "\x04\x0e", 2) <
2702 #endif /* CONFIG_TDLS */
2704 /* FT Action frames */
2705 if (nl80211_register_action_frame(bss
, (u8
*) "\x06", 1) < 0)
2708 drv
->capa
.key_mgmt
|= WPA_DRIVER_CAPA_KEY_MGMT_FT
|
2709 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK
;
2711 /* WNM - BSS Transition Management Request */
2712 if (nl80211_register_action_frame(bss
, (u8
*) "\x0a\x07", 2) < 0)
2719 static int nl80211_register_spurious_class3(struct i802_bss
*bss
)
2721 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
2725 msg
= nlmsg_alloc();
2729 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_UNEXPECTED_FRAME
);
2731 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, bss
->ifindex
);
2733 ret
= send_and_recv(drv
, bss
->nl_mgmt
.handle
, msg
, NULL
, NULL
);
2736 wpa_printf(MSG_DEBUG
, "nl80211: Register spurious class3 "
2737 "failed: ret=%d (%s)",
2738 ret
, strerror(-ret
));
2739 goto nla_put_failure
;
2748 static int nl80211_mgmt_subscribe_ap(struct i802_bss
*bss
)
2750 static const int stypes
[] = {
2752 WLAN_FC_STYPE_ASSOC_REQ
,
2753 WLAN_FC_STYPE_REASSOC_REQ
,
2754 WLAN_FC_STYPE_DISASSOC
,
2755 WLAN_FC_STYPE_DEAUTH
,
2756 WLAN_FC_STYPE_ACTION
,
2757 WLAN_FC_STYPE_PROBE_REQ
,
2758 /* Beacon doesn't work as mac80211 doesn't currently allow
2759 * it, but it wouldn't really be the right thing anyway as
2760 * it isn't per interface ... maybe just dump the scan
2761 * results periodically for OLBC?
2763 // WLAN_FC_STYPE_BEACON,
2767 if (nl80211_alloc_mgmt_handle(bss
))
2770 for (i
= 0; i
< sizeof(stypes
) / sizeof(stypes
[0]); i
++) {
2771 if (nl80211_register_frame(bss
, bss
->nl_mgmt
.handle
,
2772 (WLAN_FC_TYPE_MGMT
<< 2) |
2779 if (nl80211_register_spurious_class3(bss
))
2785 eloop_unregister_read_sock(nl_socket_get_fd(bss
->nl_mgmt
.handle
));
2786 nl_destroy_handles(&bss
->nl_mgmt
);
2791 static void nl80211_mgmt_unsubscribe(struct i802_bss
*bss
)
2793 if (bss
->nl_mgmt
.handle
== NULL
)
2795 eloop_unregister_read_sock(nl_socket_get_fd(bss
->nl_mgmt
.handle
));
2796 nl_destroy_handles(&bss
->nl_mgmt
);
2800 static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx
, void *timeout_ctx
)
2802 wpa_supplicant_event(timeout_ctx
, EVENT_INTERFACE_DISABLED
, NULL
);
2807 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data
*drv
)
2809 struct i802_bss
*bss
= &drv
->first_bss
;
2810 int send_rfkill_event
= 0;
2812 drv
->ifindex
= if_nametoindex(bss
->ifname
);
2813 drv
->first_bss
.ifindex
= drv
->ifindex
;
2817 * Make sure the interface starts up in station mode unless this is a
2818 * dynamically added interface (e.g., P2P) that was already configured
2819 * with proper iftype.
2821 if (drv
->ifindex
!= drv
->global
->if_add_ifindex
&&
2822 wpa_driver_nl80211_set_mode(bss
, NL80211_IFTYPE_STATION
) < 0) {
2823 wpa_printf(MSG_ERROR
, "nl80211: Could not configure driver to "
2824 "use managed mode");
2828 if (linux_set_iface_flags(drv
->global
->ioctl_sock
, bss
->ifname
, 1)) {
2829 if (rfkill_is_blocked(drv
->rfkill
)) {
2830 wpa_printf(MSG_DEBUG
, "nl80211: Could not yet enable "
2831 "interface '%s' due to rfkill",
2833 drv
->if_disabled
= 1;
2834 send_rfkill_event
= 1;
2836 wpa_printf(MSG_ERROR
, "nl80211: Could not set "
2837 "interface '%s' UP", bss
->ifname
);
2842 netlink_send_oper_ifla(drv
->global
->netlink
, drv
->ifindex
,
2843 1, IF_OPER_DORMANT
);
2844 #endif /* HOSTAPD */
2846 if (wpa_driver_nl80211_capa(drv
))
2849 if (linux_get_ifhwaddr(drv
->global
->ioctl_sock
, bss
->ifname
,
2853 if (send_rfkill_event
) {
2854 eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill
,
2862 static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data
*drv
)
2866 msg
= nlmsg_alloc();
2870 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_DEL_BEACON
);
2871 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
2873 return send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
2880 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
2881 * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
2883 * Shut down driver interface and processing of driver events. Free
2884 * private data buffer if one was allocated in wpa_driver_nl80211_init().
2886 static void wpa_driver_nl80211_deinit(void *priv
)
2888 struct i802_bss
*bss
= priv
;
2889 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
2891 if (drv
->data_tx_status
)
2892 eloop_unregister_read_sock(drv
->eapol_tx_sock
);
2893 if (drv
->eapol_tx_sock
>= 0)
2894 close(drv
->eapol_tx_sock
);
2896 if (bss
->nl_preq
.handle
)
2897 wpa_driver_nl80211_probe_req_report(bss
, 0);
2898 if (bss
->added_if_into_bridge
) {
2899 if (linux_br_del_if(drv
->global
->ioctl_sock
, bss
->brname
,
2901 wpa_printf(MSG_INFO
, "nl80211: Failed to remove "
2902 "interface %s from bridge %s: %s",
2903 bss
->ifname
, bss
->brname
, strerror(errno
));
2905 if (bss
->added_bridge
) {
2906 if (linux_br_del(drv
->global
->ioctl_sock
, bss
->brname
) < 0)
2907 wpa_printf(MSG_INFO
, "nl80211: Failed to remove "
2909 bss
->brname
, strerror(errno
));
2912 nl80211_remove_monitor_interface(drv
);
2914 if (is_ap_interface(drv
->nlmode
))
2915 wpa_driver_nl80211_del_beacon(drv
);
2918 if (drv
->last_freq_ht
) {
2919 /* Clear HT flags from the driver */
2920 struct hostapd_freq_params freq
;
2921 os_memset(&freq
, 0, sizeof(freq
));
2922 freq
.freq
= drv
->last_freq
;
2923 i802_set_freq(priv
, &freq
);
2926 if (drv
->eapol_sock
>= 0) {
2927 eloop_unregister_read_sock(drv
->eapol_sock
);
2928 close(drv
->eapol_sock
);
2931 if (drv
->if_indices
!= drv
->default_if_indices
)
2932 os_free(drv
->if_indices
);
2933 #endif /* HOSTAPD */
2935 if (drv
->disabled_11b_rates
)
2936 nl80211_disable_11b_rates(drv
, drv
->ifindex
, 0);
2938 netlink_send_oper_ifla(drv
->global
->netlink
, drv
->ifindex
, 0,
2940 rfkill_deinit(drv
->rfkill
);
2942 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout
, drv
, drv
->ctx
);
2944 (void) linux_set_iface_flags(drv
->global
->ioctl_sock
, bss
->ifname
, 0);
2945 wpa_driver_nl80211_set_mode(bss
, NL80211_IFTYPE_STATION
);
2946 nl80211_mgmt_unsubscribe(bss
);
2948 eloop_unregister_read_sock(nl_socket_get_fd(drv
->nl_event
.handle
));
2949 nl_destroy_handles(&drv
->nl_event
);
2950 nl_cb_put(drv
->nl_cb
);
2952 nl80211_destroy_bss(&drv
->first_bss
);
2954 os_free(drv
->filter_ssids
);
2956 os_free(drv
->auth_ie
);
2958 if (drv
->in_interface_list
)
2959 dl_list_del(&drv
->list
);
2966 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
2967 * @eloop_ctx: Driver private data
2968 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
2970 * This function can be used as registered timeout when starting a scan to
2971 * generate a scan completed event if the driver does not report this.
2973 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx
, void *timeout_ctx
)
2975 struct wpa_driver_nl80211_data
*drv
= eloop_ctx
;
2976 if (drv
->ap_scan_as_station
!= NL80211_IFTYPE_UNSPECIFIED
) {
2977 wpa_driver_nl80211_set_mode(&drv
->first_bss
,
2978 drv
->ap_scan_as_station
);
2979 drv
->ap_scan_as_station
= NL80211_IFTYPE_UNSPECIFIED
;
2981 wpa_printf(MSG_DEBUG
, "Scan timeout - try to get results");
2982 wpa_supplicant_event(timeout_ctx
, EVENT_SCAN_RESULTS
, NULL
);
2987 * wpa_driver_nl80211_scan - Request the driver to initiate scan
2988 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
2989 * @params: Scan parameters
2990 * Returns: 0 on success, -1 on failure
2992 static int wpa_driver_nl80211_scan(void *priv
,
2993 struct wpa_driver_scan_params
*params
)
2995 struct i802_bss
*bss
= priv
;
2996 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
2997 int ret
= 0, timeout
;
2998 struct nl_msg
*msg
, *ssids
, *freqs
, *rates
;
3001 drv
->scan_for_auth
= 0;
3003 msg
= nlmsg_alloc();
3004 ssids
= nlmsg_alloc();
3005 freqs
= nlmsg_alloc();
3006 rates
= nlmsg_alloc();
3007 if (!msg
|| !ssids
|| !freqs
|| !rates
) {
3015 os_free(drv
->filter_ssids
);
3016 drv
->filter_ssids
= params
->filter_ssids
;
3017 params
->filter_ssids
= NULL
;
3018 drv
->num_filter_ssids
= params
->num_filter_ssids
;
3020 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_TRIGGER_SCAN
);
3022 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
3024 for (i
= 0; i
< params
->num_ssids
; i
++) {
3025 wpa_hexdump_ascii(MSG_MSGDUMP
, "nl80211: Scan SSID",
3026 params
->ssids
[i
].ssid
,
3027 params
->ssids
[i
].ssid_len
);
3028 NLA_PUT(ssids
, i
+ 1, params
->ssids
[i
].ssid_len
,
3029 params
->ssids
[i
].ssid
);
3031 if (params
->num_ssids
)
3032 nla_put_nested(msg
, NL80211_ATTR_SCAN_SSIDS
, ssids
);
3034 if (params
->extra_ies
) {
3035 wpa_hexdump(MSG_MSGDUMP
, "nl80211: Scan extra IEs",
3036 params
->extra_ies
, params
->extra_ies_len
);
3037 NLA_PUT(msg
, NL80211_ATTR_IE
, params
->extra_ies_len
,
3041 if (params
->freqs
) {
3042 for (i
= 0; params
->freqs
[i
]; i
++) {
3043 wpa_printf(MSG_MSGDUMP
, "nl80211: Scan frequency %u "
3044 "MHz", params
->freqs
[i
]);
3045 NLA_PUT_U32(freqs
, i
+ 1, params
->freqs
[i
]);
3047 nla_put_nested(msg
, NL80211_ATTR_SCAN_FREQUENCIES
, freqs
);
3050 if (params
->p2p_probe
) {
3052 * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
3053 * by masking out everything else apart from the OFDM rates 6,
3054 * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
3055 * rates are left enabled.
3057 NLA_PUT(rates
, NL80211_BAND_2GHZ
, 8,
3058 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
3059 nla_put_nested(msg
, NL80211_ATTR_SCAN_SUPP_RATES
, rates
);
3061 NLA_PUT_FLAG(msg
, NL80211_ATTR_TX_NO_CCK_RATE
);
3064 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
3067 wpa_printf(MSG_DEBUG
, "nl80211: Scan trigger failed: ret=%d "
3068 "(%s)", ret
, strerror(-ret
));
3070 if (is_ap_interface(drv
->nlmode
)) {
3072 * mac80211 does not allow scan requests in AP mode, so
3073 * try to do this in station mode.
3075 if (wpa_driver_nl80211_set_mode(
3076 bss
, NL80211_IFTYPE_STATION
))
3077 goto nla_put_failure
;
3079 if (wpa_driver_nl80211_scan(drv
, params
)) {
3080 wpa_driver_nl80211_set_mode(bss
, drv
->nlmode
);
3081 goto nla_put_failure
;
3084 /* Restore AP mode when processing scan results */
3085 drv
->ap_scan_as_station
= drv
->nlmode
;
3088 goto nla_put_failure
;
3090 goto nla_put_failure
;
3091 #endif /* HOSTAPD */
3094 /* Not all drivers generate "scan completed" wireless event, so try to
3095 * read results after a timeout. */
3097 if (drv
->scan_complete_events
) {
3099 * The driver seems to deliver events to notify when scan is
3100 * complete, so use longer timeout to avoid race conditions
3101 * with scanning and following association request.
3105 wpa_printf(MSG_DEBUG
, "Scan requested (ret=%d) - scan timeout %d "
3106 "seconds", ret
, timeout
);
3107 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout
, drv
, drv
->ctx
);
3108 eloop_register_timeout(timeout
, 0, wpa_driver_nl80211_scan_timeout
,
3121 * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
3122 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
3123 * @params: Scan parameters
3124 * @interval: Interval between scan cycles in milliseconds
3125 * Returns: 0 on success, -1 on failure or if not supported
3127 static int wpa_driver_nl80211_sched_scan(void *priv
,
3128 struct wpa_driver_scan_params
*params
,
3131 struct i802_bss
*bss
= priv
;
3132 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
3134 struct nl_msg
*msg
, *ssids
, *freqs
, *match_set_ssid
, *match_sets
;
3138 if (!drv
->capa
.sched_scan_supported
)
3139 return android_pno_start(bss
, params
);
3140 #endif /* ANDROID */
3142 msg
= nlmsg_alloc();
3143 ssids
= nlmsg_alloc();
3144 freqs
= nlmsg_alloc();
3145 if (!msg
|| !ssids
|| !freqs
) {
3152 os_free(drv
->filter_ssids
);
3153 drv
->filter_ssids
= params
->filter_ssids
;
3154 params
->filter_ssids
= NULL
;
3155 drv
->num_filter_ssids
= params
->num_filter_ssids
;
3157 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_START_SCHED_SCAN
);
3159 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
3161 NLA_PUT_U32(msg
, NL80211_ATTR_SCHED_SCAN_INTERVAL
, interval
);
3163 if (drv
->num_filter_ssids
&&
3164 (int) drv
->num_filter_ssids
<= drv
->capa
.max_match_sets
) {
3165 match_sets
= nlmsg_alloc();
3167 for (i
= 0; i
< drv
->num_filter_ssids
; i
++) {
3168 wpa_hexdump_ascii(MSG_MSGDUMP
,
3169 "nl80211: Sched scan filter SSID",
3170 drv
->filter_ssids
[i
].ssid
,
3171 drv
->filter_ssids
[i
].ssid_len
);
3173 match_set_ssid
= nlmsg_alloc();
3174 nla_put(match_set_ssid
,
3175 NL80211_ATTR_SCHED_SCAN_MATCH_SSID
,
3176 drv
->filter_ssids
[i
].ssid_len
,
3177 drv
->filter_ssids
[i
].ssid
);
3179 nla_put_nested(match_sets
, i
+ 1, match_set_ssid
);
3181 nlmsg_free(match_set_ssid
);
3184 nla_put_nested(msg
, NL80211_ATTR_SCHED_SCAN_MATCH
,
3186 nlmsg_free(match_sets
);
3189 for (i
= 0; i
< params
->num_ssids
; i
++) {
3190 wpa_hexdump_ascii(MSG_MSGDUMP
, "nl80211: Sched scan SSID",
3191 params
->ssids
[i
].ssid
,
3192 params
->ssids
[i
].ssid_len
);
3193 NLA_PUT(ssids
, i
+ 1, params
->ssids
[i
].ssid_len
,
3194 params
->ssids
[i
].ssid
);
3196 if (params
->num_ssids
)
3197 nla_put_nested(msg
, NL80211_ATTR_SCAN_SSIDS
, ssids
);
3199 if (params
->extra_ies
) {
3200 wpa_hexdump_ascii(MSG_MSGDUMP
, "nl80211: Sched scan extra IEs",
3201 params
->extra_ies
, params
->extra_ies_len
);
3202 NLA_PUT(msg
, NL80211_ATTR_IE
, params
->extra_ies_len
,
3206 if (params
->freqs
) {
3207 for (i
= 0; params
->freqs
[i
]; i
++) {
3208 wpa_printf(MSG_MSGDUMP
, "nl80211: Scan frequency %u "
3209 "MHz", params
->freqs
[i
]);
3210 NLA_PUT_U32(freqs
, i
+ 1, params
->freqs
[i
]);
3212 nla_put_nested(msg
, NL80211_ATTR_SCAN_FREQUENCIES
, freqs
);
3215 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
3217 /* TODO: if we get an error here, we should fall back to normal scan */
3221 wpa_printf(MSG_DEBUG
, "nl80211: Sched scan start failed: "
3222 "ret=%d (%s)", ret
, strerror(-ret
));
3223 goto nla_put_failure
;
3226 wpa_printf(MSG_DEBUG
, "nl80211: Sched scan requested (ret=%d) - "
3227 "scan interval %d msec", ret
, interval
);
3238 * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
3239 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
3240 * Returns: 0 on success, -1 on failure or if not supported
3242 static int wpa_driver_nl80211_stop_sched_scan(void *priv
)
3244 struct i802_bss
*bss
= priv
;
3245 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
3250 if (!drv
->capa
.sched_scan_supported
)
3251 return android_pno_stop(bss
);
3252 #endif /* ANDROID */
3254 msg
= nlmsg_alloc();
3258 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_STOP_SCHED_SCAN
);
3260 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
3262 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
3265 wpa_printf(MSG_DEBUG
, "nl80211: Sched scan stop failed: "
3266 "ret=%d (%s)", ret
, strerror(-ret
));
3267 goto nla_put_failure
;
3270 wpa_printf(MSG_DEBUG
, "nl80211: Sched scan stop sent (ret=%d)", ret
);
3278 static const u8
* nl80211_get_ie(const u8
*ies
, size_t ies_len
, u8 ie
)
3280 const u8
*end
, *pos
;
3286 end
= ies
+ ies_len
;
3288 while (pos
+ 1 < end
) {
3289 if (pos
+ 2 + pos
[1] > end
)
3300 static int nl80211_scan_filtered(struct wpa_driver_nl80211_data
*drv
,
3301 const u8
*ie
, size_t ie_len
)
3306 if (drv
->filter_ssids
== NULL
)
3309 ssid
= nl80211_get_ie(ie
, ie_len
, WLAN_EID_SSID
);
3313 for (i
= 0; i
< drv
->num_filter_ssids
; i
++) {
3314 if (ssid
[1] == drv
->filter_ssids
[i
].ssid_len
&&
3315 os_memcmp(ssid
+ 2, drv
->filter_ssids
[i
].ssid
, ssid
[1]) ==
3324 static int bss_info_handler(struct nl_msg
*msg
, void *arg
)
3326 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
3327 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
3328 struct nlattr
*bss
[NL80211_BSS_MAX
+ 1];
3329 static struct nla_policy bss_policy
[NL80211_BSS_MAX
+ 1] = {
3330 [NL80211_BSS_BSSID
] = { .type
= NLA_UNSPEC
},
3331 [NL80211_BSS_FREQUENCY
] = { .type
= NLA_U32
},
3332 [NL80211_BSS_TSF
] = { .type
= NLA_U64
},
3333 [NL80211_BSS_BEACON_INTERVAL
] = { .type
= NLA_U16
},
3334 [NL80211_BSS_CAPABILITY
] = { .type
= NLA_U16
},
3335 [NL80211_BSS_INFORMATION_ELEMENTS
] = { .type
= NLA_UNSPEC
},
3336 [NL80211_BSS_SIGNAL_MBM
] = { .type
= NLA_U32
},
3337 [NL80211_BSS_SIGNAL_UNSPEC
] = { .type
= NLA_U8
},
3338 [NL80211_BSS_STATUS
] = { .type
= NLA_U32
},
3339 [NL80211_BSS_SEEN_MS_AGO
] = { .type
= NLA_U32
},
3340 [NL80211_BSS_BEACON_IES
] = { .type
= NLA_UNSPEC
},
3342 struct nl80211_bss_info_arg
*_arg
= arg
;
3343 struct wpa_scan_results
*res
= _arg
->res
;
3344 struct wpa_scan_res
**tmp
;
3345 struct wpa_scan_res
*r
;
3346 const u8
*ie
, *beacon_ie
;
3347 size_t ie_len
, beacon_ie_len
;
3351 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
3352 genlmsg_attrlen(gnlh
, 0), NULL
);
3353 if (!tb
[NL80211_ATTR_BSS
])
3355 if (nla_parse_nested(bss
, NL80211_BSS_MAX
, tb
[NL80211_ATTR_BSS
],
3358 if (bss
[NL80211_BSS_STATUS
]) {
3359 enum nl80211_bss_status status
;
3360 status
= nla_get_u32(bss
[NL80211_BSS_STATUS
]);
3361 if (status
== NL80211_BSS_STATUS_ASSOCIATED
&&
3362 bss
[NL80211_BSS_FREQUENCY
]) {
3364 nla_get_u32(bss
[NL80211_BSS_FREQUENCY
]);
3365 wpa_printf(MSG_DEBUG
, "nl80211: Associated on %u MHz",
3368 if (status
== NL80211_BSS_STATUS_ASSOCIATED
&&
3369 bss
[NL80211_BSS_BSSID
]) {
3370 os_memcpy(_arg
->assoc_bssid
,
3371 nla_data(bss
[NL80211_BSS_BSSID
]), ETH_ALEN
);
3372 wpa_printf(MSG_DEBUG
, "nl80211: Associated with "
3373 MACSTR
, MAC2STR(_arg
->assoc_bssid
));
3378 if (bss
[NL80211_BSS_INFORMATION_ELEMENTS
]) {
3379 ie
= nla_data(bss
[NL80211_BSS_INFORMATION_ELEMENTS
]);
3380 ie_len
= nla_len(bss
[NL80211_BSS_INFORMATION_ELEMENTS
]);
3385 if (bss
[NL80211_BSS_BEACON_IES
]) {
3386 beacon_ie
= nla_data(bss
[NL80211_BSS_BEACON_IES
]);
3387 beacon_ie_len
= nla_len(bss
[NL80211_BSS_BEACON_IES
]);
3393 if (nl80211_scan_filtered(_arg
->drv
, ie
? ie
: beacon_ie
,
3394 ie
? ie_len
: beacon_ie_len
))
3397 r
= os_zalloc(sizeof(*r
) + ie_len
+ beacon_ie_len
);
3400 if (bss
[NL80211_BSS_BSSID
])
3401 os_memcpy(r
->bssid
, nla_data(bss
[NL80211_BSS_BSSID
]),
3403 if (bss
[NL80211_BSS_FREQUENCY
])
3404 r
->freq
= nla_get_u32(bss
[NL80211_BSS_FREQUENCY
]);
3405 if (bss
[NL80211_BSS_BEACON_INTERVAL
])
3406 r
->beacon_int
= nla_get_u16(bss
[NL80211_BSS_BEACON_INTERVAL
]);
3407 if (bss
[NL80211_BSS_CAPABILITY
])
3408 r
->caps
= nla_get_u16(bss
[NL80211_BSS_CAPABILITY
]);
3409 r
->flags
|= WPA_SCAN_NOISE_INVALID
;
3410 if (bss
[NL80211_BSS_SIGNAL_MBM
]) {
3411 r
->level
= nla_get_u32(bss
[NL80211_BSS_SIGNAL_MBM
]);
3412 r
->level
/= 100; /* mBm to dBm */
3413 r
->flags
|= WPA_SCAN_LEVEL_DBM
| WPA_SCAN_QUAL_INVALID
;
3414 } else if (bss
[NL80211_BSS_SIGNAL_UNSPEC
]) {
3415 r
->level
= nla_get_u8(bss
[NL80211_BSS_SIGNAL_UNSPEC
]);
3416 r
->flags
|= WPA_SCAN_QUAL_INVALID
;
3418 r
->flags
|= WPA_SCAN_LEVEL_INVALID
| WPA_SCAN_QUAL_INVALID
;
3419 if (bss
[NL80211_BSS_TSF
])
3420 r
->tsf
= nla_get_u64(bss
[NL80211_BSS_TSF
]);
3421 if (bss
[NL80211_BSS_SEEN_MS_AGO
])
3422 r
->age
= nla_get_u32(bss
[NL80211_BSS_SEEN_MS_AGO
]);
3424 pos
= (u8
*) (r
+ 1);
3426 os_memcpy(pos
, ie
, ie_len
);
3429 r
->beacon_ie_len
= beacon_ie_len
;
3431 os_memcpy(pos
, beacon_ie
, beacon_ie_len
);
3433 if (bss
[NL80211_BSS_STATUS
]) {
3434 enum nl80211_bss_status status
;
3435 status
= nla_get_u32(bss
[NL80211_BSS_STATUS
]);
3437 case NL80211_BSS_STATUS_AUTHENTICATED
:
3438 r
->flags
|= WPA_SCAN_AUTHENTICATED
;
3440 case NL80211_BSS_STATUS_ASSOCIATED
:
3441 r
->flags
|= WPA_SCAN_ASSOCIATED
;
3449 * cfg80211 maintains separate BSS table entries for APs if the same
3450 * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
3451 * not use frequency as a separate key in the BSS table, so filter out
3452 * duplicated entries. Prefer associated BSS entry in such a case in
3453 * order to get the correct frequency into the BSS table.
3455 for (i
= 0; i
< res
->num
; i
++) {
3457 if (os_memcmp(res
->res
[i
]->bssid
, r
->bssid
, ETH_ALEN
) != 0)
3460 s1
= nl80211_get_ie((u8
*) (res
->res
[i
] + 1),
3461 res
->res
[i
]->ie_len
, WLAN_EID_SSID
);
3462 s2
= nl80211_get_ie((u8
*) (r
+ 1), r
->ie_len
, WLAN_EID_SSID
);
3463 if (s1
== NULL
|| s2
== NULL
|| s1
[1] != s2
[1] ||
3464 os_memcmp(s1
, s2
, 2 + s1
[1]) != 0)
3467 /* Same BSSID,SSID was already included in scan results */
3468 wpa_printf(MSG_DEBUG
, "nl80211: Remove duplicated scan result "
3469 "for " MACSTR
, MAC2STR(r
->bssid
));
3471 if ((r
->flags
& WPA_SCAN_ASSOCIATED
) &&
3472 !(res
->res
[i
]->flags
& WPA_SCAN_ASSOCIATED
)) {
3473 os_free(res
->res
[i
]);
3480 tmp
= os_realloc(res
->res
,
3481 (res
->num
+ 1) * sizeof(struct wpa_scan_res
*));
3486 tmp
[res
->num
++] = r
;
3493 static void clear_state_mismatch(struct wpa_driver_nl80211_data
*drv
,
3496 if (drv
->capa
.flags
& WPA_DRIVER_FLAGS_SME
) {
3497 wpa_printf(MSG_DEBUG
, "nl80211: Clear possible state "
3498 "mismatch (" MACSTR
")", MAC2STR(addr
));
3499 wpa_driver_nl80211_mlme(drv
, addr
,
3500 NL80211_CMD_DEAUTHENTICATE
,
3501 WLAN_REASON_PREV_AUTH_NOT_VALID
, 1);
3506 static void wpa_driver_nl80211_check_bss_status(
3507 struct wpa_driver_nl80211_data
*drv
, struct wpa_scan_results
*res
)
3511 for (i
= 0; i
< res
->num
; i
++) {
3512 struct wpa_scan_res
*r
= res
->res
[i
];
3513 if (r
->flags
& WPA_SCAN_AUTHENTICATED
) {
3514 wpa_printf(MSG_DEBUG
, "nl80211: Scan results "
3515 "indicates BSS status with " MACSTR
3516 " as authenticated",
3518 if (is_sta_interface(drv
->nlmode
) &&
3519 os_memcmp(r
->bssid
, drv
->bssid
, ETH_ALEN
) != 0 &&
3520 os_memcmp(r
->bssid
, drv
->auth_bssid
, ETH_ALEN
) !=
3522 wpa_printf(MSG_DEBUG
, "nl80211: Unknown BSSID"
3523 " in local state (auth=" MACSTR
3524 " assoc=" MACSTR
")",
3525 MAC2STR(drv
->auth_bssid
),
3526 MAC2STR(drv
->bssid
));
3527 clear_state_mismatch(drv
, r
->bssid
);
3531 if (r
->flags
& WPA_SCAN_ASSOCIATED
) {
3532 wpa_printf(MSG_DEBUG
, "nl80211: Scan results "
3533 "indicate BSS status with " MACSTR
3536 if (is_sta_interface(drv
->nlmode
) &&
3538 wpa_printf(MSG_DEBUG
, "nl80211: Local state "
3539 "(not associated) does not match "
3541 clear_state_mismatch(drv
, r
->bssid
);
3542 } else if (is_sta_interface(drv
->nlmode
) &&
3543 os_memcmp(drv
->bssid
, r
->bssid
, ETH_ALEN
) !=
3545 wpa_printf(MSG_DEBUG
, "nl80211: Local state "
3546 "(associated with " MACSTR
") does "
3547 "not match with BSS state",
3548 MAC2STR(drv
->bssid
));
3549 clear_state_mismatch(drv
, r
->bssid
);
3550 clear_state_mismatch(drv
, drv
->bssid
);
3557 static struct wpa_scan_results
*
3558 nl80211_get_scan_results(struct wpa_driver_nl80211_data
*drv
)
3561 struct wpa_scan_results
*res
;
3563 struct nl80211_bss_info_arg arg
;
3565 res
= os_zalloc(sizeof(*res
));
3568 msg
= nlmsg_alloc();
3570 goto nla_put_failure
;
3572 nl80211_cmd(drv
, msg
, NLM_F_DUMP
, NL80211_CMD_GET_SCAN
);
3573 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
3577 ret
= send_and_recv_msgs(drv
, msg
, bss_info_handler
, &arg
);
3580 wpa_printf(MSG_DEBUG
, "nl80211: Received scan results (%lu "
3581 "BSSes)", (unsigned long) res
->num
);
3582 nl80211_get_noise_for_scan_results(drv
, res
);
3585 wpa_printf(MSG_DEBUG
, "nl80211: Scan result fetch failed: ret=%d "
3586 "(%s)", ret
, strerror(-ret
));
3589 wpa_scan_results_free(res
);
3595 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
3596 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
3597 * Returns: Scan results on success, -1 on failure
3599 static struct wpa_scan_results
*
3600 wpa_driver_nl80211_get_scan_results(void *priv
)
3602 struct i802_bss
*bss
= priv
;
3603 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
3604 struct wpa_scan_results
*res
;
3606 res
= nl80211_get_scan_results(drv
);
3608 wpa_driver_nl80211_check_bss_status(drv
, res
);
3613 static void nl80211_dump_scan(struct wpa_driver_nl80211_data
*drv
)
3615 struct wpa_scan_results
*res
;
3618 res
= nl80211_get_scan_results(drv
);
3620 wpa_printf(MSG_DEBUG
, "nl80211: Failed to get scan results");
3624 wpa_printf(MSG_DEBUG
, "nl80211: Scan result dump");
3625 for (i
= 0; i
< res
->num
; i
++) {
3626 struct wpa_scan_res
*r
= res
->res
[i
];
3627 wpa_printf(MSG_DEBUG
, "nl80211: %d/%d " MACSTR
"%s%s",
3628 (int) i
, (int) res
->num
, MAC2STR(r
->bssid
),
3629 r
->flags
& WPA_SCAN_AUTHENTICATED
? " [auth]" : "",
3630 r
->flags
& WPA_SCAN_ASSOCIATED
? " [assoc]" : "");
3633 wpa_scan_results_free(res
);
3637 static int wpa_driver_nl80211_set_key(const char *ifname
, void *priv
,
3638 enum wpa_alg alg
, const u8
*addr
,
3639 int key_idx
, int set_tx
,
3640 const u8
*seq
, size_t seq_len
,
3641 const u8
*key
, size_t key_len
)
3643 struct i802_bss
*bss
= priv
;
3644 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
3645 int ifindex
= if_nametoindex(ifname
);
3649 wpa_printf(MSG_DEBUG
, "%s: ifindex=%d alg=%d addr=%p key_idx=%d "
3650 "set_tx=%d seq_len=%lu key_len=%lu",
3651 __func__
, ifindex
, alg
, addr
, key_idx
, set_tx
,
3652 (unsigned long) seq_len
, (unsigned long) key_len
);
3656 #endif /* CONFIG_TDLS */
3658 msg
= nlmsg_alloc();
3662 if (alg
== WPA_ALG_NONE
) {
3663 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_DEL_KEY
);
3665 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_NEW_KEY
);
3666 NLA_PUT(msg
, NL80211_ATTR_KEY_DATA
, key_len
, key
);
3670 NLA_PUT_U32(msg
, NL80211_ATTR_KEY_CIPHER
,
3671 WLAN_CIPHER_SUITE_WEP40
);
3673 NLA_PUT_U32(msg
, NL80211_ATTR_KEY_CIPHER
,
3674 WLAN_CIPHER_SUITE_WEP104
);
3677 NLA_PUT_U32(msg
, NL80211_ATTR_KEY_CIPHER
,
3678 WLAN_CIPHER_SUITE_TKIP
);
3681 NLA_PUT_U32(msg
, NL80211_ATTR_KEY_CIPHER
,
3682 WLAN_CIPHER_SUITE_CCMP
);
3685 NLA_PUT_U32(msg
, NL80211_ATTR_KEY_CIPHER
,
3686 WLAN_CIPHER_SUITE_AES_CMAC
);
3689 wpa_printf(MSG_ERROR
, "%s: Unsupported encryption "
3690 "algorithm %d", __func__
, alg
);
3697 NLA_PUT(msg
, NL80211_ATTR_KEY_SEQ
, seq_len
, seq
);
3699 if (addr
&& !is_broadcast_ether_addr(addr
)) {
3700 wpa_printf(MSG_DEBUG
, " addr=" MACSTR
, MAC2STR(addr
));
3701 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
3703 if (alg
!= WPA_ALG_WEP
&& key_idx
&& !set_tx
) {
3704 wpa_printf(MSG_DEBUG
, " RSN IBSS RX GTK");
3705 NLA_PUT_U32(msg
, NL80211_ATTR_KEY_TYPE
,
3706 NL80211_KEYTYPE_GROUP
);
3708 } else if (addr
&& is_broadcast_ether_addr(addr
)) {
3709 struct nl_msg
*types
;
3711 wpa_printf(MSG_DEBUG
, " broadcast key");
3712 types
= nlmsg_alloc();
3714 goto nla_put_failure
;
3715 NLA_PUT_FLAG(types
, NL80211_KEY_DEFAULT_TYPE_MULTICAST
);
3716 err
= nla_put_nested(msg
, NL80211_ATTR_KEY_DEFAULT_TYPES
,
3720 goto nla_put_failure
;
3722 NLA_PUT_U8(msg
, NL80211_ATTR_KEY_IDX
, key_idx
);
3723 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, ifindex
);
3725 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
3726 if ((ret
== -ENOENT
|| ret
== -ENOLINK
) && alg
== WPA_ALG_NONE
)
3729 wpa_printf(MSG_DEBUG
, "nl80211: set_key failed; err=%d %s)",
3730 ret
, strerror(-ret
));
3733 * If we failed or don't need to set the default TX key (below),
3736 if (ret
|| !set_tx
|| alg
== WPA_ALG_NONE
)
3738 if (is_ap_interface(drv
->nlmode
) && addr
&&
3739 !is_broadcast_ether_addr(addr
))
3742 msg
= nlmsg_alloc();
3746 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_KEY
);
3747 NLA_PUT_U8(msg
, NL80211_ATTR_KEY_IDX
, key_idx
);
3748 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, ifindex
);
3749 if (alg
== WPA_ALG_IGTK
)
3750 NLA_PUT_FLAG(msg
, NL80211_ATTR_KEY_DEFAULT_MGMT
);
3752 NLA_PUT_FLAG(msg
, NL80211_ATTR_KEY_DEFAULT
);
3753 if (addr
&& is_broadcast_ether_addr(addr
)) {
3754 struct nl_msg
*types
;
3756 types
= nlmsg_alloc();
3758 goto nla_put_failure
;
3759 NLA_PUT_FLAG(types
, NL80211_KEY_DEFAULT_TYPE_MULTICAST
);
3760 err
= nla_put_nested(msg
, NL80211_ATTR_KEY_DEFAULT_TYPES
,
3764 goto nla_put_failure
;
3766 struct nl_msg
*types
;
3768 types
= nlmsg_alloc();
3770 goto nla_put_failure
;
3771 NLA_PUT_FLAG(types
, NL80211_KEY_DEFAULT_TYPE_UNICAST
);
3772 err
= nla_put_nested(msg
, NL80211_ATTR_KEY_DEFAULT_TYPES
,
3776 goto nla_put_failure
;
3779 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
3783 wpa_printf(MSG_DEBUG
, "nl80211: set_key default failed; "
3784 "err=%d %s)", ret
, strerror(-ret
));
3792 static int nl_add_key(struct nl_msg
*msg
, enum wpa_alg alg
,
3793 int key_idx
, int defkey
,
3794 const u8
*seq
, size_t seq_len
,
3795 const u8
*key
, size_t key_len
)
3797 struct nlattr
*key_attr
= nla_nest_start(msg
, NL80211_ATTR_KEY
);
3801 if (defkey
&& alg
== WPA_ALG_IGTK
)
3802 NLA_PUT_FLAG(msg
, NL80211_KEY_DEFAULT_MGMT
);
3804 NLA_PUT_FLAG(msg
, NL80211_KEY_DEFAULT
);
3806 NLA_PUT_U8(msg
, NL80211_KEY_IDX
, key_idx
);
3811 NLA_PUT_U32(msg
, NL80211_KEY_CIPHER
,
3812 WLAN_CIPHER_SUITE_WEP40
);
3814 NLA_PUT_U32(msg
, NL80211_KEY_CIPHER
,
3815 WLAN_CIPHER_SUITE_WEP104
);
3818 NLA_PUT_U32(msg
, NL80211_KEY_CIPHER
, WLAN_CIPHER_SUITE_TKIP
);
3821 NLA_PUT_U32(msg
, NL80211_KEY_CIPHER
, WLAN_CIPHER_SUITE_CCMP
);
3824 NLA_PUT_U32(msg
, NL80211_KEY_CIPHER
,
3825 WLAN_CIPHER_SUITE_AES_CMAC
);
3828 wpa_printf(MSG_ERROR
, "%s: Unsupported encryption "
3829 "algorithm %d", __func__
, alg
);
3834 NLA_PUT(msg
, NL80211_KEY_SEQ
, seq_len
, seq
);
3836 NLA_PUT(msg
, NL80211_KEY_DATA
, key_len
, key
);
3838 nla_nest_end(msg
, key_attr
);
3846 static int nl80211_set_conn_keys(struct wpa_driver_associate_params
*params
,
3850 struct nlattr
*nl_keys
, *nl_key
;
3852 for (i
= 0; i
< 4; i
++) {
3853 if (!params
->wep_key
[i
])
3858 if (params
->wps
== WPS_MODE_PRIVACY
)
3860 if (params
->pairwise_suite
&&
3861 params
->pairwise_suite
!= WPA_CIPHER_NONE
)
3867 NLA_PUT_FLAG(msg
, NL80211_ATTR_PRIVACY
);
3869 nl_keys
= nla_nest_start(msg
, NL80211_ATTR_KEYS
);
3871 goto nla_put_failure
;
3873 for (i
= 0; i
< 4; i
++) {
3874 if (!params
->wep_key
[i
])
3877 nl_key
= nla_nest_start(msg
, i
);
3879 goto nla_put_failure
;
3881 NLA_PUT(msg
, NL80211_KEY_DATA
, params
->wep_key_len
[i
],
3882 params
->wep_key
[i
]);
3883 if (params
->wep_key_len
[i
] == 5)
3884 NLA_PUT_U32(msg
, NL80211_KEY_CIPHER
,
3885 WLAN_CIPHER_SUITE_WEP40
);
3887 NLA_PUT_U32(msg
, NL80211_KEY_CIPHER
,
3888 WLAN_CIPHER_SUITE_WEP104
);
3890 NLA_PUT_U8(msg
, NL80211_KEY_IDX
, i
);
3892 if (i
== params
->wep_tx_keyidx
)
3893 NLA_PUT_FLAG(msg
, NL80211_KEY_DEFAULT
);
3895 nla_nest_end(msg
, nl_key
);
3897 nla_nest_end(msg
, nl_keys
);
3906 static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data
*drv
,
3907 const u8
*addr
, int cmd
, u16 reason_code
,
3908 int local_state_change
)
3913 msg
= nlmsg_alloc();
3917 nl80211_cmd(drv
, msg
, 0, cmd
);
3919 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
3920 NLA_PUT_U16(msg
, NL80211_ATTR_REASON_CODE
, reason_code
);
3921 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
3922 if (local_state_change
)
3923 NLA_PUT_FLAG(msg
, NL80211_ATTR_LOCAL_STATE_CHANGE
);
3925 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
3928 wpa_dbg(drv
->ctx
, MSG_DEBUG
,
3929 "nl80211: MLME command failed: reason=%u ret=%d (%s)",
3930 reason_code
, ret
, strerror(-ret
));
3931 goto nla_put_failure
;
3941 static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data
*drv
,
3942 const u8
*addr
, int reason_code
)
3944 wpa_printf(MSG_DEBUG
, "%s(addr=" MACSTR
" reason_code=%d)",
3945 __func__
, MAC2STR(addr
), reason_code
);
3946 drv
->associated
= 0;
3947 return wpa_driver_nl80211_mlme(drv
, addr
, NL80211_CMD_DISCONNECT
,
3952 static int wpa_driver_nl80211_deauthenticate(void *priv
, const u8
*addr
,
3955 struct i802_bss
*bss
= priv
;
3956 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
3957 if (!(drv
->capa
.flags
& WPA_DRIVER_FLAGS_SME
))
3958 return wpa_driver_nl80211_disconnect(drv
, addr
, reason_code
);
3959 wpa_printf(MSG_DEBUG
, "%s(addr=" MACSTR
" reason_code=%d)",
3960 __func__
, MAC2STR(addr
), reason_code
);
3961 drv
->associated
= 0;
3962 if (drv
->nlmode
== NL80211_IFTYPE_ADHOC
)
3963 return nl80211_leave_ibss(drv
);
3964 return wpa_driver_nl80211_mlme(drv
, addr
, NL80211_CMD_DEAUTHENTICATE
,
3969 static int wpa_driver_nl80211_disassociate(void *priv
, const u8
*addr
,
3972 struct i802_bss
*bss
= priv
;
3973 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
3974 if (!(drv
->capa
.flags
& WPA_DRIVER_FLAGS_SME
))
3975 return wpa_driver_nl80211_disconnect(drv
, addr
, reason_code
);
3976 wpa_printf(MSG_DEBUG
, "%s", __func__
);
3977 drv
->associated
= 0;
3978 return wpa_driver_nl80211_mlme(drv
, addr
, NL80211_CMD_DISASSOCIATE
,
3983 static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data
*drv
,
3984 struct wpa_driver_auth_params
*params
)
3988 drv
->auth_freq
= params
->freq
;
3989 drv
->auth_alg
= params
->auth_alg
;
3990 drv
->auth_wep_tx_keyidx
= params
->wep_tx_keyidx
;
3991 drv
->auth_local_state_change
= params
->local_state_change
;
3992 drv
->auth_p2p
= params
->p2p
;
3995 os_memcpy(drv
->auth_bssid_
, params
->bssid
, ETH_ALEN
);
3997 os_memset(drv
->auth_bssid_
, 0, ETH_ALEN
);
4000 os_memcpy(drv
->auth_ssid
, params
->ssid
, params
->ssid_len
);
4001 drv
->auth_ssid_len
= params
->ssid_len
;
4003 drv
->auth_ssid_len
= 0;
4006 os_free(drv
->auth_ie
);
4007 drv
->auth_ie
= NULL
;
4008 drv
->auth_ie_len
= 0;
4010 drv
->auth_ie
= os_malloc(params
->ie_len
);
4012 os_memcpy(drv
->auth_ie
, params
->ie
, params
->ie_len
);
4013 drv
->auth_ie_len
= params
->ie_len
;
4017 for (i
= 0; i
< 4; i
++) {
4018 if (params
->wep_key
[i
] && params
->wep_key_len
[i
] &&
4019 params
->wep_key_len
[i
] <= 16) {
4020 os_memcpy(drv
->auth_wep_key
[i
], params
->wep_key
[i
],
4021 params
->wep_key_len
[i
]);
4022 drv
->auth_wep_key_len
[i
] = params
->wep_key_len
[i
];
4024 drv
->auth_wep_key_len
[i
] = 0;
4029 static int wpa_driver_nl80211_authenticate(
4030 void *priv
, struct wpa_driver_auth_params
*params
)
4032 struct i802_bss
*bss
= priv
;
4033 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
4036 enum nl80211_auth_type type
;
4037 enum nl80211_iftype nlmode
;
4041 is_retry
= drv
->retry_auth
;
4042 drv
->retry_auth
= 0;
4044 drv
->associated
= 0;
4045 os_memset(drv
->auth_bssid
, 0, ETH_ALEN
);
4046 /* FIX: IBSS mode */
4047 nlmode
= params
->p2p
?
4048 NL80211_IFTYPE_P2P_CLIENT
: NL80211_IFTYPE_STATION
;
4049 if (drv
->nlmode
!= nlmode
&&
4050 wpa_driver_nl80211_set_mode(priv
, nlmode
) < 0)
4054 msg
= nlmsg_alloc();
4058 wpa_printf(MSG_DEBUG
, "nl80211: Authenticate (ifindex=%d)",
4061 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_AUTHENTICATE
);
4063 for (i
= 0; i
< 4; i
++) {
4064 if (!params
->wep_key
[i
])
4066 wpa_driver_nl80211_set_key(bss
->ifname
, priv
, WPA_ALG_WEP
,
4068 i
== params
->wep_tx_keyidx
, NULL
, 0,
4070 params
->wep_key_len
[i
]);
4071 if (params
->wep_tx_keyidx
!= i
)
4073 if (nl_add_key(msg
, WPA_ALG_WEP
, i
, 1, NULL
, 0,
4074 params
->wep_key
[i
], params
->wep_key_len
[i
])) {
4080 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
4081 if (params
->bssid
) {
4082 wpa_printf(MSG_DEBUG
, " * bssid=" MACSTR
,
4083 MAC2STR(params
->bssid
));
4084 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, params
->bssid
);
4087 wpa_printf(MSG_DEBUG
, " * freq=%d", params
->freq
);
4088 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, params
->freq
);
4091 wpa_hexdump_ascii(MSG_DEBUG
, " * SSID",
4092 params
->ssid
, params
->ssid_len
);
4093 NLA_PUT(msg
, NL80211_ATTR_SSID
, params
->ssid_len
,
4096 wpa_hexdump(MSG_DEBUG
, " * IEs", params
->ie
, params
->ie_len
);
4098 NLA_PUT(msg
, NL80211_ATTR_IE
, params
->ie_len
, params
->ie
);
4099 if (params
->auth_alg
& WPA_AUTH_ALG_OPEN
)
4100 type
= NL80211_AUTHTYPE_OPEN_SYSTEM
;
4101 else if (params
->auth_alg
& WPA_AUTH_ALG_SHARED
)
4102 type
= NL80211_AUTHTYPE_SHARED_KEY
;
4103 else if (params
->auth_alg
& WPA_AUTH_ALG_LEAP
)
4104 type
= NL80211_AUTHTYPE_NETWORK_EAP
;
4105 else if (params
->auth_alg
& WPA_AUTH_ALG_FT
)
4106 type
= NL80211_AUTHTYPE_FT
;
4108 goto nla_put_failure
;
4109 wpa_printf(MSG_DEBUG
, " * Auth Type %d", type
);
4110 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
, type
);
4111 if (params
->local_state_change
) {
4112 wpa_printf(MSG_DEBUG
, " * Local state change only");
4113 NLA_PUT_FLAG(msg
, NL80211_ATTR_LOCAL_STATE_CHANGE
);
4116 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
4119 wpa_dbg(drv
->ctx
, MSG_DEBUG
,
4120 "nl80211: MLME command failed (auth): ret=%d (%s)",
4121 ret
, strerror(-ret
));
4123 if (ret
== -EALREADY
&& count
== 1 && params
->bssid
&&
4124 !params
->local_state_change
) {
4126 * mac80211 does not currently accept new
4127 * authentication if we are already authenticated. As a
4128 * workaround, force deauthentication and try again.
4130 wpa_printf(MSG_DEBUG
, "nl80211: Retry authentication "
4131 "after forced deauthentication");
4132 wpa_driver_nl80211_deauthenticate(
4134 WLAN_REASON_PREV_AUTH_NOT_VALID
);
4139 if (ret
== -ENOENT
&& params
->freq
&& !is_retry
) {
4141 * cfg80211 has likely expired the BSS entry even
4142 * though it was previously available in our internal
4143 * BSS table. To recover quickly, start a single
4144 * channel scan on the specified channel.
4146 struct wpa_driver_scan_params scan
;
4149 os_memset(&scan
, 0, sizeof(scan
));
4152 scan
.ssids
[0].ssid
= params
->ssid
;
4153 scan
.ssids
[0].ssid_len
= params
->ssid_len
;
4155 freqs
[0] = params
->freq
;
4158 wpa_printf(MSG_DEBUG
, "nl80211: Trigger single "
4159 "channel scan to refresh cfg80211 BSS "
4161 ret
= wpa_driver_nl80211_scan(bss
, &scan
);
4163 nl80211_copy_auth_params(drv
, params
);
4164 drv
->scan_for_auth
= 1;
4166 } else if (is_retry
) {
4168 * Need to indicate this with an event since the return
4169 * value from the retry is not delivered to core code.
4171 union wpa_event_data event
;
4172 wpa_printf(MSG_DEBUG
, "nl80211: Authentication retry "
4174 os_memset(&event
, 0, sizeof(event
));
4175 os_memcpy(event
.timeout_event
.addr
, drv
->auth_bssid_
,
4177 wpa_supplicant_event(drv
->ctx
, EVENT_AUTH_TIMED_OUT
,
4181 goto nla_put_failure
;
4184 wpa_printf(MSG_DEBUG
, "nl80211: Authentication request send "
4193 static int wpa_driver_nl80211_authenticate_retry(
4194 struct wpa_driver_nl80211_data
*drv
)
4196 struct wpa_driver_auth_params params
;
4197 struct i802_bss
*bss
= &drv
->first_bss
;
4200 wpa_printf(MSG_DEBUG
, "nl80211: Try to authenticate again");
4202 os_memset(¶ms
, 0, sizeof(params
));
4203 params
.freq
= drv
->auth_freq
;
4204 params
.auth_alg
= drv
->auth_alg
;
4205 params
.wep_tx_keyidx
= drv
->auth_wep_tx_keyidx
;
4206 params
.local_state_change
= drv
->auth_local_state_change
;
4207 params
.p2p
= drv
->auth_p2p
;
4209 if (!is_zero_ether_addr(drv
->auth_bssid_
))
4210 params
.bssid
= drv
->auth_bssid_
;
4212 if (drv
->auth_ssid_len
) {
4213 params
.ssid
= drv
->auth_ssid
;
4214 params
.ssid_len
= drv
->auth_ssid_len
;
4217 params
.ie
= drv
->auth_ie
;
4218 params
.ie_len
= drv
->auth_ie_len
;
4220 for (i
= 0; i
< 4; i
++) {
4221 if (drv
->auth_wep_key_len
[i
]) {
4222 params
.wep_key
[i
] = drv
->auth_wep_key
[i
];
4223 params
.wep_key_len
[i
] = drv
->auth_wep_key_len
[i
];
4227 drv
->retry_auth
= 1;
4228 return wpa_driver_nl80211_authenticate(bss
, ¶ms
);
4232 struct phy_info_arg
{
4234 struct hostapd_hw_modes
*modes
;
4237 static int phy_info_handler(struct nl_msg
*msg
, void *arg
)
4239 struct nlattr
*tb_msg
[NL80211_ATTR_MAX
+ 1];
4240 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
4241 struct phy_info_arg
*phy_info
= arg
;
4243 struct nlattr
*tb_band
[NL80211_BAND_ATTR_MAX
+ 1];
4245 struct nlattr
*tb_freq
[NL80211_FREQUENCY_ATTR_MAX
+ 1];
4246 static struct nla_policy freq_policy
[NL80211_FREQUENCY_ATTR_MAX
+ 1] = {
4247 [NL80211_FREQUENCY_ATTR_FREQ
] = { .type
= NLA_U32
},
4248 [NL80211_FREQUENCY_ATTR_DISABLED
] = { .type
= NLA_FLAG
},
4249 [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN
] = { .type
= NLA_FLAG
},
4250 [NL80211_FREQUENCY_ATTR_NO_IBSS
] = { .type
= NLA_FLAG
},
4251 [NL80211_FREQUENCY_ATTR_RADAR
] = { .type
= NLA_FLAG
},
4252 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER
] = { .type
= NLA_U32
},
4255 struct nlattr
*tb_rate
[NL80211_BITRATE_ATTR_MAX
+ 1];
4256 static struct nla_policy rate_policy
[NL80211_BITRATE_ATTR_MAX
+ 1] = {
4257 [NL80211_BITRATE_ATTR_RATE
] = { .type
= NLA_U32
},
4258 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE
] = { .type
= NLA_FLAG
},
4261 struct nlattr
*nl_band
;
4262 struct nlattr
*nl_freq
;
4263 struct nlattr
*nl_rate
;
4264 int rem_band
, rem_freq
, rem_rate
;
4265 struct hostapd_hw_modes
*mode
;
4266 int idx
, mode_is_set
;
4268 nla_parse(tb_msg
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
4269 genlmsg_attrlen(gnlh
, 0), NULL
);
4271 if (!tb_msg
[NL80211_ATTR_WIPHY_BANDS
])
4274 nla_for_each_nested(nl_band
, tb_msg
[NL80211_ATTR_WIPHY_BANDS
], rem_band
) {
4275 mode
= os_realloc(phy_info
->modes
, (*phy_info
->num_modes
+ 1) * sizeof(*mode
));
4278 phy_info
->modes
= mode
;
4282 mode
= &phy_info
->modes
[*(phy_info
->num_modes
)];
4283 memset(mode
, 0, sizeof(*mode
));
4284 mode
->flags
= HOSTAPD_MODE_FLAG_HT_INFO_KNOWN
;
4285 *(phy_info
->num_modes
) += 1;
4287 nla_parse(tb_band
, NL80211_BAND_ATTR_MAX
, nla_data(nl_band
),
4288 nla_len(nl_band
), NULL
);
4290 if (tb_band
[NL80211_BAND_ATTR_HT_CAPA
]) {
4291 mode
->ht_capab
= nla_get_u16(
4292 tb_band
[NL80211_BAND_ATTR_HT_CAPA
]);
4295 if (tb_band
[NL80211_BAND_ATTR_HT_AMPDU_FACTOR
]) {
4296 mode
->a_mpdu_params
|= nla_get_u8(
4297 tb_band
[NL80211_BAND_ATTR_HT_AMPDU_FACTOR
]) &
4301 if (tb_band
[NL80211_BAND_ATTR_HT_AMPDU_DENSITY
]) {
4302 mode
->a_mpdu_params
|= nla_get_u8(
4303 tb_band
[NL80211_BAND_ATTR_HT_AMPDU_DENSITY
]) <<
4307 if (tb_band
[NL80211_BAND_ATTR_HT_MCS_SET
] &&
4308 nla_len(tb_band
[NL80211_BAND_ATTR_HT_MCS_SET
])) {
4310 mcs
= nla_data(tb_band
[NL80211_BAND_ATTR_HT_MCS_SET
]);
4311 os_memcpy(mode
->mcs_set
, mcs
, 16);
4314 nla_for_each_nested(nl_freq
, tb_band
[NL80211_BAND_ATTR_FREQS
], rem_freq
) {
4315 nla_parse(tb_freq
, NL80211_FREQUENCY_ATTR_MAX
, nla_data(nl_freq
),
4316 nla_len(nl_freq
), freq_policy
);
4317 if (!tb_freq
[NL80211_FREQUENCY_ATTR_FREQ
])
4319 mode
->num_channels
++;
4322 mode
->channels
= os_zalloc(mode
->num_channels
* sizeof(struct hostapd_channel_data
));
4323 if (!mode
->channels
)
4328 nla_for_each_nested(nl_freq
, tb_band
[NL80211_BAND_ATTR_FREQS
], rem_freq
) {
4329 nla_parse(tb_freq
, NL80211_FREQUENCY_ATTR_MAX
, nla_data(nl_freq
),
4330 nla_len(nl_freq
), freq_policy
);
4331 if (!tb_freq
[NL80211_FREQUENCY_ATTR_FREQ
])
4334 mode
->channels
[idx
].freq
= nla_get_u32(tb_freq
[NL80211_FREQUENCY_ATTR_FREQ
]);
4335 mode
->channels
[idx
].flag
= 0;
4338 /* crude heuristic */
4339 if (mode
->channels
[idx
].freq
< 4000)
4340 mode
->mode
= HOSTAPD_MODE_IEEE80211B
;
4342 mode
->mode
= HOSTAPD_MODE_IEEE80211A
;
4346 /* crude heuristic */
4347 if (mode
->channels
[idx
].freq
< 4000)
4348 if (mode
->channels
[idx
].freq
== 2484)
4349 mode
->channels
[idx
].chan
= 14;
4351 mode
->channels
[idx
].chan
= (mode
->channels
[idx
].freq
- 2407) / 5;
4353 mode
->channels
[idx
].chan
= mode
->channels
[idx
].freq
/5 - 1000;
4355 if (tb_freq
[NL80211_FREQUENCY_ATTR_DISABLED
])
4356 mode
->channels
[idx
].flag
|=
4357 HOSTAPD_CHAN_DISABLED
;
4358 if (tb_freq
[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN
])
4359 mode
->channels
[idx
].flag
|=
4360 HOSTAPD_CHAN_PASSIVE_SCAN
;
4361 if (tb_freq
[NL80211_FREQUENCY_ATTR_NO_IBSS
])
4362 mode
->channels
[idx
].flag
|=
4363 HOSTAPD_CHAN_NO_IBSS
;
4364 if (tb_freq
[NL80211_FREQUENCY_ATTR_RADAR
])
4365 mode
->channels
[idx
].flag
|=
4368 if (tb_freq
[NL80211_FREQUENCY_ATTR_MAX_TX_POWER
] &&
4369 !tb_freq
[NL80211_FREQUENCY_ATTR_DISABLED
])
4370 mode
->channels
[idx
].max_tx_power
=
4371 nla_get_u32(tb_freq
[NL80211_FREQUENCY_ATTR_MAX_TX_POWER
]) / 100;
4376 nla_for_each_nested(nl_rate
, tb_band
[NL80211_BAND_ATTR_RATES
], rem_rate
) {
4377 nla_parse(tb_rate
, NL80211_BITRATE_ATTR_MAX
, nla_data(nl_rate
),
4378 nla_len(nl_rate
), rate_policy
);
4379 if (!tb_rate
[NL80211_BITRATE_ATTR_RATE
])
4384 mode
->rates
= os_zalloc(mode
->num_rates
* sizeof(int));
4390 nla_for_each_nested(nl_rate
, tb_band
[NL80211_BAND_ATTR_RATES
], rem_rate
) {
4391 nla_parse(tb_rate
, NL80211_BITRATE_ATTR_MAX
, nla_data(nl_rate
),
4392 nla_len(nl_rate
), rate_policy
);
4393 if (!tb_rate
[NL80211_BITRATE_ATTR_RATE
])
4395 mode
->rates
[idx
] = nla_get_u32(tb_rate
[NL80211_BITRATE_ATTR_RATE
]);
4397 /* crude heuristic */
4398 if (mode
->mode
== HOSTAPD_MODE_IEEE80211B
&&
4399 mode
->rates
[idx
] > 200)
4400 mode
->mode
= HOSTAPD_MODE_IEEE80211G
;
4409 static struct hostapd_hw_modes
*
4410 wpa_driver_nl80211_add_11b(struct hostapd_hw_modes
*modes
, u16
*num_modes
)
4413 struct hostapd_hw_modes
*mode11g
= NULL
, *nmodes
, *mode
;
4414 int i
, mode11g_idx
= -1;
4416 /* If only 802.11g mode is included, use it to construct matching
4417 * 802.11b mode data. */
4419 for (m
= 0; m
< *num_modes
; m
++) {
4420 if (modes
[m
].mode
== HOSTAPD_MODE_IEEE80211B
)
4421 return modes
; /* 802.11b already included */
4422 if (modes
[m
].mode
== HOSTAPD_MODE_IEEE80211G
)
4426 if (mode11g_idx
< 0)
4427 return modes
; /* 2.4 GHz band not supported at all */
4429 nmodes
= os_realloc(modes
, (*num_modes
+ 1) * sizeof(*nmodes
));
4431 return modes
; /* Could not add 802.11b mode */
4433 mode
= &nmodes
[*num_modes
];
4434 os_memset(mode
, 0, sizeof(*mode
));
4438 mode
->mode
= HOSTAPD_MODE_IEEE80211B
;
4440 mode11g
= &modes
[mode11g_idx
];
4441 mode
->num_channels
= mode11g
->num_channels
;
4442 mode
->channels
= os_malloc(mode11g
->num_channels
*
4443 sizeof(struct hostapd_channel_data
));
4444 if (mode
->channels
== NULL
) {
4446 return modes
; /* Could not add 802.11b mode */
4448 os_memcpy(mode
->channels
, mode11g
->channels
,
4449 mode11g
->num_channels
* sizeof(struct hostapd_channel_data
));
4451 mode
->num_rates
= 0;
4452 mode
->rates
= os_malloc(4 * sizeof(int));
4453 if (mode
->rates
== NULL
) {
4454 os_free(mode
->channels
);
4456 return modes
; /* Could not add 802.11b mode */
4459 for (i
= 0; i
< mode11g
->num_rates
; i
++) {
4460 if (mode11g
->rates
[i
] != 10 && mode11g
->rates
[i
] != 20 &&
4461 mode11g
->rates
[i
] != 55 && mode11g
->rates
[i
] != 110)
4463 mode
->rates
[mode
->num_rates
] = mode11g
->rates
[i
];
4465 if (mode
->num_rates
== 4)
4469 if (mode
->num_rates
== 0) {
4470 os_free(mode
->channels
);
4471 os_free(mode
->rates
);
4473 return modes
; /* No 802.11b rates */
4476 wpa_printf(MSG_DEBUG
, "nl80211: Added 802.11b mode based on 802.11g "
4483 static void nl80211_set_ht40_mode(struct hostapd_hw_modes
*mode
, int start
,
4488 for (c
= 0; c
< mode
->num_channels
; c
++) {
4489 struct hostapd_channel_data
*chan
= &mode
->channels
[c
];
4490 if (chan
->freq
- 10 >= start
&& chan
->freq
+ 10 <= end
)
4491 chan
->flag
|= HOSTAPD_CHAN_HT40
;
4496 static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes
*mode
, int start
,
4501 for (c
= 0; c
< mode
->num_channels
; c
++) {
4502 struct hostapd_channel_data
*chan
= &mode
->channels
[c
];
4503 if (!(chan
->flag
& HOSTAPD_CHAN_HT40
))
4505 if (chan
->freq
- 30 >= start
&& chan
->freq
- 10 <= end
)
4506 chan
->flag
|= HOSTAPD_CHAN_HT40MINUS
;
4507 if (chan
->freq
+ 10 >= start
&& chan
->freq
+ 30 <= end
)
4508 chan
->flag
|= HOSTAPD_CHAN_HT40PLUS
;
4513 static void nl80211_reg_rule_ht40(struct nlattr
*tb
[],
4514 struct phy_info_arg
*results
)
4516 u32 start
, end
, max_bw
;
4519 if (tb
[NL80211_ATTR_FREQ_RANGE_START
] == NULL
||
4520 tb
[NL80211_ATTR_FREQ_RANGE_END
] == NULL
||
4521 tb
[NL80211_ATTR_FREQ_RANGE_MAX_BW
] == NULL
)
4524 start
= nla_get_u32(tb
[NL80211_ATTR_FREQ_RANGE_START
]) / 1000;
4525 end
= nla_get_u32(tb
[NL80211_ATTR_FREQ_RANGE_END
]) / 1000;
4526 max_bw
= nla_get_u32(tb
[NL80211_ATTR_FREQ_RANGE_MAX_BW
]) / 1000;
4528 wpa_printf(MSG_DEBUG
, "nl80211: %u-%u @ %u MHz",
4529 start
, end
, max_bw
);
4533 for (m
= 0; m
< *results
->num_modes
; m
++) {
4534 if (!(results
->modes
[m
].ht_capab
&
4535 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
))
4537 nl80211_set_ht40_mode(&results
->modes
[m
], start
, end
);
4542 static void nl80211_reg_rule_sec(struct nlattr
*tb
[],
4543 struct phy_info_arg
*results
)
4545 u32 start
, end
, max_bw
;
4548 if (tb
[NL80211_ATTR_FREQ_RANGE_START
] == NULL
||
4549 tb
[NL80211_ATTR_FREQ_RANGE_END
] == NULL
||
4550 tb
[NL80211_ATTR_FREQ_RANGE_MAX_BW
] == NULL
)
4553 start
= nla_get_u32(tb
[NL80211_ATTR_FREQ_RANGE_START
]) / 1000;
4554 end
= nla_get_u32(tb
[NL80211_ATTR_FREQ_RANGE_END
]) / 1000;
4555 max_bw
= nla_get_u32(tb
[NL80211_ATTR_FREQ_RANGE_MAX_BW
]) / 1000;
4560 for (m
= 0; m
< *results
->num_modes
; m
++) {
4561 if (!(results
->modes
[m
].ht_capab
&
4562 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
))
4564 nl80211_set_ht40_mode_sec(&results
->modes
[m
], start
, end
);
4569 static int nl80211_get_reg(struct nl_msg
*msg
, void *arg
)
4571 struct phy_info_arg
*results
= arg
;
4572 struct nlattr
*tb_msg
[NL80211_ATTR_MAX
+ 1];
4573 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
4574 struct nlattr
*nl_rule
;
4575 struct nlattr
*tb_rule
[NL80211_FREQUENCY_ATTR_MAX
+ 1];
4577 static struct nla_policy reg_policy
[NL80211_FREQUENCY_ATTR_MAX
+ 1] = {
4578 [NL80211_ATTR_REG_RULE_FLAGS
] = { .type
= NLA_U32
},
4579 [NL80211_ATTR_FREQ_RANGE_START
] = { .type
= NLA_U32
},
4580 [NL80211_ATTR_FREQ_RANGE_END
] = { .type
= NLA_U32
},
4581 [NL80211_ATTR_FREQ_RANGE_MAX_BW
] = { .type
= NLA_U32
},
4582 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN
] = { .type
= NLA_U32
},
4583 [NL80211_ATTR_POWER_RULE_MAX_EIRP
] = { .type
= NLA_U32
},
4586 nla_parse(tb_msg
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
4587 genlmsg_attrlen(gnlh
, 0), NULL
);
4588 if (!tb_msg
[NL80211_ATTR_REG_ALPHA2
] ||
4589 !tb_msg
[NL80211_ATTR_REG_RULES
]) {
4590 wpa_printf(MSG_DEBUG
, "nl80211: No regulatory information "
4595 wpa_printf(MSG_DEBUG
, "nl80211: Regulatory information - country=%s",
4596 (char *) nla_data(tb_msg
[NL80211_ATTR_REG_ALPHA2
]));
4598 nla_for_each_nested(nl_rule
, tb_msg
[NL80211_ATTR_REG_RULES
], rem_rule
)
4600 nla_parse(tb_rule
, NL80211_FREQUENCY_ATTR_MAX
,
4601 nla_data(nl_rule
), nla_len(nl_rule
), reg_policy
);
4602 nl80211_reg_rule_ht40(tb_rule
, results
);
4605 nla_for_each_nested(nl_rule
, tb_msg
[NL80211_ATTR_REG_RULES
], rem_rule
)
4607 nla_parse(tb_rule
, NL80211_FREQUENCY_ATTR_MAX
,
4608 nla_data(nl_rule
), nla_len(nl_rule
), reg_policy
);
4609 nl80211_reg_rule_sec(tb_rule
, results
);
4616 static int nl80211_set_ht40_flags(struct wpa_driver_nl80211_data
*drv
,
4617 struct phy_info_arg
*results
)
4621 msg
= nlmsg_alloc();
4625 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_GET_REG
);
4626 return send_and_recv_msgs(drv
, msg
, nl80211_get_reg
, results
);
4630 static struct hostapd_hw_modes
*
4631 wpa_driver_nl80211_get_hw_feature_data(void *priv
, u16
*num_modes
, u16
*flags
)
4633 struct i802_bss
*bss
= priv
;
4634 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
4636 struct phy_info_arg result
= {
4637 .num_modes
= num_modes
,
4644 msg
= nlmsg_alloc();
4648 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_GET_WIPHY
);
4650 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
4652 if (send_and_recv_msgs(drv
, msg
, phy_info_handler
, &result
) == 0) {
4653 nl80211_set_ht40_flags(drv
, &result
);
4654 return wpa_driver_nl80211_add_11b(result
.modes
, num_modes
);
4661 static int wpa_driver_nl80211_send_mntr(struct wpa_driver_nl80211_data
*drv
,
4662 const void *data
, size_t len
,
4663 int encrypt
, int noack
)
4666 0x00, 0x00, /* radiotap version */
4667 0x0e, 0x00, /* radiotap length */
4668 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
4669 IEEE80211_RADIOTAP_F_FRAG
, /* F_FRAG (fragment if required) */
4671 0x00, 0x00, /* RX and TX flags to indicate that */
4672 0x00, 0x00, /* this is the injected frame directly */
4674 struct iovec iov
[2] = {
4676 .iov_base
= &rtap_hdr
,
4677 .iov_len
= sizeof(rtap_hdr
),
4680 .iov_base
= (void *) data
,
4684 struct msghdr msg
= {
4689 .msg_control
= NULL
,
4690 .msg_controllen
= 0,
4697 rtap_hdr
[8] |= IEEE80211_RADIOTAP_F_WEP
;
4699 if (drv
->monitor_sock
< 0) {
4700 wpa_printf(MSG_DEBUG
, "nl80211: No monitor socket available "
4701 "for %s", __func__
);
4706 txflags
|= IEEE80211_RADIOTAP_F_TX_NOACK
;
4707 *(le16
*) &rtap_hdr
[12] = host_to_le16(txflags
);
4709 res
= sendmsg(drv
->monitor_sock
, &msg
, 0);
4711 wpa_printf(MSG_INFO
, "nl80211: sendmsg: %s", strerror(errno
));
4718 static int wpa_driver_nl80211_send_frame(struct i802_bss
*bss
,
4719 const void *data
, size_t len
,
4720 int encrypt
, int noack
)
4722 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
4725 if (drv
->use_monitor
)
4726 return wpa_driver_nl80211_send_mntr(drv
, data
, len
,
4729 return nl80211_send_frame_cmd(bss
, bss
->freq
, 0, data
, len
,
4730 &cookie
, 0, noack
, 0);
4734 static int wpa_driver_nl80211_send_mlme(void *priv
, const u8
*data
,
4735 size_t data_len
, int noack
)
4737 struct i802_bss
*bss
= priv
;
4738 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
4739 struct ieee80211_mgmt
*mgmt
;
4743 mgmt
= (struct ieee80211_mgmt
*) data
;
4744 fc
= le_to_host16(mgmt
->frame_control
);
4746 if (is_sta_interface(drv
->nlmode
) &&
4747 WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
&&
4748 WLAN_FC_GET_STYPE(fc
) == WLAN_FC_STYPE_PROBE_RESP
) {
4750 * The use of last_mgmt_freq is a bit of a hack,
4751 * but it works due to the single-threaded nature
4752 * of wpa_supplicant.
4754 return nl80211_send_frame_cmd(bss
, drv
->last_mgmt_freq
, 0,
4755 data
, data_len
, NULL
, 1, noack
,
4759 if (drv
->device_ap_sme
&& is_ap_interface(drv
->nlmode
)) {
4760 return nl80211_send_frame_cmd(bss
, bss
->freq
, 0,
4761 data
, data_len
, NULL
,
4765 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
&&
4766 WLAN_FC_GET_STYPE(fc
) == WLAN_FC_STYPE_AUTH
) {
4768 * Only one of the authentication frame types is encrypted.
4769 * In order for static WEP encryption to work properly (i.e.,
4770 * to not encrypt the frame), we need to tell mac80211 about
4771 * the frames that must not be encrypted.
4773 u16 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4774 u16 auth_trans
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4775 if (auth_alg
!= WLAN_AUTH_SHARED_KEY
|| auth_trans
!= 3)
4779 return wpa_driver_nl80211_send_frame(bss
, data
, data_len
, encrypt
,
4784 static int nl80211_set_bss(struct i802_bss
*bss
, int cts
, int preamble
,
4785 int slot
, int ht_opmode
, int ap_isolate
,
4788 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
4791 msg
= nlmsg_alloc();
4795 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_BSS
);
4798 NLA_PUT_U8(msg
, NL80211_ATTR_BSS_CTS_PROT
, cts
);
4800 NLA_PUT_U8(msg
, NL80211_ATTR_BSS_SHORT_PREAMBLE
, preamble
);
4802 NLA_PUT_U8(msg
, NL80211_ATTR_BSS_SHORT_SLOT_TIME
, slot
);
4804 NLA_PUT_U16(msg
, NL80211_ATTR_BSS_HT_OPMODE
, ht_opmode
);
4805 if (ap_isolate
>= 0)
4806 NLA_PUT_U8(msg
, NL80211_ATTR_AP_ISOLATE
, ap_isolate
);
4809 u8 rates
[NL80211_MAX_SUPP_RATES
];
4813 for (i
= 0; i
< NL80211_MAX_SUPP_RATES
&& basic_rates
[i
] >= 0;
4815 rates
[rates_len
++] = basic_rates
[i
] / 5;
4817 NLA_PUT(msg
, NL80211_ATTR_BSS_BASIC_RATES
, rates_len
, rates
);
4820 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, if_nametoindex(bss
->ifname
));
4822 return send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
4828 static int wpa_driver_nl80211_set_ap(void *priv
,
4829 struct wpa_driver_ap_params
*params
)
4831 struct i802_bss
*bss
= priv
;
4832 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
4834 u8 cmd
= NL80211_CMD_NEW_BEACON
;
4837 int ifindex
= if_nametoindex(bss
->ifname
);
4842 beacon_set
= bss
->beacon_set
;
4844 msg
= nlmsg_alloc();
4848 wpa_printf(MSG_DEBUG
, "nl80211: Set beacon (beacon_set=%d)",
4851 cmd
= NL80211_CMD_SET_BEACON
;
4853 nl80211_cmd(drv
, msg
, 0, cmd
);
4854 NLA_PUT(msg
, NL80211_ATTR_BEACON_HEAD
, params
->head_len
, params
->head
);
4855 NLA_PUT(msg
, NL80211_ATTR_BEACON_TAIL
, params
->tail_len
, params
->tail
);
4856 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, ifindex
);
4857 NLA_PUT_U32(msg
, NL80211_ATTR_BEACON_INTERVAL
, params
->beacon_int
);
4858 NLA_PUT_U32(msg
, NL80211_ATTR_DTIM_PERIOD
, params
->dtim_period
);
4859 NLA_PUT(msg
, NL80211_ATTR_SSID
, params
->ssid_len
,
4861 switch (params
->hide_ssid
) {
4862 case NO_SSID_HIDING
:
4863 NLA_PUT_U32(msg
, NL80211_ATTR_HIDDEN_SSID
,
4864 NL80211_HIDDEN_SSID_NOT_IN_USE
);
4866 case HIDDEN_SSID_ZERO_LEN
:
4867 NLA_PUT_U32(msg
, NL80211_ATTR_HIDDEN_SSID
,
4868 NL80211_HIDDEN_SSID_ZERO_LEN
);
4870 case HIDDEN_SSID_ZERO_CONTENTS
:
4871 NLA_PUT_U32(msg
, NL80211_ATTR_HIDDEN_SSID
,
4872 NL80211_HIDDEN_SSID_ZERO_CONTENTS
);
4875 if (params
->privacy
)
4876 NLA_PUT_FLAG(msg
, NL80211_ATTR_PRIVACY
);
4877 if ((params
->auth_algs
& (WPA_AUTH_ALG_OPEN
| WPA_AUTH_ALG_SHARED
)) ==
4878 (WPA_AUTH_ALG_OPEN
| WPA_AUTH_ALG_SHARED
)) {
4879 /* Leave out the attribute */
4880 } else if (params
->auth_algs
& WPA_AUTH_ALG_SHARED
)
4881 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
,
4882 NL80211_AUTHTYPE_SHARED_KEY
);
4884 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
,
4885 NL80211_AUTHTYPE_OPEN_SYSTEM
);
4888 if (params
->wpa_version
& WPA_PROTO_WPA
)
4889 ver
|= NL80211_WPA_VERSION_1
;
4890 if (params
->wpa_version
& WPA_PROTO_RSN
)
4891 ver
|= NL80211_WPA_VERSION_2
;
4893 NLA_PUT_U32(msg
, NL80211_ATTR_WPA_VERSIONS
, ver
);
4896 if (params
->key_mgmt_suites
& WPA_KEY_MGMT_IEEE8021X
)
4897 suites
[num_suites
++] = WLAN_AKM_SUITE_8021X
;
4898 if (params
->key_mgmt_suites
& WPA_KEY_MGMT_PSK
)
4899 suites
[num_suites
++] = WLAN_AKM_SUITE_PSK
;
4901 NLA_PUT(msg
, NL80211_ATTR_AKM_SUITES
,
4902 num_suites
* sizeof(u32
), suites
);
4905 if (params
->key_mgmt_suites
& WPA_KEY_MGMT_IEEE8021X
&&
4906 params
->pairwise_ciphers
& (WPA_CIPHER_WEP104
| WPA_CIPHER_WEP40
))
4907 NLA_PUT_FLAG(msg
, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT
);
4910 if (params
->pairwise_ciphers
& WPA_CIPHER_CCMP
)
4911 suites
[num_suites
++] = WLAN_CIPHER_SUITE_CCMP
;
4912 if (params
->pairwise_ciphers
& WPA_CIPHER_TKIP
)
4913 suites
[num_suites
++] = WLAN_CIPHER_SUITE_TKIP
;
4914 if (params
->pairwise_ciphers
& WPA_CIPHER_WEP104
)
4915 suites
[num_suites
++] = WLAN_CIPHER_SUITE_WEP104
;
4916 if (params
->pairwise_ciphers
& WPA_CIPHER_WEP40
)
4917 suites
[num_suites
++] = WLAN_CIPHER_SUITE_WEP40
;
4919 NLA_PUT(msg
, NL80211_ATTR_CIPHER_SUITES_PAIRWISE
,
4920 num_suites
* sizeof(u32
), suites
);
4923 switch (params
->group_cipher
) {
4924 case WPA_CIPHER_CCMP
:
4925 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITE_GROUP
,
4926 WLAN_CIPHER_SUITE_CCMP
);
4928 case WPA_CIPHER_TKIP
:
4929 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITE_GROUP
,
4930 WLAN_CIPHER_SUITE_TKIP
);
4932 case WPA_CIPHER_WEP104
:
4933 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITE_GROUP
,
4934 WLAN_CIPHER_SUITE_WEP104
);
4936 case WPA_CIPHER_WEP40
:
4937 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITE_GROUP
,
4938 WLAN_CIPHER_SUITE_WEP40
);
4942 if (params
->beacon_ies
) {
4943 NLA_PUT(msg
, NL80211_ATTR_IE
, wpabuf_len(params
->beacon_ies
),
4944 wpabuf_head(params
->beacon_ies
));
4946 if (params
->proberesp_ies
) {
4947 NLA_PUT(msg
, NL80211_ATTR_IE_PROBE_RESP
,
4948 wpabuf_len(params
->proberesp_ies
),
4949 wpabuf_head(params
->proberesp_ies
));
4951 if (params
->assocresp_ies
) {
4952 NLA_PUT(msg
, NL80211_ATTR_IE_ASSOC_RESP
,
4953 wpabuf_len(params
->assocresp_ies
),
4954 wpabuf_head(params
->assocresp_ies
));
4957 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
4959 wpa_printf(MSG_DEBUG
, "nl80211: Beacon set failed: %d (%s)",
4960 ret
, strerror(-ret
));
4962 bss
->beacon_set
= 1;
4963 nl80211_set_bss(bss
, params
->cts_protect
, params
->preamble
,
4964 params
->short_slot_time
, params
->ht_opmode
,
4965 params
->isolate
, params
->basic_rates
);
4973 static int wpa_driver_nl80211_set_freq(struct i802_bss
*bss
,
4974 int freq
, int ht_enabled
,
4975 int sec_channel_offset
)
4977 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
4981 wpa_printf(MSG_DEBUG
, "nl80211: Set freq %d (ht_enabled=%d "
4982 "sec_channel_offset=%d)",
4983 freq
, ht_enabled
, sec_channel_offset
);
4984 msg
= nlmsg_alloc();
4988 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_WIPHY
);
4990 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
4991 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
4993 switch (sec_channel_offset
) {
4995 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_CHANNEL_TYPE
,
4996 NL80211_CHAN_HT40MINUS
);
4999 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_CHANNEL_TYPE
,
5000 NL80211_CHAN_HT40PLUS
);
5003 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_CHANNEL_TYPE
,
5009 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
5014 wpa_printf(MSG_DEBUG
, "nl80211: Failed to set channel (freq=%d): "
5015 "%d (%s)", freq
, ret
, strerror(-ret
));
5021 static u32
sta_flags_nl80211(int flags
)
5025 if (flags
& WPA_STA_AUTHORIZED
)
5026 f
|= BIT(NL80211_STA_FLAG_AUTHORIZED
);
5027 if (flags
& WPA_STA_WMM
)
5028 f
|= BIT(NL80211_STA_FLAG_WME
);
5029 if (flags
& WPA_STA_SHORT_PREAMBLE
)
5030 f
|= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE
);
5031 if (flags
& WPA_STA_MFP
)
5032 f
|= BIT(NL80211_STA_FLAG_MFP
);
5033 if (flags
& WPA_STA_TDLS_PEER
)
5034 f
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
5040 static int wpa_driver_nl80211_sta_add(void *priv
,
5041 struct hostapd_sta_add_params
*params
)
5043 struct i802_bss
*bss
= priv
;
5044 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
5046 struct nl80211_sta_flag_update upd
;
5049 if ((params
->flags
& WPA_STA_TDLS_PEER
) &&
5050 !(drv
->capa
.flags
& WPA_DRIVER_FLAGS_TDLS_SUPPORT
))
5053 msg
= nlmsg_alloc();
5057 nl80211_cmd(drv
, msg
, 0, params
->set
? NL80211_CMD_SET_STATION
:
5058 NL80211_CMD_NEW_STATION
);
5060 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, if_nametoindex(bss
->ifname
));
5061 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, params
->addr
);
5062 NLA_PUT(msg
, NL80211_ATTR_STA_SUPPORTED_RATES
, params
->supp_rates_len
,
5063 params
->supp_rates
);
5065 NLA_PUT_U16(msg
, NL80211_ATTR_STA_AID
, params
->aid
);
5066 NLA_PUT_U16(msg
, NL80211_ATTR_STA_LISTEN_INTERVAL
,
5067 params
->listen_interval
);
5069 if (params
->ht_capabilities
) {
5070 NLA_PUT(msg
, NL80211_ATTR_HT_CAPABILITY
,
5071 sizeof(*params
->ht_capabilities
),
5072 params
->ht_capabilities
);
5075 os_memset(&upd
, 0, sizeof(upd
));
5076 upd
.mask
= sta_flags_nl80211(params
->flags
);
5078 NLA_PUT(msg
, NL80211_ATTR_STA_FLAGS2
, sizeof(upd
), &upd
);
5080 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
5082 wpa_printf(MSG_DEBUG
, "nl80211: NL80211_CMD_%s_STATION "
5083 "result: %d (%s)", params
->set
? "SET" : "NEW", ret
,
5092 static int wpa_driver_nl80211_sta_remove(void *priv
, const u8
*addr
)
5094 struct i802_bss
*bss
= priv
;
5095 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
5099 msg
= nlmsg_alloc();
5103 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_DEL_STATION
);
5105 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
,
5106 if_nametoindex(bss
->ifname
));
5107 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
5109 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
5118 static void nl80211_remove_iface(struct wpa_driver_nl80211_data
*drv
,
5123 wpa_printf(MSG_DEBUG
, "nl80211: Remove interface ifindex=%d", ifidx
);
5125 /* stop listening for EAPOL on this interface */
5126 del_ifidx(drv
, ifidx
);
5128 msg
= nlmsg_alloc();
5130 goto nla_put_failure
;
5132 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_DEL_INTERFACE
);
5133 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, ifidx
);
5135 if (send_and_recv_msgs(drv
, msg
, NULL
, NULL
) == 0)
5138 wpa_printf(MSG_ERROR
, "Failed to remove interface (ifidx=%d)", ifidx
);
5142 static const char * nl80211_iftype_str(enum nl80211_iftype mode
)
5145 case NL80211_IFTYPE_ADHOC
:
5147 case NL80211_IFTYPE_STATION
:
5149 case NL80211_IFTYPE_AP
:
5151 case NL80211_IFTYPE_MONITOR
:
5153 case NL80211_IFTYPE_P2P_CLIENT
:
5154 return "P2P_CLIENT";
5155 case NL80211_IFTYPE_P2P_GO
:
5163 static int nl80211_create_iface_once(struct wpa_driver_nl80211_data
*drv
,
5165 enum nl80211_iftype iftype
,
5166 const u8
*addr
, int wds
)
5168 struct nl_msg
*msg
, *flags
= NULL
;
5172 wpa_printf(MSG_DEBUG
, "nl80211: Create interface iftype %d (%s)",
5173 iftype
, nl80211_iftype_str(iftype
));
5175 msg
= nlmsg_alloc();
5179 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_NEW_INTERFACE
);
5180 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
5181 NLA_PUT_STRING(msg
, NL80211_ATTR_IFNAME
, ifname
);
5182 NLA_PUT_U32(msg
, NL80211_ATTR_IFTYPE
, iftype
);
5184 if (iftype
== NL80211_IFTYPE_MONITOR
) {
5187 flags
= nlmsg_alloc();
5189 goto nla_put_failure
;
5191 NLA_PUT_FLAG(flags
, NL80211_MNTR_FLAG_COOK_FRAMES
);
5193 err
= nla_put_nested(msg
, NL80211_ATTR_MNTR_FLAGS
, flags
);
5198 goto nla_put_failure
;
5200 NLA_PUT_U8(msg
, NL80211_ATTR_4ADDR
, wds
);
5203 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
5206 wpa_printf(MSG_ERROR
, "Failed to create interface %s: %d (%s)",
5207 ifname
, ret
, strerror(-ret
));
5211 ifidx
= if_nametoindex(ifname
);
5212 wpa_printf(MSG_DEBUG
, "nl80211: New interface %s created: ifindex=%d",
5218 /* start listening for EAPOL on this interface */
5219 add_ifidx(drv
, ifidx
);
5221 if (addr
&& iftype
!= NL80211_IFTYPE_MONITOR
&&
5222 linux_set_ifhwaddr(drv
->global
->ioctl_sock
, ifname
, addr
)) {
5223 nl80211_remove_iface(drv
, ifidx
);
5231 static int nl80211_create_iface(struct wpa_driver_nl80211_data
*drv
,
5232 const char *ifname
, enum nl80211_iftype iftype
,
5233 const u8
*addr
, int wds
)
5237 ret
= nl80211_create_iface_once(drv
, ifname
, iftype
, addr
, wds
);
5239 /* if error occurred and interface exists already */
5240 if (ret
== -ENFILE
&& if_nametoindex(ifname
)) {
5241 wpa_printf(MSG_INFO
, "Try to remove and re-create %s", ifname
);
5243 /* Try to remove the interface that was already there. */
5244 nl80211_remove_iface(drv
, if_nametoindex(ifname
));
5246 /* Try to create the interface again */
5247 ret
= nl80211_create_iface_once(drv
, ifname
, iftype
, addr
,
5251 if (ret
>= 0 && is_p2p_interface(iftype
))
5252 nl80211_disable_11b_rates(drv
, ret
, 1);
5258 static void handle_tx_callback(void *ctx
, u8
*buf
, size_t len
, int ok
)
5260 struct ieee80211_hdr
*hdr
;
5262 union wpa_event_data event
;
5264 hdr
= (struct ieee80211_hdr
*) buf
;
5265 fc
= le_to_host16(hdr
->frame_control
);
5267 os_memset(&event
, 0, sizeof(event
));
5268 event
.tx_status
.type
= WLAN_FC_GET_TYPE(fc
);
5269 event
.tx_status
.stype
= WLAN_FC_GET_STYPE(fc
);
5270 event
.tx_status
.dst
= hdr
->addr1
;
5271 event
.tx_status
.data
= buf
;
5272 event
.tx_status
.data_len
= len
;
5273 event
.tx_status
.ack
= ok
;
5274 wpa_supplicant_event(ctx
, EVENT_TX_STATUS
, &event
);
5278 static void from_unknown_sta(struct wpa_driver_nl80211_data
*drv
,
5279 u8
*buf
, size_t len
)
5281 struct ieee80211_hdr
*hdr
= (void *)buf
;
5283 union wpa_event_data event
;
5285 if (len
< sizeof(*hdr
))
5288 fc
= le_to_host16(hdr
->frame_control
);
5290 os_memset(&event
, 0, sizeof(event
));
5291 event
.rx_from_unknown
.bssid
= get_hdr_bssid(hdr
, len
);
5292 event
.rx_from_unknown
.addr
= hdr
->addr2
;
5293 event
.rx_from_unknown
.wds
= (fc
& (WLAN_FC_FROMDS
| WLAN_FC_TODS
)) ==
5294 (WLAN_FC_FROMDS
| WLAN_FC_TODS
);
5295 wpa_supplicant_event(drv
->ctx
, EVENT_RX_FROM_UNKNOWN
, &event
);
5299 static void handle_frame(struct wpa_driver_nl80211_data
*drv
,
5300 u8
*buf
, size_t len
, int datarate
, int ssi_signal
)
5302 struct ieee80211_hdr
*hdr
;
5304 union wpa_event_data event
;
5306 hdr
= (struct ieee80211_hdr
*) buf
;
5307 fc
= le_to_host16(hdr
->frame_control
);
5309 switch (WLAN_FC_GET_TYPE(fc
)) {
5310 case WLAN_FC_TYPE_MGMT
:
5311 os_memset(&event
, 0, sizeof(event
));
5312 event
.rx_mgmt
.frame
= buf
;
5313 event
.rx_mgmt
.frame_len
= len
;
5314 event
.rx_mgmt
.datarate
= datarate
;
5315 event
.rx_mgmt
.ssi_signal
= ssi_signal
;
5316 wpa_supplicant_event(drv
->ctx
, EVENT_RX_MGMT
, &event
);
5318 case WLAN_FC_TYPE_CTRL
:
5319 /* can only get here with PS-Poll frames */
5320 wpa_printf(MSG_DEBUG
, "CTRL");
5321 from_unknown_sta(drv
, buf
, len
);
5323 case WLAN_FC_TYPE_DATA
:
5324 from_unknown_sta(drv
, buf
, len
);
5330 static void handle_monitor_read(int sock
, void *eloop_ctx
, void *sock_ctx
)
5332 struct wpa_driver_nl80211_data
*drv
= eloop_ctx
;
5334 unsigned char buf
[3000];
5335 struct ieee80211_radiotap_iterator iter
;
5337 int datarate
= 0, ssi_signal
= 0;
5338 int injected
= 0, failed
= 0, rxflags
= 0;
5340 len
= recv(sock
, buf
, sizeof(buf
), 0);
5346 if (ieee80211_radiotap_iterator_init(&iter
, (void*)buf
, len
)) {
5347 printf("received invalid radiotap frame\n");
5352 ret
= ieee80211_radiotap_iterator_next(&iter
);
5356 printf("received invalid radiotap frame (%d)\n", ret
);
5359 switch (iter
.this_arg_index
) {
5360 case IEEE80211_RADIOTAP_FLAGS
:
5361 if (*iter
.this_arg
& IEEE80211_RADIOTAP_F_FCS
)
5364 case IEEE80211_RADIOTAP_RX_FLAGS
:
5367 case IEEE80211_RADIOTAP_TX_FLAGS
:
5369 failed
= le_to_host16((*(uint16_t *) iter
.this_arg
)) &
5370 IEEE80211_RADIOTAP_F_TX_FAIL
;
5372 case IEEE80211_RADIOTAP_DATA_RETRIES
:
5374 case IEEE80211_RADIOTAP_CHANNEL
:
5375 /* TODO: convert from freq/flags to channel number */
5377 case IEEE80211_RADIOTAP_RATE
:
5378 datarate
= *iter
.this_arg
* 5;
5380 case IEEE80211_RADIOTAP_DB_ANTSIGNAL
:
5381 ssi_signal
= *iter
.this_arg
;
5386 if (rxflags
&& injected
)
5390 handle_frame(drv
, buf
+ iter
.max_length
,
5391 len
- iter
.max_length
, datarate
, ssi_signal
);
5393 handle_tx_callback(drv
->ctx
, buf
+ iter
.max_length
,
5394 len
- iter
.max_length
, !failed
);
5399 * we post-process the filter code later and rewrite
5400 * this to the offset to the last instruction
5405 static struct sock_filter msock_filter_insns
[] = {
5407 * do a little-endian load of the radiotap length field
5409 /* load lower byte into A */
5410 BPF_STMT(BPF_LD
| BPF_B
| BPF_ABS
, 2),
5411 /* put it into X (== index register) */
5412 BPF_STMT(BPF_MISC
| BPF_TAX
, 0),
5413 /* load upper byte into A */
5414 BPF_STMT(BPF_LD
| BPF_B
| BPF_ABS
, 3),
5415 /* left-shift it by 8 */
5416 BPF_STMT(BPF_ALU
| BPF_LSH
| BPF_K
, 8),
5418 BPF_STMT(BPF_ALU
| BPF_OR
| BPF_X
, 0),
5419 /* put result into X */
5420 BPF_STMT(BPF_MISC
| BPF_TAX
, 0),
5423 * Allow management frames through, this also gives us those
5424 * management frames that we sent ourselves with status
5426 /* load the lower byte of the IEEE 802.11 frame control field */
5427 BPF_STMT(BPF_LD
| BPF_B
| BPF_IND
, 0),
5428 /* mask off frame type and version */
5429 BPF_STMT(BPF_ALU
| BPF_AND
| BPF_K
, 0xF),
5430 /* accept frame if it's both 0, fall through otherwise */
5431 BPF_JUMP(BPF_JMP
| BPF_JEQ
| BPF_K
, 0, PASS
, 0),
5434 * TODO: add a bit to radiotap RX flags that indicates
5435 * that the sending station is not associated, then
5436 * add a filter here that filters on our DA and that flag
5437 * to allow us to deauth frames to that bad station.
5439 * For now allow all To DS data frames through.
5441 /* load the IEEE 802.11 frame control field */
5442 BPF_STMT(BPF_LD
| BPF_H
| BPF_IND
, 0),
5443 /* mask off frame type, version and DS status */
5444 BPF_STMT(BPF_ALU
| BPF_AND
| BPF_K
, 0x0F03),
5445 /* accept frame if version 0, type 2 and To DS, fall through otherwise
5447 BPF_JUMP(BPF_JMP
| BPF_JEQ
| BPF_K
, 0x0801, PASS
, 0),
5451 * drop non-data frames
5453 /* load the lower byte of the frame control field */
5454 BPF_STMT(BPF_LD
| BPF_B
| BPF_IND
, 0),
5455 /* mask off QoS bit */
5456 BPF_STMT(BPF_ALU
| BPF_AND
| BPF_K
, 0x0c),
5457 /* drop non-data frames */
5458 BPF_JUMP(BPF_JMP
| BPF_JEQ
| BPF_K
, 8, 0, FAIL
),
5460 /* load the upper byte of the frame control field */
5461 BPF_STMT(BPF_LD
| BPF_B
| BPF_IND
, 1),
5462 /* mask off toDS/fromDS */
5463 BPF_STMT(BPF_ALU
| BPF_AND
| BPF_K
, 0x03),
5464 /* accept WDS frames */
5465 BPF_JUMP(BPF_JMP
| BPF_JEQ
| BPF_K
, 3, PASS
, 0),
5468 * add header length to index
5470 /* load the lower byte of the frame control field */
5471 BPF_STMT(BPF_LD
| BPF_B
| BPF_IND
, 0),
5472 /* mask off QoS bit */
5473 BPF_STMT(BPF_ALU
| BPF_AND
| BPF_K
, 0x80),
5474 /* right shift it by 6 to give 0 or 2 */
5475 BPF_STMT(BPF_ALU
| BPF_RSH
| BPF_K
, 6),
5476 /* add data frame header length */
5477 BPF_STMT(BPF_ALU
| BPF_ADD
| BPF_K
, 24),
5478 /* add index, was start of 802.11 header */
5479 BPF_STMT(BPF_ALU
| BPF_ADD
| BPF_X
, 0),
5480 /* move to index, now start of LL header */
5481 BPF_STMT(BPF_MISC
| BPF_TAX
, 0),
5484 * Accept empty data frames, we use those for
5487 BPF_STMT(BPF_LD
| BPF_W
| BPF_LEN
, 0),
5488 BPF_JUMP(BPF_JMP
| BPF_JEQ
| BPF_X
, 0, PASS
, 0),
5491 * Accept EAPOL frames
5493 BPF_STMT(BPF_LD
| BPF_W
| BPF_IND
, 0),
5494 BPF_JUMP(BPF_JMP
| BPF_JEQ
| BPF_K
, 0xAAAA0300, 0, FAIL
),
5495 BPF_STMT(BPF_LD
| BPF_W
| BPF_IND
, 4),
5496 BPF_JUMP(BPF_JMP
| BPF_JEQ
| BPF_K
, 0x0000888E, PASS
, FAIL
),
5498 /* keep these last two statements or change the code below */
5499 /* return 0 == "DROP" */
5500 BPF_STMT(BPF_RET
| BPF_K
, 0),
5501 /* return ~0 == "keep all" */
5502 BPF_STMT(BPF_RET
| BPF_K
, ~0),
5505 static struct sock_fprog msock_filter
= {
5506 .len
= sizeof(msock_filter_insns
)/sizeof(msock_filter_insns
[0]),
5507 .filter
= msock_filter_insns
,
5511 static int add_monitor_filter(int s
)
5515 /* rewrite all PASS/FAIL jump offsets */
5516 for (idx
= 0; idx
< msock_filter
.len
; idx
++) {
5517 struct sock_filter
*insn
= &msock_filter_insns
[idx
];
5519 if (BPF_CLASS(insn
->code
) == BPF_JMP
) {
5520 if (insn
->code
== (BPF_JMP
|BPF_JA
)) {
5521 if (insn
->k
== PASS
)
5522 insn
->k
= msock_filter
.len
- idx
- 2;
5523 else if (insn
->k
== FAIL
)
5524 insn
->k
= msock_filter
.len
- idx
- 3;
5527 if (insn
->jt
== PASS
)
5528 insn
->jt
= msock_filter
.len
- idx
- 2;
5529 else if (insn
->jt
== FAIL
)
5530 insn
->jt
= msock_filter
.len
- idx
- 3;
5532 if (insn
->jf
== PASS
)
5533 insn
->jf
= msock_filter
.len
- idx
- 2;
5534 else if (insn
->jf
== FAIL
)
5535 insn
->jf
= msock_filter
.len
- idx
- 3;
5539 if (setsockopt(s
, SOL_SOCKET
, SO_ATTACH_FILTER
,
5540 &msock_filter
, sizeof(msock_filter
))) {
5541 perror("SO_ATTACH_FILTER");
5549 static void nl80211_remove_monitor_interface(
5550 struct wpa_driver_nl80211_data
*drv
)
5552 drv
->monitor_refcount
--;
5553 if (drv
->monitor_refcount
> 0)
5556 if (drv
->monitor_ifidx
>= 0) {
5557 nl80211_remove_iface(drv
, drv
->monitor_ifidx
);
5558 drv
->monitor_ifidx
= -1;
5560 if (drv
->monitor_sock
>= 0) {
5561 eloop_unregister_read_sock(drv
->monitor_sock
);
5562 close(drv
->monitor_sock
);
5563 drv
->monitor_sock
= -1;
5569 nl80211_create_monitor_interface(struct wpa_driver_nl80211_data
*drv
)
5572 struct sockaddr_ll ll
;
5576 if (drv
->monitor_ifidx
>= 0) {
5577 drv
->monitor_refcount
++;
5581 if (os_strncmp(drv
->first_bss
.ifname
, "p2p-", 4) == 0) {
5583 * P2P interface name is of the format p2p-%s-%d. For monitor
5584 * interface name corresponding to P2P GO, replace "p2p-" with
5585 * "mon-" to retain the same interface name length and to
5586 * indicate that it is a monitor interface.
5588 snprintf(buf
, IFNAMSIZ
, "mon-%s", drv
->first_bss
.ifname
+ 4);
5590 /* Non-P2P interface with AP functionality. */
5591 snprintf(buf
, IFNAMSIZ
, "mon.%s", drv
->first_bss
.ifname
);
5594 buf
[IFNAMSIZ
- 1] = '\0';
5596 drv
->monitor_ifidx
=
5597 nl80211_create_iface(drv
, buf
, NL80211_IFTYPE_MONITOR
, NULL
,
5600 if (drv
->monitor_ifidx
== -EOPNOTSUPP
) {
5602 * This is backward compatibility for a few versions of
5603 * the kernel only that didn't advertise the right
5604 * attributes for the only driver that then supported
5605 * AP mode w/o monitor -- ath6kl.
5607 wpa_printf(MSG_DEBUG
, "nl80211: Driver does not support "
5608 "monitor interface type - try to run without it");
5609 drv
->device_ap_sme
= 1;
5612 if (drv
->monitor_ifidx
< 0)
5615 if (linux_set_iface_flags(drv
->global
->ioctl_sock
, buf
, 1))
5618 memset(&ll
, 0, sizeof(ll
));
5619 ll
.sll_family
= AF_PACKET
;
5620 ll
.sll_ifindex
= drv
->monitor_ifidx
;
5621 drv
->monitor_sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
5622 if (drv
->monitor_sock
< 0) {
5623 perror("socket[PF_PACKET,SOCK_RAW]");
5627 if (add_monitor_filter(drv
->monitor_sock
)) {
5628 wpa_printf(MSG_INFO
, "Failed to set socket filter for monitor "
5629 "interface; do filtering in user space");
5630 /* This works, but will cost in performance. */
5633 if (bind(drv
->monitor_sock
, (struct sockaddr
*) &ll
, sizeof(ll
)) < 0) {
5634 perror("monitor socket bind");
5638 optlen
= sizeof(optval
);
5641 (drv
->monitor_sock
, SOL_SOCKET
, SO_PRIORITY
, &optval
, optlen
)) {
5642 perror("Failed to set socket priority");
5646 if (eloop_register_read_sock(drv
->monitor_sock
, handle_monitor_read
,
5648 printf("Could not register monitor read socket\n");
5654 nl80211_remove_monitor_interface(drv
);
5659 static int nl80211_setup_ap(struct i802_bss
*bss
)
5661 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
5664 * Disable Probe Request reporting unless we need it in this way for
5665 * devices that include the AP SME, in the other case (unless using
5666 * monitor iface) we'll get it through the nl_mgmt socket instead.
5668 if (!drv
->device_ap_sme
)
5669 wpa_driver_nl80211_probe_req_report(bss
, 0);
5671 if (!drv
->device_ap_sme
&& !drv
->use_monitor
)
5672 if (nl80211_mgmt_subscribe_ap(bss
))
5675 if (!drv
->device_ap_sme
&& drv
->use_monitor
&&
5676 nl80211_create_monitor_interface(drv
) &&
5677 !drv
->device_ap_sme
)
5680 if (drv
->device_ap_sme
&&
5681 wpa_driver_nl80211_probe_req_report(bss
, 1) < 0) {
5682 wpa_printf(MSG_DEBUG
, "nl80211: Failed to enable "
5683 "Probe Request frame reporting in AP mode");
5684 /* Try to survive without this */
5691 static void nl80211_teardown_ap(struct i802_bss
*bss
)
5693 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
5695 if (drv
->device_ap_sme
)
5696 wpa_driver_nl80211_probe_req_report(bss
, 0);
5697 else if (drv
->use_monitor
)
5698 nl80211_remove_monitor_interface(drv
);
5700 nl80211_mgmt_unsubscribe(bss
);
5702 bss
->beacon_set
= 0;
5706 static int nl80211_send_eapol_data(struct i802_bss
*bss
,
5707 const u8
*addr
, const u8
*data
,
5710 struct sockaddr_ll ll
;
5713 if (bss
->drv
->eapol_tx_sock
< 0) {
5714 wpa_printf(MSG_DEBUG
, "nl80211: No socket to send EAPOL");
5718 os_memset(&ll
, 0, sizeof(ll
));
5719 ll
.sll_family
= AF_PACKET
;
5720 ll
.sll_ifindex
= bss
->ifindex
;
5721 ll
.sll_protocol
= htons(ETH_P_PAE
);
5722 ll
.sll_halen
= ETH_ALEN
;
5723 os_memcpy(ll
.sll_addr
, addr
, ETH_ALEN
);
5724 ret
= sendto(bss
->drv
->eapol_tx_sock
, data
, data_len
, 0,
5725 (struct sockaddr
*) &ll
, sizeof(ll
));
5727 wpa_printf(MSG_ERROR
, "nl80211: EAPOL TX: %s",
5734 static const u8 rfc1042_header
[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
5736 static int wpa_driver_nl80211_hapd_send_eapol(
5737 void *priv
, const u8
*addr
, const u8
*data
,
5738 size_t data_len
, int encrypt
, const u8
*own_addr
, u32 flags
)
5740 struct i802_bss
*bss
= priv
;
5741 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
5742 struct ieee80211_hdr
*hdr
;
5746 int qos
= flags
& WPA_STA_WMM
;
5748 if (drv
->device_ap_sme
|| !drv
->use_monitor
)
5749 return nl80211_send_eapol_data(bss
, addr
, data
, data_len
);
5751 len
= sizeof(*hdr
) + (qos
? 2 : 0) + sizeof(rfc1042_header
) + 2 +
5753 hdr
= os_zalloc(len
);
5755 printf("malloc() failed for i802_send_data(len=%lu)\n",
5756 (unsigned long) len
);
5760 hdr
->frame_control
=
5761 IEEE80211_FC(WLAN_FC_TYPE_DATA
, WLAN_FC_STYPE_DATA
);
5762 hdr
->frame_control
|= host_to_le16(WLAN_FC_FROMDS
);
5764 hdr
->frame_control
|= host_to_le16(WLAN_FC_ISWEP
);
5766 hdr
->frame_control
|=
5767 host_to_le16(WLAN_FC_STYPE_QOS_DATA
<< 4);
5770 memcpy(hdr
->IEEE80211_DA_FROMDS
, addr
, ETH_ALEN
);
5771 memcpy(hdr
->IEEE80211_BSSID_FROMDS
, own_addr
, ETH_ALEN
);
5772 memcpy(hdr
->IEEE80211_SA_FROMDS
, own_addr
, ETH_ALEN
);
5773 pos
= (u8
*) (hdr
+ 1);
5776 /* add an empty QoS header if needed */
5782 memcpy(pos
, rfc1042_header
, sizeof(rfc1042_header
));
5783 pos
+= sizeof(rfc1042_header
);
5784 WPA_PUT_BE16(pos
, ETH_P_PAE
);
5786 memcpy(pos
, data
, data_len
);
5788 res
= wpa_driver_nl80211_send_frame(bss
, (u8
*) hdr
, len
, encrypt
, 0);
5790 wpa_printf(MSG_ERROR
, "i802_send_eapol - packet len: %lu - "
5792 (unsigned long) len
, errno
, strerror(errno
));
5800 static int wpa_driver_nl80211_sta_set_flags(void *priv
, const u8
*addr
,
5802 int flags_or
, int flags_and
)
5804 struct i802_bss
*bss
= priv
;
5805 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
5806 struct nl_msg
*msg
, *flags
= NULL
;
5807 struct nl80211_sta_flag_update upd
;
5809 msg
= nlmsg_alloc();
5813 flags
= nlmsg_alloc();
5819 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_STATION
);
5821 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
,
5822 if_nametoindex(bss
->ifname
));
5823 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
5826 * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
5827 * can be removed eventually.
5829 if (total_flags
& WPA_STA_AUTHORIZED
)
5830 NLA_PUT_FLAG(flags
, NL80211_STA_FLAG_AUTHORIZED
);
5832 if (total_flags
& WPA_STA_WMM
)
5833 NLA_PUT_FLAG(flags
, NL80211_STA_FLAG_WME
);
5835 if (total_flags
& WPA_STA_SHORT_PREAMBLE
)
5836 NLA_PUT_FLAG(flags
, NL80211_STA_FLAG_SHORT_PREAMBLE
);
5838 if (total_flags
& WPA_STA_MFP
)
5839 NLA_PUT_FLAG(flags
, NL80211_STA_FLAG_MFP
);
5841 if (total_flags
& WPA_STA_TDLS_PEER
)
5842 NLA_PUT_FLAG(flags
, NL80211_STA_FLAG_TDLS_PEER
);
5844 if (nla_put_nested(msg
, NL80211_ATTR_STA_FLAGS
, flags
))
5845 goto nla_put_failure
;
5847 os_memset(&upd
, 0, sizeof(upd
));
5848 upd
.mask
= sta_flags_nl80211(flags_or
| ~flags_and
);
5849 upd
.set
= sta_flags_nl80211(flags_or
);
5850 NLA_PUT(msg
, NL80211_ATTR_STA_FLAGS2
, sizeof(upd
), &upd
);
5854 return send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
5861 static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data
*drv
,
5862 struct wpa_driver_associate_params
*params
)
5864 enum nl80211_iftype nlmode
;
5867 wpa_printf(MSG_DEBUG
, "nl80211: Setup AP operations for P2P "
5869 nlmode
= NL80211_IFTYPE_P2P_GO
;
5871 nlmode
= NL80211_IFTYPE_AP
;
5873 if (wpa_driver_nl80211_set_mode(&drv
->first_bss
, nlmode
) ||
5874 wpa_driver_nl80211_set_freq(&drv
->first_bss
, params
->freq
, 0, 0)) {
5875 nl80211_remove_monitor_interface(drv
);
5883 static int nl80211_leave_ibss(struct wpa_driver_nl80211_data
*drv
)
5888 msg
= nlmsg_alloc();
5892 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_LEAVE_IBSS
);
5893 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
5894 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
5897 wpa_printf(MSG_DEBUG
, "nl80211: Leave IBSS failed: ret=%d "
5898 "(%s)", ret
, strerror(-ret
));
5899 goto nla_put_failure
;
5903 wpa_printf(MSG_DEBUG
, "nl80211: Leave IBSS request sent successfully");
5911 static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data
*drv
,
5912 struct wpa_driver_associate_params
*params
)
5918 wpa_printf(MSG_DEBUG
, "nl80211: Join IBSS (ifindex=%d)", drv
->ifindex
);
5920 if (wpa_driver_nl80211_set_mode(&drv
->first_bss
,
5921 NL80211_IFTYPE_ADHOC
)) {
5922 wpa_printf(MSG_INFO
, "nl80211: Failed to set interface into "
5928 msg
= nlmsg_alloc();
5932 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_JOIN_IBSS
);
5933 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
5935 if (params
->ssid
== NULL
|| params
->ssid_len
> sizeof(drv
->ssid
))
5936 goto nla_put_failure
;
5938 wpa_hexdump_ascii(MSG_DEBUG
, " * SSID",
5939 params
->ssid
, params
->ssid_len
);
5940 NLA_PUT(msg
, NL80211_ATTR_SSID
, params
->ssid_len
,
5942 os_memcpy(drv
->ssid
, params
->ssid
, params
->ssid_len
);
5943 drv
->ssid_len
= params
->ssid_len
;
5945 wpa_printf(MSG_DEBUG
, " * freq=%d", params
->freq
);
5946 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, params
->freq
);
5948 ret
= nl80211_set_conn_keys(params
, msg
);
5950 goto nla_put_failure
;
5952 if (params
->wpa_ie
) {
5953 wpa_hexdump(MSG_DEBUG
,
5954 " * Extra IEs for Beacon/Probe Response frames",
5955 params
->wpa_ie
, params
->wpa_ie_len
);
5956 NLA_PUT(msg
, NL80211_ATTR_IE
, params
->wpa_ie_len
,
5960 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
5963 wpa_printf(MSG_DEBUG
, "nl80211: Join IBSS failed: ret=%d (%s)",
5964 ret
, strerror(-ret
));
5966 if (ret
== -EALREADY
&& count
== 1) {
5967 wpa_printf(MSG_DEBUG
, "nl80211: Retry IBSS join after "
5969 nl80211_leave_ibss(drv
);
5974 goto nla_put_failure
;
5977 wpa_printf(MSG_DEBUG
, "nl80211: Join IBSS request sent successfully");
5985 static unsigned int nl80211_get_assoc_bssid(struct wpa_driver_nl80211_data
*drv
,
5990 struct nl80211_bss_info_arg arg
;
5992 os_memset(&arg
, 0, sizeof(arg
));
5993 msg
= nlmsg_alloc();
5995 goto nla_put_failure
;
5997 nl80211_cmd(drv
, msg
, NLM_F_DUMP
, NL80211_CMD_GET_SCAN
);
5998 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
6001 ret
= send_and_recv_msgs(drv
, msg
, bss_info_handler
, &arg
);
6004 if (is_zero_ether_addr(arg
.assoc_bssid
))
6006 os_memcpy(bssid
, arg
.assoc_bssid
, ETH_ALEN
);
6009 wpa_printf(MSG_DEBUG
, "nl80211: Scan result fetch failed: ret=%d "
6010 "(%s)", ret
, strerror(-ret
));
6013 return drv
->assoc_freq
;
6017 static int nl80211_disconnect(struct wpa_driver_nl80211_data
*drv
,
6022 if (bssid
== NULL
) {
6023 int res
= nl80211_get_assoc_bssid(drv
, addr
);
6029 return wpa_driver_nl80211_disconnect(drv
, bssid
,
6030 WLAN_REASON_PREV_AUTH_NOT_VALID
);
6034 static int wpa_driver_nl80211_connect(
6035 struct wpa_driver_nl80211_data
*drv
,
6036 struct wpa_driver_associate_params
*params
)
6039 enum nl80211_auth_type type
;
6043 msg
= nlmsg_alloc();
6047 wpa_printf(MSG_DEBUG
, "nl80211: Connect (ifindex=%d)", drv
->ifindex
);
6048 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_CONNECT
);
6050 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
6051 if (params
->bssid
) {
6052 wpa_printf(MSG_DEBUG
, " * bssid=" MACSTR
,
6053 MAC2STR(params
->bssid
));
6054 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, params
->bssid
);
6057 wpa_printf(MSG_DEBUG
, " * freq=%d", params
->freq
);
6058 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, params
->freq
);
6061 wpa_hexdump_ascii(MSG_DEBUG
, " * SSID",
6062 params
->ssid
, params
->ssid_len
);
6063 NLA_PUT(msg
, NL80211_ATTR_SSID
, params
->ssid_len
,
6065 if (params
->ssid_len
> sizeof(drv
->ssid
))
6066 goto nla_put_failure
;
6067 os_memcpy(drv
->ssid
, params
->ssid
, params
->ssid_len
);
6068 drv
->ssid_len
= params
->ssid_len
;
6070 wpa_hexdump(MSG_DEBUG
, " * IEs", params
->wpa_ie
, params
->wpa_ie_len
);
6072 NLA_PUT(msg
, NL80211_ATTR_IE
, params
->wpa_ie_len
,
6076 if (params
->auth_alg
& WPA_AUTH_ALG_OPEN
)
6078 if (params
->auth_alg
& WPA_AUTH_ALG_SHARED
)
6080 if (params
->auth_alg
& WPA_AUTH_ALG_LEAP
)
6083 wpa_printf(MSG_DEBUG
, " * Leave out Auth Type for automatic "
6085 goto skip_auth_type
;
6088 if (params
->auth_alg
& WPA_AUTH_ALG_OPEN
)
6089 type
= NL80211_AUTHTYPE_OPEN_SYSTEM
;
6090 else if (params
->auth_alg
& WPA_AUTH_ALG_SHARED
)
6091 type
= NL80211_AUTHTYPE_SHARED_KEY
;
6092 else if (params
->auth_alg
& WPA_AUTH_ALG_LEAP
)
6093 type
= NL80211_AUTHTYPE_NETWORK_EAP
;
6094 else if (params
->auth_alg
& WPA_AUTH_ALG_FT
)
6095 type
= NL80211_AUTHTYPE_FT
;
6097 goto nla_put_failure
;
6099 wpa_printf(MSG_DEBUG
, " * Auth Type %d", type
);
6100 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
, type
);
6103 if (params
->wpa_proto
) {
6104 enum nl80211_wpa_versions ver
= 0;
6106 if (params
->wpa_proto
& WPA_PROTO_WPA
)
6107 ver
|= NL80211_WPA_VERSION_1
;
6108 if (params
->wpa_proto
& WPA_PROTO_RSN
)
6109 ver
|= NL80211_WPA_VERSION_2
;
6111 wpa_printf(MSG_DEBUG
, " * WPA Versions 0x%x", ver
);
6112 NLA_PUT_U32(msg
, NL80211_ATTR_WPA_VERSIONS
, ver
);
6115 if (params
->pairwise_suite
!= CIPHER_NONE
) {
6118 switch (params
->pairwise_suite
) {
6120 cipher
= WLAN_CIPHER_SUITE_WEP40
;
6123 cipher
= WLAN_CIPHER_SUITE_WEP104
;
6126 cipher
= WLAN_CIPHER_SUITE_CCMP
;
6130 cipher
= WLAN_CIPHER_SUITE_TKIP
;
6133 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITES_PAIRWISE
, cipher
);
6136 if (params
->group_suite
!= CIPHER_NONE
) {
6139 switch (params
->group_suite
) {
6141 cipher
= WLAN_CIPHER_SUITE_WEP40
;
6144 cipher
= WLAN_CIPHER_SUITE_WEP104
;
6147 cipher
= WLAN_CIPHER_SUITE_CCMP
;
6151 cipher
= WLAN_CIPHER_SUITE_TKIP
;
6154 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITE_GROUP
, cipher
);
6157 if (params
->key_mgmt_suite
== KEY_MGMT_802_1X
||
6158 params
->key_mgmt_suite
== KEY_MGMT_PSK
) {
6159 int mgmt
= WLAN_AKM_SUITE_PSK
;
6161 switch (params
->key_mgmt_suite
) {
6162 case KEY_MGMT_802_1X
:
6163 mgmt
= WLAN_AKM_SUITE_8021X
;
6167 mgmt
= WLAN_AKM_SUITE_PSK
;
6170 NLA_PUT_U32(msg
, NL80211_ATTR_AKM_SUITES
, mgmt
);
6173 ret
= nl80211_set_conn_keys(params
, msg
);
6175 goto nla_put_failure
;
6177 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6180 wpa_printf(MSG_DEBUG
, "nl80211: MLME connect failed: ret=%d "
6181 "(%s)", ret
, strerror(-ret
));
6183 * cfg80211 does not currently accept new connection if we are
6184 * already connected. As a workaround, force disconnection and
6185 * try again once the driver indicates it completed
6188 if (ret
== -EALREADY
)
6189 nl80211_disconnect(drv
, params
->bssid
);
6190 goto nla_put_failure
;
6193 wpa_printf(MSG_DEBUG
, "nl80211: Connect request send successfully");
6202 static int wpa_driver_nl80211_associate(
6203 void *priv
, struct wpa_driver_associate_params
*params
)
6205 struct i802_bss
*bss
= priv
;
6206 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6210 if (params
->mode
== IEEE80211_MODE_AP
)
6211 return wpa_driver_nl80211_ap(drv
, params
);
6213 if (params
->mode
== IEEE80211_MODE_IBSS
)
6214 return wpa_driver_nl80211_ibss(drv
, params
);
6216 if (!(drv
->capa
.flags
& WPA_DRIVER_FLAGS_SME
)) {
6217 enum nl80211_iftype nlmode
= params
->p2p
?
6218 NL80211_IFTYPE_P2P_CLIENT
: NL80211_IFTYPE_STATION
;
6220 if (wpa_driver_nl80211_set_mode(priv
, nlmode
) < 0)
6222 return wpa_driver_nl80211_connect(drv
, params
);
6225 drv
->associated
= 0;
6227 msg
= nlmsg_alloc();
6231 wpa_printf(MSG_DEBUG
, "nl80211: Associate (ifindex=%d)",
6233 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_ASSOCIATE
);
6235 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
6236 if (params
->bssid
) {
6237 wpa_printf(MSG_DEBUG
, " * bssid=" MACSTR
,
6238 MAC2STR(params
->bssid
));
6239 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, params
->bssid
);
6242 wpa_printf(MSG_DEBUG
, " * freq=%d", params
->freq
);
6243 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, params
->freq
);
6244 drv
->assoc_freq
= params
->freq
;
6246 drv
->assoc_freq
= 0;
6248 wpa_hexdump_ascii(MSG_DEBUG
, " * SSID",
6249 params
->ssid
, params
->ssid_len
);
6250 NLA_PUT(msg
, NL80211_ATTR_SSID
, params
->ssid_len
,
6252 if (params
->ssid_len
> sizeof(drv
->ssid
))
6253 goto nla_put_failure
;
6254 os_memcpy(drv
->ssid
, params
->ssid
, params
->ssid_len
);
6255 drv
->ssid_len
= params
->ssid_len
;
6257 wpa_hexdump(MSG_DEBUG
, " * IEs", params
->wpa_ie
, params
->wpa_ie_len
);
6259 NLA_PUT(msg
, NL80211_ATTR_IE
, params
->wpa_ie_len
,
6262 if (params
->pairwise_suite
!= CIPHER_NONE
) {
6265 switch (params
->pairwise_suite
) {
6267 cipher
= WLAN_CIPHER_SUITE_WEP40
;
6270 cipher
= WLAN_CIPHER_SUITE_WEP104
;
6273 cipher
= WLAN_CIPHER_SUITE_CCMP
;
6277 cipher
= WLAN_CIPHER_SUITE_TKIP
;
6280 wpa_printf(MSG_DEBUG
, " * pairwise=0x%x", cipher
);
6281 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITES_PAIRWISE
, cipher
);
6284 if (params
->group_suite
!= CIPHER_NONE
) {
6287 switch (params
->group_suite
) {
6289 cipher
= WLAN_CIPHER_SUITE_WEP40
;
6292 cipher
= WLAN_CIPHER_SUITE_WEP104
;
6295 cipher
= WLAN_CIPHER_SUITE_CCMP
;
6299 cipher
= WLAN_CIPHER_SUITE_TKIP
;
6302 wpa_printf(MSG_DEBUG
, " * group=0x%x", cipher
);
6303 NLA_PUT_U32(msg
, NL80211_ATTR_CIPHER_SUITE_GROUP
, cipher
);
6306 #ifdef CONFIG_IEEE80211W
6307 if (params
->mgmt_frame_protection
== MGMT_FRAME_PROTECTION_REQUIRED
)
6308 NLA_PUT_U32(msg
, NL80211_ATTR_USE_MFP
, NL80211_MFP_REQUIRED
);
6309 #endif /* CONFIG_IEEE80211W */
6311 NLA_PUT_FLAG(msg
, NL80211_ATTR_CONTROL_PORT
);
6313 if (params
->prev_bssid
) {
6314 wpa_printf(MSG_DEBUG
, " * prev_bssid=" MACSTR
,
6315 MAC2STR(params
->prev_bssid
));
6316 NLA_PUT(msg
, NL80211_ATTR_PREV_BSSID
, ETH_ALEN
,
6317 params
->prev_bssid
);
6321 wpa_printf(MSG_DEBUG
, " * P2P group");
6323 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6326 wpa_dbg(drv
->ctx
, MSG_DEBUG
,
6327 "nl80211: MLME command failed (assoc): ret=%d (%s)",
6328 ret
, strerror(-ret
));
6329 nl80211_dump_scan(drv
);
6330 goto nla_put_failure
;
6333 wpa_printf(MSG_DEBUG
, "nl80211: Association request send "
6342 static int nl80211_set_mode(struct wpa_driver_nl80211_data
*drv
,
6343 int ifindex
, enum nl80211_iftype mode
)
6348 wpa_printf(MSG_DEBUG
, "nl80211: Set mode ifindex %d iftype %d (%s)",
6349 ifindex
, mode
, nl80211_iftype_str(mode
));
6351 msg
= nlmsg_alloc();
6355 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_INTERFACE
);
6356 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, ifindex
);
6357 NLA_PUT_U32(msg
, NL80211_ATTR_IFTYPE
, mode
);
6359 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6363 wpa_printf(MSG_DEBUG
, "nl80211: Failed to set interface %d to mode %d:"
6364 " %d (%s)", ifindex
, mode
, ret
, strerror(-ret
));
6369 static int wpa_driver_nl80211_set_mode(struct i802_bss
*bss
,
6370 enum nl80211_iftype nlmode
)
6372 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6375 int was_ap
= is_ap_interface(drv
->nlmode
);
6377 if (nl80211_set_mode(drv
, drv
->ifindex
, nlmode
) == 0) {
6378 drv
->nlmode
= nlmode
;
6383 if (nlmode
== drv
->nlmode
) {
6384 wpa_printf(MSG_DEBUG
, "nl80211: Interface already in "
6385 "requested mode - ignore error");
6387 goto done
; /* Already in the requested mode */
6390 /* mac80211 doesn't allow mode changes while the device is up, so
6391 * take the device down, try to set the mode again, and bring the
6394 wpa_printf(MSG_DEBUG
, "nl80211: Try mode change after setting "
6396 for (i
= 0; i
< 10; i
++) {
6398 res
= linux_set_iface_flags(drv
->global
->ioctl_sock
,
6400 if (res
== -EACCES
|| res
== -ENODEV
)
6403 /* Try to set the mode again while the interface is
6405 ret
= nl80211_set_mode(drv
, drv
->ifindex
, nlmode
);
6408 res
= linux_set_iface_flags(drv
->global
->ioctl_sock
,
6412 else if (ret
!= -EBUSY
)
6415 wpa_printf(MSG_DEBUG
, "nl80211: Failed to set "
6417 os_sleep(0, 100000);
6421 wpa_printf(MSG_DEBUG
, "nl80211: Mode change succeeded while "
6422 "interface is down");
6423 drv
->nlmode
= nlmode
;
6424 drv
->ignore_if_down_event
= 1;
6429 wpa_printf(MSG_DEBUG
, "nl80211: Interface mode change to %d "
6430 "from %d failed", nlmode
, drv
->nlmode
);
6434 if (is_ap_interface(nlmode
)) {
6435 nl80211_mgmt_unsubscribe(bss
);
6436 /* Setup additional AP mode functionality if needed */
6437 if (nl80211_setup_ap(bss
))
6439 } else if (was_ap
) {
6440 /* Remove additional AP mode functionality */
6441 nl80211_teardown_ap(bss
);
6443 nl80211_mgmt_unsubscribe(bss
);
6446 if (!is_ap_interface(nlmode
) &&
6447 nl80211_mgmt_subscribe_non_ap(bss
) < 0)
6448 wpa_printf(MSG_DEBUG
, "nl80211: Failed to register Action "
6449 "frame processing - ignore for now");
6455 static int wpa_driver_nl80211_get_capa(void *priv
,
6456 struct wpa_driver_capa
*capa
)
6458 struct i802_bss
*bss
= priv
;
6459 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6460 if (!drv
->has_capability
)
6462 os_memcpy(capa
, &drv
->capa
, sizeof(*capa
));
6467 static int wpa_driver_nl80211_set_operstate(void *priv
, int state
)
6469 struct i802_bss
*bss
= priv
;
6470 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6472 wpa_printf(MSG_DEBUG
, "%s: operstate %d->%d (%s)",
6473 __func__
, drv
->operstate
, state
, state
? "UP" : "DORMANT");
6474 drv
->operstate
= state
;
6475 return netlink_send_oper_ifla(drv
->global
->netlink
, drv
->ifindex
, -1,
6476 state
? IF_OPER_UP
: IF_OPER_DORMANT
);
6480 static int wpa_driver_nl80211_set_supp_port(void *priv
, int authorized
)
6482 struct i802_bss
*bss
= priv
;
6483 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6485 struct nl80211_sta_flag_update upd
;
6487 msg
= nlmsg_alloc();
6491 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_STATION
);
6493 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
,
6494 if_nametoindex(bss
->ifname
));
6495 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, drv
->bssid
);
6497 os_memset(&upd
, 0, sizeof(upd
));
6498 upd
.mask
= BIT(NL80211_STA_FLAG_AUTHORIZED
);
6500 upd
.set
= BIT(NL80211_STA_FLAG_AUTHORIZED
);
6501 NLA_PUT(msg
, NL80211_ATTR_STA_FLAGS2
, sizeof(upd
), &upd
);
6503 return send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6509 /* Set kernel driver on given frequency (MHz) */
6510 static int i802_set_freq(void *priv
, struct hostapd_freq_params
*freq
)
6512 struct i802_bss
*bss
= priv
;
6513 return wpa_driver_nl80211_set_freq(bss
, freq
->freq
, freq
->ht_enabled
,
6514 freq
->sec_channel_offset
);
6518 #if defined(HOSTAPD) || defined(CONFIG_AP)
6520 static inline int min_int(int a
, int b
)
6528 static int get_key_handler(struct nl_msg
*msg
, void *arg
)
6530 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
6531 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
6533 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
6534 genlmsg_attrlen(gnlh
, 0), NULL
);
6537 * TODO: validate the key index and mac address!
6538 * Otherwise, there's a race condition as soon as
6539 * the kernel starts sending key notifications.
6542 if (tb
[NL80211_ATTR_KEY_SEQ
])
6543 memcpy(arg
, nla_data(tb
[NL80211_ATTR_KEY_SEQ
]),
6544 min_int(nla_len(tb
[NL80211_ATTR_KEY_SEQ
]), 6));
6549 static int i802_get_seqnum(const char *iface
, void *priv
, const u8
*addr
,
6552 struct i802_bss
*bss
= priv
;
6553 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6556 msg
= nlmsg_alloc();
6560 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_GET_KEY
);
6563 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
6564 NLA_PUT_U8(msg
, NL80211_ATTR_KEY_IDX
, idx
);
6565 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, if_nametoindex(iface
));
6569 return send_and_recv_msgs(drv
, msg
, get_key_handler
, seq
);
6575 static int i802_set_rts(void *priv
, int rts
)
6577 struct i802_bss
*bss
= priv
;
6578 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6583 msg
= nlmsg_alloc();
6592 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_WIPHY
);
6593 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
6594 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_RTS_THRESHOLD
, val
);
6596 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6600 wpa_printf(MSG_DEBUG
, "nl80211: Failed to set RTS threshold %d: "
6601 "%d (%s)", rts
, ret
, strerror(-ret
));
6606 static int i802_set_frag(void *priv
, int frag
)
6608 struct i802_bss
*bss
= priv
;
6609 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6614 msg
= nlmsg_alloc();
6623 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_WIPHY
);
6624 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
6625 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FRAG_THRESHOLD
, val
);
6627 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6631 wpa_printf(MSG_DEBUG
, "nl80211: Failed to set fragmentation threshold "
6632 "%d: %d (%s)", frag
, ret
, strerror(-ret
));
6637 static int i802_flush(void *priv
)
6639 struct i802_bss
*bss
= priv
;
6640 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6643 msg
= nlmsg_alloc();
6647 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_DEL_STATION
);
6650 * XXX: FIX! this needs to flush all VLANs too
6652 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
,
6653 if_nametoindex(bss
->ifname
));
6655 return send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6661 static int get_sta_handler(struct nl_msg
*msg
, void *arg
)
6663 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
6664 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
6665 struct hostap_sta_driver_data
*data
= arg
;
6666 struct nlattr
*stats
[NL80211_STA_INFO_MAX
+ 1];
6667 static struct nla_policy stats_policy
[NL80211_STA_INFO_MAX
+ 1] = {
6668 [NL80211_STA_INFO_INACTIVE_TIME
] = { .type
= NLA_U32
},
6669 [NL80211_STA_INFO_RX_BYTES
] = { .type
= NLA_U32
},
6670 [NL80211_STA_INFO_TX_BYTES
] = { .type
= NLA_U32
},
6671 [NL80211_STA_INFO_RX_PACKETS
] = { .type
= NLA_U32
},
6672 [NL80211_STA_INFO_TX_PACKETS
] = { .type
= NLA_U32
},
6675 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
6676 genlmsg_attrlen(gnlh
, 0), NULL
);
6679 * TODO: validate the interface and mac address!
6680 * Otherwise, there's a race condition as soon as
6681 * the kernel starts sending station notifications.
6684 if (!tb
[NL80211_ATTR_STA_INFO
]) {
6685 wpa_printf(MSG_DEBUG
, "sta stats missing!");
6688 if (nla_parse_nested(stats
, NL80211_STA_INFO_MAX
,
6689 tb
[NL80211_ATTR_STA_INFO
],
6691 wpa_printf(MSG_DEBUG
, "failed to parse nested attributes!");
6695 if (stats
[NL80211_STA_INFO_INACTIVE_TIME
])
6696 data
->inactive_msec
=
6697 nla_get_u32(stats
[NL80211_STA_INFO_INACTIVE_TIME
]);
6698 if (stats
[NL80211_STA_INFO_RX_BYTES
])
6699 data
->rx_bytes
= nla_get_u32(stats
[NL80211_STA_INFO_RX_BYTES
]);
6700 if (stats
[NL80211_STA_INFO_TX_BYTES
])
6701 data
->tx_bytes
= nla_get_u32(stats
[NL80211_STA_INFO_TX_BYTES
]);
6702 if (stats
[NL80211_STA_INFO_RX_PACKETS
])
6704 nla_get_u32(stats
[NL80211_STA_INFO_RX_PACKETS
]);
6705 if (stats
[NL80211_STA_INFO_TX_PACKETS
])
6707 nla_get_u32(stats
[NL80211_STA_INFO_TX_PACKETS
]);
6712 static int i802_read_sta_data(void *priv
, struct hostap_sta_driver_data
*data
,
6715 struct i802_bss
*bss
= priv
;
6716 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6719 os_memset(data
, 0, sizeof(*data
));
6720 msg
= nlmsg_alloc();
6724 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_GET_STATION
);
6726 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
6727 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, if_nametoindex(bss
->ifname
));
6729 return send_and_recv_msgs(drv
, msg
, get_sta_handler
, data
);
6735 static int i802_set_tx_queue_params(void *priv
, int queue
, int aifs
,
6736 int cw_min
, int cw_max
, int burst_time
)
6738 struct i802_bss
*bss
= priv
;
6739 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6741 struct nlattr
*txq
, *params
;
6743 msg
= nlmsg_alloc();
6747 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_WIPHY
);
6749 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, if_nametoindex(bss
->ifname
));
6751 txq
= nla_nest_start(msg
, NL80211_ATTR_WIPHY_TXQ_PARAMS
);
6753 goto nla_put_failure
;
6755 /* We are only sending parameters for a single TXQ at a time */
6756 params
= nla_nest_start(msg
, 1);
6758 goto nla_put_failure
;
6762 NLA_PUT_U8(msg
, NL80211_TXQ_ATTR_QUEUE
, NL80211_TXQ_Q_VO
);
6765 NLA_PUT_U8(msg
, NL80211_TXQ_ATTR_QUEUE
, NL80211_TXQ_Q_VI
);
6768 NLA_PUT_U8(msg
, NL80211_TXQ_ATTR_QUEUE
, NL80211_TXQ_Q_BE
);
6771 NLA_PUT_U8(msg
, NL80211_TXQ_ATTR_QUEUE
, NL80211_TXQ_Q_BK
);
6774 /* Burst time is configured in units of 0.1 msec and TXOP parameter in
6775 * 32 usec, so need to convert the value here. */
6776 NLA_PUT_U16(msg
, NL80211_TXQ_ATTR_TXOP
, (burst_time
* 100 + 16) / 32);
6777 NLA_PUT_U16(msg
, NL80211_TXQ_ATTR_CWMIN
, cw_min
);
6778 NLA_PUT_U16(msg
, NL80211_TXQ_ATTR_CWMAX
, cw_max
);
6779 NLA_PUT_U8(msg
, NL80211_TXQ_ATTR_AIFS
, aifs
);
6781 nla_nest_end(msg
, params
);
6783 nla_nest_end(msg
, txq
);
6785 if (send_and_recv_msgs(drv
, msg
, NULL
, NULL
) == 0)
6792 static int i802_set_sta_vlan(void *priv
, const u8
*addr
,
6793 const char *ifname
, int vlan_id
)
6795 struct i802_bss
*bss
= priv
;
6796 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6800 msg
= nlmsg_alloc();
6804 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_STATION
);
6806 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
,
6807 if_nametoindex(bss
->ifname
));
6808 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
6809 NLA_PUT_U32(msg
, NL80211_ATTR_STA_VLAN
,
6810 if_nametoindex(ifname
));
6812 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
6814 wpa_printf(MSG_ERROR
, "nl80211: NL80211_ATTR_STA_VLAN (addr="
6815 MACSTR
" ifname=%s vlan_id=%d) failed: %d (%s)",
6816 MAC2STR(addr
), ifname
, vlan_id
, ret
,
6824 static int i802_get_inact_sec(void *priv
, const u8
*addr
)
6826 struct hostap_sta_driver_data data
;
6829 data
.inactive_msec
= (unsigned long) -1;
6830 ret
= i802_read_sta_data(priv
, &data
, addr
);
6831 if (ret
|| data
.inactive_msec
== (unsigned long) -1)
6833 return data
.inactive_msec
/ 1000;
6837 static int i802_sta_clear_stats(void *priv
, const u8
*addr
)
6846 static int i802_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
6849 struct i802_bss
*bss
= priv
;
6850 struct ieee80211_mgmt mgmt
;
6852 memset(&mgmt
, 0, sizeof(mgmt
));
6853 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
6854 WLAN_FC_STYPE_DEAUTH
);
6855 memcpy(mgmt
.da
, addr
, ETH_ALEN
);
6856 memcpy(mgmt
.sa
, own_addr
, ETH_ALEN
);
6857 memcpy(mgmt
.bssid
, own_addr
, ETH_ALEN
);
6858 mgmt
.u
.deauth
.reason_code
= host_to_le16(reason
);
6859 return wpa_driver_nl80211_send_mlme(bss
, (u8
*) &mgmt
,
6861 sizeof(mgmt
.u
.deauth
), 0);
6865 static int i802_sta_disassoc(void *priv
, const u8
*own_addr
, const u8
*addr
,
6868 struct i802_bss
*bss
= priv
;
6869 struct ieee80211_mgmt mgmt
;
6871 memset(&mgmt
, 0, sizeof(mgmt
));
6872 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
6873 WLAN_FC_STYPE_DISASSOC
);
6874 memcpy(mgmt
.da
, addr
, ETH_ALEN
);
6875 memcpy(mgmt
.sa
, own_addr
, ETH_ALEN
);
6876 memcpy(mgmt
.bssid
, own_addr
, ETH_ALEN
);
6877 mgmt
.u
.disassoc
.reason_code
= host_to_le16(reason
);
6878 return wpa_driver_nl80211_send_mlme(bss
, (u8
*) &mgmt
,
6880 sizeof(mgmt
.u
.disassoc
), 0);
6883 #endif /* HOSTAPD || CONFIG_AP */
6887 static void add_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
)
6892 wpa_printf(MSG_DEBUG
, "nl80211: Add own interface ifindex %d",
6894 for (i
= 0; i
< drv
->num_if_indices
; i
++) {
6895 if (drv
->if_indices
[i
] == 0) {
6896 drv
->if_indices
[i
] = ifidx
;
6901 if (drv
->if_indices
!= drv
->default_if_indices
)
6902 old
= drv
->if_indices
;
6906 drv
->if_indices
= os_realloc(old
,
6907 sizeof(int) * (drv
->num_if_indices
+ 1));
6908 if (!drv
->if_indices
) {
6910 drv
->if_indices
= drv
->default_if_indices
;
6912 drv
->if_indices
= old
;
6913 wpa_printf(MSG_ERROR
, "Failed to reallocate memory for "
6915 wpa_printf(MSG_ERROR
, "Ignoring EAPOL on interface %d", ifidx
);
6918 os_memcpy(drv
->if_indices
, drv
->default_if_indices
,
6919 sizeof(drv
->default_if_indices
));
6920 drv
->if_indices
[drv
->num_if_indices
] = ifidx
;
6921 drv
->num_if_indices
++;
6925 static void del_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
)
6929 for (i
= 0; i
< drv
->num_if_indices
; i
++) {
6930 if (drv
->if_indices
[i
] == ifidx
) {
6931 drv
->if_indices
[i
] = 0;
6938 static int have_ifidx(struct wpa_driver_nl80211_data
*drv
, int ifidx
)
6942 for (i
= 0; i
< drv
->num_if_indices
; i
++)
6943 if (drv
->if_indices
[i
] == ifidx
)
6950 static int i802_set_wds_sta(void *priv
, const u8
*addr
, int aid
, int val
,
6951 const char *bridge_ifname
)
6953 struct i802_bss
*bss
= priv
;
6954 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
6955 char name
[IFNAMSIZ
+ 1];
6957 os_snprintf(name
, sizeof(name
), "%s.sta%d", bss
->ifname
, aid
);
6958 wpa_printf(MSG_DEBUG
, "nl80211: Set WDS STA addr=" MACSTR
6959 " aid=%d val=%d name=%s", MAC2STR(addr
), aid
, val
, name
);
6961 if (!if_nametoindex(name
)) {
6962 if (nl80211_create_iface(drv
, name
,
6963 NL80211_IFTYPE_AP_VLAN
,
6966 if (bridge_ifname
&&
6967 linux_br_add_if(drv
->global
->ioctl_sock
,
6968 bridge_ifname
, name
) < 0)
6971 linux_set_iface_flags(drv
->global
->ioctl_sock
, name
, 1);
6972 return i802_set_sta_vlan(priv
, addr
, name
, 0);
6974 i802_set_sta_vlan(priv
, addr
, bss
->ifname
, 0);
6975 return wpa_driver_nl80211_if_remove(priv
, WPA_IF_AP_VLAN
,
6981 static void handle_eapol(int sock
, void *eloop_ctx
, void *sock_ctx
)
6983 struct wpa_driver_nl80211_data
*drv
= eloop_ctx
;
6984 struct sockaddr_ll lladdr
;
6985 unsigned char buf
[3000];
6987 socklen_t fromlen
= sizeof(lladdr
);
6989 len
= recvfrom(sock
, buf
, sizeof(buf
), 0,
6990 (struct sockaddr
*)&lladdr
, &fromlen
);
6996 if (have_ifidx(drv
, lladdr
.sll_ifindex
))
6997 drv_event_eapol_rx(drv
->ctx
, lladdr
.sll_addr
, buf
, len
);
7001 static int i802_check_bridge(struct wpa_driver_nl80211_data
*drv
,
7002 struct i802_bss
*bss
,
7003 const char *brname
, const char *ifname
)
7006 char in_br
[IFNAMSIZ
];
7008 os_strlcpy(bss
->brname
, brname
, IFNAMSIZ
);
7009 ifindex
= if_nametoindex(brname
);
7012 * Bridge was configured, but the bridge device does
7013 * not exist. Try to add it now.
7015 if (linux_br_add(drv
->global
->ioctl_sock
, brname
) < 0) {
7016 wpa_printf(MSG_ERROR
, "nl80211: Failed to add the "
7017 "bridge interface %s: %s",
7018 brname
, strerror(errno
));
7021 bss
->added_bridge
= 1;
7022 add_ifidx(drv
, if_nametoindex(brname
));
7025 if (linux_br_get(in_br
, ifname
) == 0) {
7026 if (os_strcmp(in_br
, brname
) == 0)
7027 return 0; /* already in the bridge */
7029 wpa_printf(MSG_DEBUG
, "nl80211: Removing interface %s from "
7030 "bridge %s", ifname
, in_br
);
7031 if (linux_br_del_if(drv
->global
->ioctl_sock
, in_br
, ifname
) <
7033 wpa_printf(MSG_ERROR
, "nl80211: Failed to "
7034 "remove interface %s from bridge "
7036 ifname
, brname
, strerror(errno
));
7041 wpa_printf(MSG_DEBUG
, "nl80211: Adding interface %s into bridge %s",
7043 if (linux_br_add_if(drv
->global
->ioctl_sock
, brname
, ifname
) < 0) {
7044 wpa_printf(MSG_ERROR
, "nl80211: Failed to add interface %s "
7045 "into bridge %s: %s",
7046 ifname
, brname
, strerror(errno
));
7049 bss
->added_if_into_bridge
= 1;
7055 static void *i802_init(struct hostapd_data
*hapd
,
7056 struct wpa_init_params
*params
)
7058 struct wpa_driver_nl80211_data
*drv
;
7059 struct i802_bss
*bss
;
7061 char brname
[IFNAMSIZ
];
7062 int ifindex
, br_ifindex
;
7065 bss
= wpa_driver_nl80211_init(hapd
, params
->ifname
,
7066 params
->global_priv
);
7071 drv
->nlmode
= NL80211_IFTYPE_AP
;
7072 drv
->eapol_sock
= -1;
7074 if (linux_br_get(brname
, params
->ifname
) == 0) {
7075 wpa_printf(MSG_DEBUG
, "nl80211: Interface %s is in bridge %s",
7076 params
->ifname
, brname
);
7077 br_ifindex
= if_nametoindex(brname
);
7083 drv
->num_if_indices
= sizeof(drv
->default_if_indices
) / sizeof(int);
7084 drv
->if_indices
= drv
->default_if_indices
;
7085 for (i
= 0; i
< params
->num_bridge
; i
++) {
7086 if (params
->bridge
[i
]) {
7087 ifindex
= if_nametoindex(params
->bridge
[i
]);
7089 add_ifidx(drv
, ifindex
);
7090 if (ifindex
== br_ifindex
)
7094 if (!br_added
&& br_ifindex
&&
7095 (params
->num_bridge
== 0 || !params
->bridge
[0]))
7096 add_ifidx(drv
, br_ifindex
);
7098 /* start listening for EAPOL on the default AP interface */
7099 add_ifidx(drv
, drv
->ifindex
);
7101 if (linux_set_iface_flags(drv
->global
->ioctl_sock
, bss
->ifname
, 0))
7104 if (params
->bssid
) {
7105 if (linux_set_ifhwaddr(drv
->global
->ioctl_sock
, bss
->ifname
,
7110 if (wpa_driver_nl80211_set_mode(bss
, drv
->nlmode
)) {
7111 wpa_printf(MSG_ERROR
, "nl80211: Failed to set interface %s "
7112 "into AP mode", bss
->ifname
);
7116 if (params
->num_bridge
&& params
->bridge
[0] &&
7117 i802_check_bridge(drv
, bss
, params
->bridge
[0], params
->ifname
) < 0)
7120 if (linux_set_iface_flags(drv
->global
->ioctl_sock
, bss
->ifname
, 1))
7123 drv
->eapol_sock
= socket(PF_PACKET
, SOCK_DGRAM
, htons(ETH_P_PAE
));
7124 if (drv
->eapol_sock
< 0) {
7125 perror("socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE)");
7129 if (eloop_register_read_sock(drv
->eapol_sock
, handle_eapol
, drv
, NULL
))
7131 printf("Could not register read socket for eapol\n");
7135 if (linux_get_ifhwaddr(drv
->global
->ioctl_sock
, bss
->ifname
,
7142 wpa_driver_nl80211_deinit(bss
);
7147 static void i802_deinit(void *priv
)
7149 wpa_driver_nl80211_deinit(priv
);
7152 #endif /* HOSTAPD */
7155 static enum nl80211_iftype
wpa_driver_nl80211_if_type(
7156 enum wpa_driver_if_type type
)
7159 case WPA_IF_STATION
:
7160 return NL80211_IFTYPE_STATION
;
7161 case WPA_IF_P2P_CLIENT
:
7162 case WPA_IF_P2P_GROUP
:
7163 return NL80211_IFTYPE_P2P_CLIENT
;
7164 case WPA_IF_AP_VLAN
:
7165 return NL80211_IFTYPE_AP_VLAN
;
7167 return NL80211_IFTYPE_AP
;
7169 return NL80211_IFTYPE_P2P_GO
;
7177 static int nl80211_addr_in_use(struct nl80211_global
*global
, const u8
*addr
)
7179 struct wpa_driver_nl80211_data
*drv
;
7180 dl_list_for_each(drv
, &global
->interfaces
,
7181 struct wpa_driver_nl80211_data
, list
) {
7182 if (os_memcmp(addr
, drv
->addr
, ETH_ALEN
) == 0)
7189 static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data
*drv
,
7197 os_memcpy(new_addr
, drv
->addr
, ETH_ALEN
);
7198 for (idx
= 0; idx
< 64; idx
++) {
7199 new_addr
[0] = drv
->addr
[0] | 0x02;
7200 new_addr
[0] ^= idx
<< 2;
7201 if (!nl80211_addr_in_use(drv
->global
, new_addr
))
7207 wpa_printf(MSG_DEBUG
, "nl80211: Assigned new P2P Interface Address "
7208 MACSTR
, MAC2STR(new_addr
));
7213 #endif /* CONFIG_P2P */
7216 static int wpa_driver_nl80211_if_add(void *priv
, enum wpa_driver_if_type type
,
7217 const char *ifname
, const u8
*addr
,
7218 void *bss_ctx
, void **drv_priv
,
7219 char *force_ifname
, u8
*if_addr
,
7222 struct i802_bss
*bss
= priv
;
7223 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7226 struct i802_bss
*new_bss
= NULL
;
7228 if (type
== WPA_IF_AP_BSS
) {
7229 new_bss
= os_zalloc(sizeof(*new_bss
));
7230 if (new_bss
== NULL
)
7233 #endif /* HOSTAPD */
7236 os_memcpy(if_addr
, addr
, ETH_ALEN
);
7237 ifidx
= nl80211_create_iface(drv
, ifname
,
7238 wpa_driver_nl80211_if_type(type
), addr
,
7243 #endif /* HOSTAPD */
7248 linux_get_ifhwaddr(drv
->global
->ioctl_sock
, bss
->ifname
,
7250 nl80211_remove_iface(drv
, ifidx
);
7256 (type
== WPA_IF_P2P_CLIENT
|| type
== WPA_IF_P2P_GROUP
||
7257 type
== WPA_IF_P2P_GO
)) {
7258 /* Enforce unique P2P Interface Address */
7259 u8 new_addr
[ETH_ALEN
], own_addr
[ETH_ALEN
];
7261 if (linux_get_ifhwaddr(drv
->global
->ioctl_sock
, bss
->ifname
,
7263 linux_get_ifhwaddr(drv
->global
->ioctl_sock
, ifname
,
7265 nl80211_remove_iface(drv
, ifidx
);
7268 if (os_memcmp(own_addr
, new_addr
, ETH_ALEN
) == 0) {
7269 wpa_printf(MSG_DEBUG
, "nl80211: Allocate new address "
7270 "for P2P group interface");
7271 if (nl80211_p2p_interface_addr(drv
, new_addr
) < 0) {
7272 nl80211_remove_iface(drv
, ifidx
);
7275 if (linux_set_ifhwaddr(drv
->global
->ioctl_sock
, ifname
,
7277 nl80211_remove_iface(drv
, ifidx
);
7281 os_memcpy(if_addr
, new_addr
, ETH_ALEN
);
7283 #endif /* CONFIG_P2P */
7287 i802_check_bridge(drv
, new_bss
, bridge
, ifname
) < 0) {
7288 wpa_printf(MSG_ERROR
, "nl80211: Failed to add the new "
7289 "interface %s to a bridge %s", ifname
, bridge
);
7290 nl80211_remove_iface(drv
, ifidx
);
7295 if (type
== WPA_IF_AP_BSS
) {
7296 if (linux_set_iface_flags(drv
->global
->ioctl_sock
, ifname
, 1))
7298 nl80211_remove_iface(drv
, ifidx
);
7302 os_strlcpy(new_bss
->ifname
, ifname
, IFNAMSIZ
);
7303 new_bss
->ifindex
= ifidx
;
7305 new_bss
->next
= drv
->first_bss
.next
;
7306 drv
->first_bss
.next
= new_bss
;
7308 *drv_priv
= new_bss
;
7309 nl80211_init_bss(new_bss
);
7311 #endif /* HOSTAPD */
7314 drv
->global
->if_add_ifindex
= ifidx
;
7320 static int wpa_driver_nl80211_if_remove(void *priv
,
7321 enum wpa_driver_if_type type
,
7324 struct i802_bss
*bss
= priv
;
7325 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7326 int ifindex
= if_nametoindex(ifname
);
7328 wpa_printf(MSG_DEBUG
, "nl80211: %s(type=%d ifname=%s) ifindex=%d",
7329 __func__
, type
, ifname
, ifindex
);
7334 if (bss
->added_if_into_bridge
) {
7335 if (linux_br_del_if(drv
->global
->ioctl_sock
, bss
->brname
,
7337 wpa_printf(MSG_INFO
, "nl80211: Failed to remove "
7338 "interface %s from bridge %s: %s",
7339 bss
->ifname
, bss
->brname
, strerror(errno
));
7341 if (bss
->added_bridge
) {
7342 if (linux_br_del(drv
->global
->ioctl_sock
, bss
->brname
) < 0)
7343 wpa_printf(MSG_INFO
, "nl80211: Failed to remove "
7345 bss
->brname
, strerror(errno
));
7347 #endif /* HOSTAPD */
7349 nl80211_remove_iface(drv
, ifindex
);
7352 if (type
!= WPA_IF_AP_BSS
)
7355 if (bss
!= &drv
->first_bss
) {
7356 struct i802_bss
*tbss
;
7358 for (tbss
= &drv
->first_bss
; tbss
; tbss
= tbss
->next
) {
7359 if (tbss
->next
== bss
) {
7360 tbss
->next
= bss
->next
;
7361 nl80211_destroy_bss(bss
);
7368 wpa_printf(MSG_INFO
, "nl80211: %s - could not find "
7369 "BSS %p in the list", __func__
, bss
);
7371 #endif /* HOSTAPD */
7377 static int cookie_handler(struct nl_msg
*msg
, void *arg
)
7379 struct nlattr
*tb
[NL80211_ATTR_MAX
+ 1];
7380 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
7382 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
7383 genlmsg_attrlen(gnlh
, 0), NULL
);
7384 if (tb
[NL80211_ATTR_COOKIE
])
7385 *cookie
= nla_get_u64(tb
[NL80211_ATTR_COOKIE
]);
7390 static int nl80211_send_frame_cmd(struct i802_bss
*bss
,
7391 unsigned int freq
, unsigned int wait
,
7392 const u8
*buf
, size_t buf_len
,
7393 u64
*cookie_out
, int no_cck
, int no_ack
,
7396 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7401 msg
= nlmsg_alloc();
7405 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_FRAME
);
7407 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, bss
->ifindex
);
7408 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
7410 NLA_PUT_U32(msg
, NL80211_ATTR_DURATION
, wait
);
7412 NLA_PUT_FLAG(msg
, NL80211_ATTR_OFFCHANNEL_TX_OK
);
7414 NLA_PUT_FLAG(msg
, NL80211_ATTR_TX_NO_CCK_RATE
);
7416 NLA_PUT_FLAG(msg
, NL80211_ATTR_DONT_WAIT_FOR_ACK
);
7418 NLA_PUT(msg
, NL80211_ATTR_FRAME
, buf_len
, buf
);
7421 ret
= send_and_recv_msgs(drv
, msg
, cookie_handler
, &cookie
);
7424 wpa_printf(MSG_DEBUG
, "nl80211: Frame command failed: ret=%d "
7425 "(%s) (freq=%u wait=%u)", ret
, strerror(-ret
),
7427 goto nla_put_failure
;
7429 wpa_printf(MSG_DEBUG
, "nl80211: Frame TX command accepted%s; "
7430 "cookie 0x%llx", no_ack
? " (no ACK)" : "",
7431 (long long unsigned int) cookie
);
7434 *cookie_out
= no_ack
? (u64
) -1 : cookie
;
7442 static int wpa_driver_nl80211_send_action(void *priv
, unsigned int freq
,
7443 unsigned int wait_time
,
7444 const u8
*dst
, const u8
*src
,
7446 const u8
*data
, size_t data_len
,
7449 struct i802_bss
*bss
= priv
;
7450 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7453 struct ieee80211_hdr
*hdr
;
7455 wpa_printf(MSG_DEBUG
, "nl80211: Send Action frame (ifindex=%d, "
7456 "wait=%d ms no_cck=%d)", drv
->ifindex
, wait_time
, no_cck
);
7458 buf
= os_zalloc(24 + data_len
);
7461 os_memcpy(buf
+ 24, data
, data_len
);
7462 hdr
= (struct ieee80211_hdr
*) buf
;
7463 hdr
->frame_control
=
7464 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_ACTION
);
7465 os_memcpy(hdr
->addr1
, dst
, ETH_ALEN
);
7466 os_memcpy(hdr
->addr2
, src
, ETH_ALEN
);
7467 os_memcpy(hdr
->addr3
, bssid
, ETH_ALEN
);
7469 if (is_ap_interface(drv
->nlmode
))
7470 ret
= wpa_driver_nl80211_send_mlme(priv
, buf
, 24 + data_len
,
7473 ret
= nl80211_send_frame_cmd(bss
, freq
, wait_time
, buf
,
7475 &drv
->send_action_cookie
,
7483 static void wpa_driver_nl80211_send_action_cancel_wait(void *priv
)
7485 struct i802_bss
*bss
= priv
;
7486 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7490 msg
= nlmsg_alloc();
7494 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_FRAME_WAIT_CANCEL
);
7496 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
7497 NLA_PUT_U64(msg
, NL80211_ATTR_COOKIE
, drv
->send_action_cookie
);
7499 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
7502 wpa_printf(MSG_DEBUG
, "nl80211: wait cancel failed: ret=%d "
7503 "(%s)", ret
, strerror(-ret
));
7510 static int wpa_driver_nl80211_remain_on_channel(void *priv
, unsigned int freq
,
7511 unsigned int duration
)
7513 struct i802_bss
*bss
= priv
;
7514 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7519 msg
= nlmsg_alloc();
7523 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_REMAIN_ON_CHANNEL
);
7525 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
7526 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
7527 NLA_PUT_U32(msg
, NL80211_ATTR_DURATION
, duration
);
7530 ret
= send_and_recv_msgs(drv
, msg
, cookie_handler
, &cookie
);
7532 wpa_printf(MSG_DEBUG
, "nl80211: Remain-on-channel cookie "
7533 "0x%llx for freq=%u MHz duration=%u",
7534 (long long unsigned int) cookie
, freq
, duration
);
7535 drv
->remain_on_chan_cookie
= cookie
;
7536 drv
->pending_remain_on_chan
= 1;
7539 wpa_printf(MSG_DEBUG
, "nl80211: Failed to request remain-on-channel "
7540 "(freq=%d duration=%u): %d (%s)",
7541 freq
, duration
, ret
, strerror(-ret
));
7547 static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv
)
7549 struct i802_bss
*bss
= priv
;
7550 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7554 if (!drv
->pending_remain_on_chan
) {
7555 wpa_printf(MSG_DEBUG
, "nl80211: No pending remain-on-channel "
7560 wpa_printf(MSG_DEBUG
, "nl80211: Cancel remain-on-channel with cookie "
7562 (long long unsigned int) drv
->remain_on_chan_cookie
);
7564 msg
= nlmsg_alloc();
7568 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL
);
7570 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
7571 NLA_PUT_U64(msg
, NL80211_ATTR_COOKIE
, drv
->remain_on_chan_cookie
);
7573 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
7576 wpa_printf(MSG_DEBUG
, "nl80211: Failed to cancel remain-on-channel: "
7577 "%d (%s)", ret
, strerror(-ret
));
7583 static int wpa_driver_nl80211_probe_req_report(void *priv
, int report
)
7585 struct i802_bss
*bss
= priv
;
7586 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7589 if (bss
->nl_preq
.handle
) {
7590 eloop_unregister_read_sock(
7591 nl_socket_get_fd(bss
->nl_preq
.handle
));
7592 nl_destroy_handles(&bss
->nl_preq
);
7597 if (bss
->nl_preq
.handle
) {
7598 wpa_printf(MSG_DEBUG
, "nl80211: Probe Request reporting "
7603 if (nl_create_handles(&bss
->nl_preq
, drv
->global
->nl_cb
, "preq"))
7606 if (nl80211_register_frame(bss
, bss
->nl_preq
.handle
,
7607 (WLAN_FC_TYPE_MGMT
<< 2) |
7608 (WLAN_FC_STYPE_PROBE_REQ
<< 4),
7612 eloop_register_read_sock(nl_socket_get_fd(bss
->nl_preq
.handle
),
7613 wpa_driver_nl80211_event_receive
, bss
->nl_cb
,
7614 bss
->nl_preq
.handle
);
7619 nl_destroy_handles(&bss
->nl_preq
);
7624 static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data
*drv
,
7625 int ifindex
, int disabled
)
7628 struct nlattr
*bands
, *band
;
7631 msg
= nlmsg_alloc();
7635 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_TX_BITRATE_MASK
);
7636 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, ifindex
);
7638 bands
= nla_nest_start(msg
, NL80211_ATTR_TX_RATES
);
7640 goto nla_put_failure
;
7643 * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
7644 * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
7645 * rates. All 5 GHz rates are left enabled.
7647 band
= nla_nest_start(msg
, NL80211_BAND_2GHZ
);
7649 goto nla_put_failure
;
7651 NLA_PUT(msg
, NL80211_TXRATE_LEGACY
, 8,
7652 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
7654 nla_nest_end(msg
, band
);
7656 nla_nest_end(msg
, bands
);
7658 ret
= send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
7661 wpa_printf(MSG_DEBUG
, "nl80211: Set TX rates failed: ret=%d "
7662 "(%s)", ret
, strerror(-ret
));
7673 static int wpa_driver_nl80211_deinit_ap(void *priv
)
7675 struct i802_bss
*bss
= priv
;
7676 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7677 if (!is_ap_interface(drv
->nlmode
))
7679 wpa_driver_nl80211_del_beacon(drv
);
7680 return wpa_driver_nl80211_set_mode(priv
, NL80211_IFTYPE_STATION
);
7684 static void wpa_driver_nl80211_resume(void *priv
)
7686 struct i802_bss
*bss
= priv
;
7687 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7688 if (linux_set_iface_flags(drv
->global
->ioctl_sock
, bss
->ifname
, 1)) {
7689 wpa_printf(MSG_DEBUG
, "nl80211: Failed to set interface up on "
7695 static int nl80211_send_ft_action(void *priv
, u8 action
, const u8
*target_ap
,
7696 const u8
*ies
, size_t ies_len
)
7698 struct i802_bss
*bss
= priv
;
7699 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7703 u8 own_addr
[ETH_ALEN
];
7705 if (linux_get_ifhwaddr(drv
->global
->ioctl_sock
, bss
->ifname
,
7710 wpa_printf(MSG_ERROR
, "nl80211: Unsupported send_ft_action "
7711 "action %d", action
);
7716 * Action frame payload:
7717 * Category[1] = 6 (Fast BSS Transition)
7718 * Action[1] = 1 (Fast BSS Transition Request)
7724 data_len
= 2 + 2 * ETH_ALEN
+ ies_len
;
7725 data
= os_malloc(data_len
);
7729 *pos
++ = 0x06; /* FT Action category */
7731 os_memcpy(pos
, own_addr
, ETH_ALEN
);
7733 os_memcpy(pos
, target_ap
, ETH_ALEN
);
7735 os_memcpy(pos
, ies
, ies_len
);
7737 ret
= wpa_driver_nl80211_send_action(bss
, drv
->assoc_freq
, 0,
7738 drv
->bssid
, own_addr
, drv
->bssid
,
7746 static int nl80211_signal_monitor(void *priv
, int threshold
, int hysteresis
)
7748 struct i802_bss
*bss
= priv
;
7749 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7750 struct nl_msg
*msg
, *cqm
= NULL
;
7752 wpa_printf(MSG_DEBUG
, "nl80211: Signal monitor threshold=%d "
7753 "hysteresis=%d", threshold
, hysteresis
);
7755 msg
= nlmsg_alloc();
7759 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_CQM
);
7761 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, bss
->ifindex
);
7763 cqm
= nlmsg_alloc();
7767 NLA_PUT_U32(cqm
, NL80211_ATTR_CQM_RSSI_THOLD
, threshold
);
7768 NLA_PUT_U32(cqm
, NL80211_ATTR_CQM_RSSI_HYST
, hysteresis
);
7769 nla_put_nested(msg
, NL80211_ATTR_CQM
, cqm
);
7771 if (send_and_recv_msgs(drv
, msg
, NULL
, NULL
) == 0)
7783 static int nl80211_signal_poll(void *priv
, struct wpa_signal_info
*si
)
7785 struct i802_bss
*bss
= priv
;
7786 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7789 os_memset(si
, 0, sizeof(*si
));
7790 res
= nl80211_get_link_signal(drv
, si
);
7794 return nl80211_get_link_noise(drv
, si
);
7798 static int wpa_driver_nl80211_shared_freq(void *priv
)
7800 struct i802_bss
*bss
= priv
;
7801 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7802 struct wpa_driver_nl80211_data
*driver
;
7806 * If the same PHY is in connected state with some other interface,
7807 * then retrieve the assoc freq.
7809 wpa_printf(MSG_DEBUG
, "nl80211: Get shared freq for PHY %s",
7812 dl_list_for_each(driver
, &drv
->global
->interfaces
,
7813 struct wpa_driver_nl80211_data
, list
) {
7814 if (drv
== driver
||
7815 os_strcmp(drv
->phyname
, driver
->phyname
) != 0 ||
7816 !driver
->associated
)
7819 wpa_printf(MSG_DEBUG
, "nl80211: Found a match for PHY %s - %s "
7821 driver
->phyname
, driver
->first_bss
.ifname
,
7822 MAC2STR(driver
->addr
));
7823 freq
= nl80211_get_assoc_freq(driver
);
7824 wpa_printf(MSG_DEBUG
, "nl80211: Shared freq for PHY %s: %d",
7825 drv
->phyname
, freq
);
7829 wpa_printf(MSG_DEBUG
, "nl80211: No shared interface for "
7830 "PHY (%s) in associated state", drv
->phyname
);
7836 static int nl80211_send_frame(void *priv
, const u8
*data
, size_t data_len
,
7839 struct i802_bss
*bss
= priv
;
7840 return wpa_driver_nl80211_send_frame(bss
, data
, data_len
, encrypt
, 0);
7844 static int nl80211_set_param(void *priv
, const char *param
)
7846 wpa_printf(MSG_DEBUG
, "nl80211: driver param='%s'", param
);
7851 if (os_strstr(param
, "use_p2p_group_interface=1")) {
7852 struct i802_bss
*bss
= priv
;
7853 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7855 wpa_printf(MSG_DEBUG
, "nl80211: Use separate P2P group "
7857 drv
->capa
.flags
|= WPA_DRIVER_FLAGS_P2P_CONCURRENT
;
7858 drv
->capa
.flags
|= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P
;
7860 #endif /* CONFIG_P2P */
7866 static void * nl80211_global_init(void)
7868 struct nl80211_global
*global
;
7869 struct netlink_config
*cfg
;
7871 global
= os_zalloc(sizeof(*global
));
7874 global
->ioctl_sock
= -1;
7875 dl_list_init(&global
->interfaces
);
7876 global
->if_add_ifindex
= -1;
7878 cfg
= os_zalloc(sizeof(*cfg
));
7883 cfg
->newlink_cb
= wpa_driver_nl80211_event_rtm_newlink
;
7884 cfg
->dellink_cb
= wpa_driver_nl80211_event_rtm_dellink
;
7885 global
->netlink
= netlink_init(cfg
);
7886 if (global
->netlink
== NULL
) {
7891 if (wpa_driver_nl80211_init_nl_global(global
) < 0)
7894 global
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
7895 if (global
->ioctl_sock
< 0) {
7896 perror("socket(PF_INET,SOCK_DGRAM)");
7903 nl80211_global_deinit(global
);
7908 static void nl80211_global_deinit(void *priv
)
7910 struct nl80211_global
*global
= priv
;
7913 if (!dl_list_empty(&global
->interfaces
)) {
7914 wpa_printf(MSG_ERROR
, "nl80211: %u interface(s) remain at "
7915 "nl80211_global_deinit",
7916 dl_list_len(&global
->interfaces
));
7919 if (global
->netlink
)
7920 netlink_deinit(global
->netlink
);
7922 nl_destroy_handles(&global
->nl
);
7925 nl_cb_put(global
->nl_cb
);
7927 if (global
->ioctl_sock
>= 0)
7928 close(global
->ioctl_sock
);
7934 static const char * nl80211_get_radio_name(void *priv
)
7936 struct i802_bss
*bss
= priv
;
7937 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7938 return drv
->phyname
;
7942 static int nl80211_pmkid(struct i802_bss
*bss
, int cmd
, const u8
*bssid
,
7947 msg
= nlmsg_alloc();
7951 nl80211_cmd(bss
->drv
, msg
, 0, cmd
);
7953 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, if_nametoindex(bss
->ifname
));
7955 NLA_PUT(msg
, NL80211_ATTR_PMKID
, 16, pmkid
);
7957 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, bssid
);
7959 return send_and_recv_msgs(bss
->drv
, msg
, NULL
, NULL
);
7965 static int nl80211_add_pmkid(void *priv
, const u8
*bssid
, const u8
*pmkid
)
7967 struct i802_bss
*bss
= priv
;
7968 wpa_printf(MSG_DEBUG
, "nl80211: Add PMKID for " MACSTR
, MAC2STR(bssid
));
7969 return nl80211_pmkid(bss
, NL80211_CMD_SET_PMKSA
, bssid
, pmkid
);
7973 static int nl80211_remove_pmkid(void *priv
, const u8
*bssid
, const u8
*pmkid
)
7975 struct i802_bss
*bss
= priv
;
7976 wpa_printf(MSG_DEBUG
, "nl80211: Delete PMKID for " MACSTR
,
7978 return nl80211_pmkid(bss
, NL80211_CMD_DEL_PMKSA
, bssid
, pmkid
);
7982 static int nl80211_flush_pmkid(void *priv
)
7984 struct i802_bss
*bss
= priv
;
7985 wpa_printf(MSG_DEBUG
, "nl80211: Flush PMKIDs");
7986 return nl80211_pmkid(bss
, NL80211_CMD_FLUSH_PMKSA
, NULL
, NULL
);
7990 static void nl80211_set_rekey_info(void *priv
, const u8
*kek
, const u8
*kck
,
7991 const u8
*replay_ctr
)
7993 struct i802_bss
*bss
= priv
;
7994 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
7995 struct nlattr
*replay_nested
;
7998 msg
= nlmsg_alloc();
8002 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_SET_REKEY_OFFLOAD
);
8004 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, bss
->ifindex
);
8006 replay_nested
= nla_nest_start(msg
, NL80211_ATTR_REKEY_DATA
);
8008 goto nla_put_failure
;
8010 NLA_PUT(msg
, NL80211_REKEY_DATA_KEK
, NL80211_KEK_LEN
, kek
);
8011 NLA_PUT(msg
, NL80211_REKEY_DATA_KCK
, NL80211_KCK_LEN
, kck
);
8012 NLA_PUT(msg
, NL80211_REKEY_DATA_REPLAY_CTR
, NL80211_REPLAY_CTR_LEN
,
8015 nla_nest_end(msg
, replay_nested
);
8017 send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
8024 static void nl80211_send_null_frame(struct i802_bss
*bss
, const u8
*own_addr
,
8025 const u8
*addr
, int qos
)
8027 /* send data frame to poll STA and check whether
8028 * this frame is ACKed */
8030 struct ieee80211_hdr hdr
;
8032 } STRUCT_PACKED nulldata
;
8035 /* Send data frame to poll STA and check whether this frame is ACKed */
8037 os_memset(&nulldata
, 0, sizeof(nulldata
));
8040 nulldata
.hdr
.frame_control
=
8041 IEEE80211_FC(WLAN_FC_TYPE_DATA
,
8042 WLAN_FC_STYPE_QOS_NULL
);
8043 size
= sizeof(nulldata
);
8045 nulldata
.hdr
.frame_control
=
8046 IEEE80211_FC(WLAN_FC_TYPE_DATA
,
8047 WLAN_FC_STYPE_NULLFUNC
);
8048 size
= sizeof(struct ieee80211_hdr
);
8051 nulldata
.hdr
.frame_control
|= host_to_le16(WLAN_FC_FROMDS
);
8052 os_memcpy(nulldata
.hdr
.IEEE80211_DA_FROMDS
, addr
, ETH_ALEN
);
8053 os_memcpy(nulldata
.hdr
.IEEE80211_BSSID_FROMDS
, own_addr
, ETH_ALEN
);
8054 os_memcpy(nulldata
.hdr
.IEEE80211_SA_FROMDS
, own_addr
, ETH_ALEN
);
8056 if (wpa_driver_nl80211_send_mlme(bss
, (u8
*) &nulldata
, size
, 0) < 0)
8057 wpa_printf(MSG_DEBUG
, "nl80211_send_null_frame: Failed to "
8061 static void nl80211_poll_client(void *priv
, const u8
*own_addr
, const u8
*addr
,
8064 struct i802_bss
*bss
= priv
;
8065 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
8068 if (!drv
->poll_command_supported
) {
8069 nl80211_send_null_frame(bss
, own_addr
, addr
, qos
);
8073 msg
= nlmsg_alloc();
8077 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_PROBE_CLIENT
);
8079 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, bss
->ifindex
);
8080 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, addr
);
8082 send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
8089 static int nl80211_set_power_save(struct i802_bss
*bss
, int enabled
)
8093 msg
= nlmsg_alloc();
8097 nl80211_cmd(bss
->drv
, msg
, 0, NL80211_CMD_SET_POWER_SAVE
);
8098 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, bss
->ifindex
);
8099 NLA_PUT_U32(msg
, NL80211_ATTR_PS_STATE
,
8100 enabled
? NL80211_PS_ENABLED
: NL80211_PS_DISABLED
);
8101 return send_and_recv_msgs(bss
->drv
, msg
, NULL
, NULL
);
8108 static int nl80211_set_p2p_powersave(void *priv
, int legacy_ps
, int opp_ps
,
8111 struct i802_bss
*bss
= priv
;
8113 wpa_printf(MSG_DEBUG
, "nl80211: set_p2p_powersave (legacy_ps=%d "
8114 "opp_ps=%d ctwindow=%d)", legacy_ps
, opp_ps
, ctwindow
);
8116 if (opp_ps
!= -1 || ctwindow
!= -1)
8117 return -1; /* Not yet supported */
8119 if (legacy_ps
== -1)
8121 if (legacy_ps
!= 0 && legacy_ps
!= 1)
8122 return -1; /* Not yet supported */
8124 return nl80211_set_power_save(bss
, legacy_ps
);
8130 static int nl80211_send_tdls_mgmt(void *priv
, const u8
*dst
, u8 action_code
,
8131 u8 dialog_token
, u16 status_code
,
8132 const u8
*buf
, size_t len
)
8134 struct i802_bss
*bss
= priv
;
8135 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
8138 if (!(drv
->capa
.flags
& WPA_DRIVER_FLAGS_TDLS_SUPPORT
))
8144 msg
= nlmsg_alloc();
8148 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_TDLS_MGMT
);
8149 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
8150 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, dst
);
8151 NLA_PUT_U8(msg
, NL80211_ATTR_TDLS_ACTION
, action_code
);
8152 NLA_PUT_U8(msg
, NL80211_ATTR_TDLS_DIALOG_TOKEN
, dialog_token
);
8153 NLA_PUT_U16(msg
, NL80211_ATTR_STATUS_CODE
, status_code
);
8154 NLA_PUT(msg
, NL80211_ATTR_IE
, len
, buf
);
8156 return send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
8164 static int nl80211_tdls_oper(void *priv
, enum tdls_oper oper
, const u8
*peer
)
8166 struct i802_bss
*bss
= priv
;
8167 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
8169 enum nl80211_tdls_operation nl80211_oper
;
8171 if (!(drv
->capa
.flags
& WPA_DRIVER_FLAGS_TDLS_SUPPORT
))
8175 case TDLS_DISCOVERY_REQ
:
8176 nl80211_oper
= NL80211_TDLS_DISCOVERY_REQ
;
8179 nl80211_oper
= NL80211_TDLS_SETUP
;
8182 nl80211_oper
= NL80211_TDLS_TEARDOWN
;
8184 case TDLS_ENABLE_LINK
:
8185 nl80211_oper
= NL80211_TDLS_ENABLE_LINK
;
8187 case TDLS_DISABLE_LINK
:
8188 nl80211_oper
= NL80211_TDLS_DISABLE_LINK
;
8198 msg
= nlmsg_alloc();
8202 nl80211_cmd(drv
, msg
, 0, NL80211_CMD_TDLS_OPER
);
8203 NLA_PUT_U8(msg
, NL80211_ATTR_TDLS_OPERATION
, nl80211_oper
);
8204 NLA_PUT_U32(msg
, NL80211_ATTR_IFINDEX
, drv
->ifindex
);
8205 NLA_PUT(msg
, NL80211_ATTR_MAC
, ETH_ALEN
, peer
);
8207 return send_and_recv_msgs(drv
, msg
, NULL
, NULL
);
8214 #endif /* CONFIG TDLS */
8219 typedef struct android_wifi_priv_cmd
{
8223 } android_wifi_priv_cmd
;
8225 static int drv_errors
= 0;
8227 static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data
*drv
)
8230 if (drv_errors
> DRV_NUMBER_SEQUENTIAL_ERRORS
) {
8232 wpa_msg(drv
->ctx
, MSG_INFO
, WPA_EVENT_DRIVER_STATE
"HANGED");
8237 static int android_priv_cmd(struct i802_bss
*bss
, const char *cmd
)
8239 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
8241 android_wifi_priv_cmd priv_cmd
;
8242 char buf
[MAX_DRV_CMD_SIZE
];
8245 os_memset(&ifr
, 0, sizeof(ifr
));
8246 os_memset(&priv_cmd
, 0, sizeof(priv_cmd
));
8247 os_strlcpy(ifr
.ifr_name
, bss
->ifname
, IFNAMSIZ
);
8249 os_memset(buf
, 0, sizeof(buf
));
8250 os_strlcpy(buf
, cmd
, sizeof(buf
));
8253 priv_cmd
.used_len
= sizeof(buf
);
8254 priv_cmd
.total_len
= sizeof(buf
);
8255 ifr
.ifr_data
= &priv_cmd
;
8257 ret
= ioctl(drv
->global
->ioctl_sock
, SIOCDEVPRIVATE
+ 1, &ifr
);
8259 wpa_printf(MSG_ERROR
, "%s: failed to issue private commands",
8261 wpa_driver_send_hang_msg(drv
);
8270 static int android_pno_start(struct i802_bss
*bss
,
8271 struct wpa_driver_scan_params
*params
)
8273 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
8275 android_wifi_priv_cmd priv_cmd
;
8276 int ret
= 0, i
= 0, bp
;
8277 char buf
[WEXT_PNO_MAX_COMMAND_SIZE
];
8279 bp
= WEXT_PNOSETUP_HEADER_SIZE
;
8280 os_memcpy(buf
, WEXT_PNOSETUP_HEADER
, bp
);
8281 buf
[bp
++] = WEXT_PNO_TLV_PREFIX
;
8282 buf
[bp
++] = WEXT_PNO_TLV_VERSION
;
8283 buf
[bp
++] = WEXT_PNO_TLV_SUBVERSION
;
8284 buf
[bp
++] = WEXT_PNO_TLV_RESERVED
;
8286 while (i
< WEXT_PNO_AMOUNT
&& (size_t) i
< params
->num_ssids
) {
8287 /* Check that there is enough space needed for 1 more SSID, the
8288 * other sections and null termination */
8289 if ((bp
+ WEXT_PNO_SSID_HEADER_SIZE
+ MAX_SSID_LEN
+
8290 WEXT_PNO_NONSSID_SECTIONS_SIZE
+ 1) >= (int) sizeof(buf
))
8292 wpa_hexdump_ascii(MSG_DEBUG
, "For PNO Scan",
8293 ssid
[i
].ssid
, ssid
[i
].ssid_len
);
8294 buf
[bp
++] = WEXT_PNO_SSID_SECTION
;
8295 buf
[bp
++] = params
->ssids
[i
].ssid_len
;
8296 os_memcpy(&buf
[bp
], params
->ssids
[i
].ssid
,
8297 params
->ssids
[i
].ssid_len
);
8298 bp
+= params
->ssids
[i
].ssid_len
;
8302 buf
[bp
++] = WEXT_PNO_SCAN_INTERVAL_SECTION
;
8303 os_snprintf(&buf
[bp
], WEXT_PNO_SCAN_INTERVAL_LENGTH
+ 1, "%x",
8304 WEXT_PNO_SCAN_INTERVAL
);
8305 bp
+= WEXT_PNO_SCAN_INTERVAL_LENGTH
;
8307 buf
[bp
++] = WEXT_PNO_REPEAT_SECTION
;
8308 os_snprintf(&buf
[bp
], WEXT_PNO_REPEAT_LENGTH
+ 1, "%x",
8310 bp
+= WEXT_PNO_REPEAT_LENGTH
;
8312 buf
[bp
++] = WEXT_PNO_MAX_REPEAT_SECTION
;
8313 os_snprintf(&buf
[bp
], WEXT_PNO_MAX_REPEAT_LENGTH
+ 1, "%x",
8314 WEXT_PNO_MAX_REPEAT
);
8315 bp
+= WEXT_PNO_MAX_REPEAT_LENGTH
+ 1;
8317 memset(&ifr
, 0, sizeof(ifr
));
8318 memset(&priv_cmd
, 0, sizeof(priv_cmd
));
8319 os_strncpy(ifr
.ifr_name
, bss
->ifname
, IFNAMSIZ
);
8322 priv_cmd
.used_len
= bp
;
8323 priv_cmd
.total_len
= bp
;
8324 ifr
.ifr_data
= &priv_cmd
;
8326 ret
= ioctl(drv
->global
->ioctl_sock
, SIOCDEVPRIVATE
+ 1, &ifr
);
8329 wpa_printf(MSG_ERROR
, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
8331 wpa_driver_send_hang_msg(drv
);
8337 return android_priv_cmd(bss
, "PNOFORCE 1");
8341 static int android_pno_stop(struct i802_bss
*bss
)
8343 return android_priv_cmd(bss
, "PNOFORCE 0");
8346 #endif /* ANDROID */
8349 const struct wpa_driver_ops wpa_driver_nl80211_ops
= {
8351 .desc
= "Linux nl80211/cfg80211",
8352 .get_bssid
= wpa_driver_nl80211_get_bssid
,
8353 .get_ssid
= wpa_driver_nl80211_get_ssid
,
8354 .set_key
= wpa_driver_nl80211_set_key
,
8355 .scan2
= wpa_driver_nl80211_scan
,
8356 .sched_scan
= wpa_driver_nl80211_sched_scan
,
8357 .stop_sched_scan
= wpa_driver_nl80211_stop_sched_scan
,
8358 .get_scan_results2
= wpa_driver_nl80211_get_scan_results
,
8359 .deauthenticate
= wpa_driver_nl80211_deauthenticate
,
8360 .disassociate
= wpa_driver_nl80211_disassociate
,
8361 .authenticate
= wpa_driver_nl80211_authenticate
,
8362 .associate
= wpa_driver_nl80211_associate
,
8363 .global_init
= nl80211_global_init
,
8364 .global_deinit
= nl80211_global_deinit
,
8365 .init2
= wpa_driver_nl80211_init
,
8366 .deinit
= wpa_driver_nl80211_deinit
,
8367 .get_capa
= wpa_driver_nl80211_get_capa
,
8368 .set_operstate
= wpa_driver_nl80211_set_operstate
,
8369 .set_supp_port
= wpa_driver_nl80211_set_supp_port
,
8370 .set_country
= wpa_driver_nl80211_set_country
,
8371 .set_ap
= wpa_driver_nl80211_set_ap
,
8372 .if_add
= wpa_driver_nl80211_if_add
,
8373 .if_remove
= wpa_driver_nl80211_if_remove
,
8374 .send_mlme
= wpa_driver_nl80211_send_mlme
,
8375 .get_hw_feature_data
= wpa_driver_nl80211_get_hw_feature_data
,
8376 .sta_add
= wpa_driver_nl80211_sta_add
,
8377 .sta_remove
= wpa_driver_nl80211_sta_remove
,
8378 .hapd_send_eapol
= wpa_driver_nl80211_hapd_send_eapol
,
8379 .sta_set_flags
= wpa_driver_nl80211_sta_set_flags
,
8381 .hapd_init
= i802_init
,
8382 .hapd_deinit
= i802_deinit
,
8383 .set_wds_sta
= i802_set_wds_sta
,
8384 #endif /* HOSTAPD */
8385 #if defined(HOSTAPD) || defined(CONFIG_AP)
8386 .get_seqnum
= i802_get_seqnum
,
8387 .flush
= i802_flush
,
8388 .read_sta_data
= i802_read_sta_data
,
8389 .get_inact_sec
= i802_get_inact_sec
,
8390 .sta_clear_stats
= i802_sta_clear_stats
,
8391 .set_rts
= i802_set_rts
,
8392 .set_frag
= i802_set_frag
,
8393 .set_tx_queue_params
= i802_set_tx_queue_params
,
8394 .set_sta_vlan
= i802_set_sta_vlan
,
8395 .sta_deauth
= i802_sta_deauth
,
8396 .sta_disassoc
= i802_sta_disassoc
,
8397 #endif /* HOSTAPD || CONFIG_AP */
8398 .set_freq
= i802_set_freq
,
8399 .send_action
= wpa_driver_nl80211_send_action
,
8400 .send_action_cancel_wait
= wpa_driver_nl80211_send_action_cancel_wait
,
8401 .remain_on_channel
= wpa_driver_nl80211_remain_on_channel
,
8402 .cancel_remain_on_channel
=
8403 wpa_driver_nl80211_cancel_remain_on_channel
,
8404 .probe_req_report
= wpa_driver_nl80211_probe_req_report
,
8405 .deinit_ap
= wpa_driver_nl80211_deinit_ap
,
8406 .resume
= wpa_driver_nl80211_resume
,
8407 .send_ft_action
= nl80211_send_ft_action
,
8408 .signal_monitor
= nl80211_signal_monitor
,
8409 .signal_poll
= nl80211_signal_poll
,
8410 .send_frame
= nl80211_send_frame
,
8411 .shared_freq
= wpa_driver_nl80211_shared_freq
,
8412 .set_param
= nl80211_set_param
,
8413 .get_radio_name
= nl80211_get_radio_name
,
8414 .add_pmkid
= nl80211_add_pmkid
,
8415 .remove_pmkid
= nl80211_remove_pmkid
,
8416 .flush_pmkid
= nl80211_flush_pmkid
,
8417 .set_rekey_info
= nl80211_set_rekey_info
,
8418 .poll_client
= nl80211_poll_client
,
8419 .set_p2p_powersave
= nl80211_set_p2p_powersave
,
8421 .send_tdls_mgmt
= nl80211_send_tdls_mgmt
,
8422 .tdls_oper
= nl80211_tdls_oper
,
8423 #endif /* CONFIG_TDLS */