2 * WPA Supplicant - driver interaction with Linux nl80211/cfg80211
3 * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
16 #include <sys/ioctl.h>
17 #include <net/if_arp.h>
18 #include <netlink/genl/genl.h>
19 #include <netlink/genl/family.h>
20 #include <netlink/genl/ctrl.h>
21 #include "nl80211_copy.h"
22 #include "wireless_copy.h"
27 #include "ieee802_11_defs.h"
30 #define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
33 #define IFF_DORMANT 0x20000 /* driver signals dormant */
36 #ifndef IF_OPER_DORMANT
37 #define IF_OPER_DORMANT 5
44 struct wpa_driver_nl80211_data {
48 char ifname[IFNAMSIZ + 1];
51 struct wpa_driver_capa capa;
56 int scan_complete_events;
58 struct nl_handle *nl_handle;
59 struct nl_cache *nl_cache;
61 struct genl_family *nl80211;
70 unsigned int beacon_set:1;
71 #endif /* CONFIG_AP */
75 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
77 static int wpa_driver_nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
80 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
84 static int ack_handler(struct nl_msg *msg, void *arg)
91 static int finish_handler(struct nl_msg *msg, void *arg)
98 static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
106 static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
108 int (*valid_handler)(struct nl_msg *, void *),
114 cb = nl_cb_clone(drv->nl_cb);
118 err = nl_send_auto_complete(drv->nl_handle, msg);
124 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
125 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
126 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
129 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
130 valid_handler, valid_data);
133 nl_recvmsgs(drv->nl_handle, cb);
147 static int family_handler(struct nl_msg *msg, void *arg)
149 struct family_data *res = arg;
150 struct nlattr *tb[CTRL_ATTR_MAX + 1];
151 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
152 struct nlattr *mcgrp;
155 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
156 genlmsg_attrlen(gnlh, 0), NULL);
157 if (!tb[CTRL_ATTR_MCAST_GROUPS])
160 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
161 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
162 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
163 nla_len(mcgrp), NULL);
164 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
165 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
166 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
168 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
170 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
178 static int nl_get_multicast_id(struct wpa_driver_nl80211_data *drv,
179 const char *family, const char *group)
183 struct family_data res = { group, -ENOENT };
188 genlmsg_put(msg, 0, 0, genl_ctrl_resolve(drv->nl_handle, "nlctrl"),
189 0, 0, CTRL_CMD_GETFAMILY, 0);
190 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
192 ret = send_and_recv_msgs(drv, msg, family_handler, &res);
203 static int wpa_driver_nl80211_send_oper_ifla(
204 struct wpa_driver_nl80211_data *drv,
205 int linkmode, int operstate)
209 struct ifinfomsg ifinfo;
216 os_memset(&req, 0, sizeof(req));
218 req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
219 req.hdr.nlmsg_type = RTM_SETLINK;
220 req.hdr.nlmsg_flags = NLM_F_REQUEST;
221 req.hdr.nlmsg_seq = ++nl_seq;
222 req.hdr.nlmsg_pid = 0;
224 req.ifinfo.ifi_family = AF_UNSPEC;
225 req.ifinfo.ifi_type = 0;
226 req.ifinfo.ifi_index = drv->ifindex;
227 req.ifinfo.ifi_flags = 0;
228 req.ifinfo.ifi_change = 0;
230 if (linkmode != -1) {
231 rta = (struct rtattr *)
232 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
233 rta->rta_type = IFLA_LINKMODE;
234 rta->rta_len = RTA_LENGTH(sizeof(char));
235 *((char *) RTA_DATA(rta)) = linkmode;
236 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
237 RTA_LENGTH(sizeof(char));
239 if (operstate != -1) {
240 rta = (struct rtattr *)
241 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
242 rta->rta_type = IFLA_OPERSTATE;
243 rta->rta_len = RTA_LENGTH(sizeof(char));
244 *((char *) RTA_DATA(rta)) = operstate;
245 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
246 RTA_LENGTH(sizeof(char));
249 wpa_printf(MSG_DEBUG, "WEXT: Operstate: linkmode=%d, operstate=%d",
250 linkmode, operstate);
252 ret = send(drv->link_event_sock, &req, req.hdr.nlmsg_len, 0);
254 wpa_printf(MSG_DEBUG, "WEXT: Sending operstate IFLA failed: "
255 "%s (assume operstate is not supported)",
259 return ret < 0 ? -1 : 0;
263 static int wpa_driver_nl80211_set_auth_param(
264 struct wpa_driver_nl80211_data *drv, int idx, u32 value)
269 os_memset(&iwr, 0, sizeof(iwr));
270 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
271 iwr.u.param.flags = idx & IW_AUTH_INDEX;
272 iwr.u.param.value = value;
274 if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) {
275 if (errno != EOPNOTSUPP) {
276 wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d "
277 "value 0x%x) failed: %s)",
278 idx, value, strerror(errno));
280 ret = errno == EOPNOTSUPP ? -2 : -1;
287 static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
289 struct wpa_driver_nl80211_data *drv = priv;
290 if (!drv->associated)
292 os_memcpy(bssid, drv->bssid, ETH_ALEN);
297 static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
299 struct wpa_driver_nl80211_data *drv = priv;
300 if (!drv->associated)
302 os_memcpy(ssid, drv->ssid, drv->ssid_len);
303 return drv->ssid_len;
307 static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
308 void *ctx, char *buf, size_t len,
311 union wpa_event_data event;
313 os_memset(&event, 0, sizeof(event));
314 if (len > sizeof(event.interface_status.ifname))
315 len = sizeof(event.interface_status.ifname) - 1;
316 os_memcpy(event.interface_status.ifname, buf, len);
317 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
318 EVENT_INTERFACE_ADDED;
320 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
322 event.interface_status.ifname,
323 del ? "removed" : "added");
325 if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
332 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
336 static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
339 struct ifinfomsg *ifi;
340 int attrlen, _nlmsg_len, rta_len;
345 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
347 attrlen = h->nlmsg_len - _nlmsg_len;
351 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
353 rta_len = RTA_ALIGN(sizeof(struct rtattr));
354 while (RTA_OK(attr, attrlen)) {
355 if (attr->rta_type == IFLA_IFNAME) {
356 if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
362 attr = RTA_NEXT(attr, attrlen);
369 static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
370 int ifindex, struct nlmsghdr *h)
372 if (drv->ifindex == ifindex)
375 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, h)) {
376 drv->ifindex = if_nametoindex(drv->ifname);
377 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
379 wpa_driver_nl80211_finish_drv_init(drv);
387 static void wpa_driver_nl80211_event_rtm_newlink(struct wpa_driver_nl80211_data *drv,
388 void *ctx, struct nlmsghdr *h,
391 struct ifinfomsg *ifi;
392 int attrlen, _nlmsg_len, rta_len;
393 struct rtattr * attr;
395 if (len < sizeof(*ifi))
400 if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, h)) {
401 wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
406 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
408 drv->operstate, ifi->ifi_flags,
409 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
410 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
411 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
412 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
414 * Some drivers send the association event before the operup event--in
415 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
416 * fails. This will hit us when wpa_supplicant does not need to do
417 * IEEE 802.1X authentication
419 if (drv->operstate == 1 &&
420 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
421 !(ifi->ifi_flags & IFF_RUNNING))
422 wpa_driver_nl80211_send_oper_ifla(drv, -1, IF_OPER_UP);
424 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
426 attrlen = h->nlmsg_len - _nlmsg_len;
430 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
432 rta_len = RTA_ALIGN(sizeof(struct rtattr));
433 while (RTA_OK(attr, attrlen)) {
434 if (attr->rta_type == IFLA_IFNAME) {
435 wpa_driver_nl80211_event_link(
437 ((char *) attr) + rta_len,
438 attr->rta_len - rta_len, 0);
440 attr = RTA_NEXT(attr, attrlen);
445 static void wpa_driver_nl80211_event_rtm_dellink(struct wpa_driver_nl80211_data *drv,
446 void *ctx, struct nlmsghdr *h,
449 struct ifinfomsg *ifi;
450 int attrlen, _nlmsg_len, rta_len;
451 struct rtattr * attr;
453 if (len < sizeof(*ifi))
458 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
460 attrlen = h->nlmsg_len - _nlmsg_len;
464 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
466 rta_len = RTA_ALIGN(sizeof(struct rtattr));
467 while (RTA_OK(attr, attrlen)) {
468 if (attr->rta_type == IFLA_IFNAME) {
469 wpa_driver_nl80211_event_link(
471 ((char *) attr) + rta_len,
472 attr->rta_len - rta_len, 1);
474 attr = RTA_NEXT(attr, attrlen);
479 static void wpa_driver_nl80211_event_receive_link(int sock, void *eloop_ctx,
484 struct sockaddr_nl from;
490 fromlen = sizeof(from);
491 left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
492 (struct sockaddr *) &from, &fromlen);
494 if (errno != EINTR && errno != EAGAIN)
495 perror("recvfrom(netlink)");
499 h = (struct nlmsghdr *) buf;
500 while (left >= (int) sizeof(*h)) {
504 plen = len - sizeof(*h);
505 if (len > left || plen < 0) {
506 wpa_printf(MSG_DEBUG, "Malformed netlink message: "
507 "len=%d left=%d plen=%d",
512 switch (h->nlmsg_type) {
514 wpa_driver_nl80211_event_rtm_newlink(eloop_ctx, sock_ctx,
518 wpa_driver_nl80211_event_rtm_dellink(eloop_ctx, sock_ctx,
523 len = NLMSG_ALIGN(len);
525 h = (struct nlmsghdr *) ((char *) h + len);
529 wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "
533 if (--max_events > 0) {
535 * Try to receive all events in one eloop call in order to
536 * limit race condition on cases where AssocInfo event, Assoc
537 * event, and EAPOL frames are received more or less at the
538 * same time. We want to process the event messages first
539 * before starting EAPOL processing.
546 static int no_seq_check(struct nl_msg *msg, void *arg)
552 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
553 const u8 *frame, size_t len)
555 const struct ieee80211_mgmt *mgmt;
556 union wpa_event_data event;
558 mgmt = (const struct ieee80211_mgmt *) frame;
559 if (len < 24 + sizeof(mgmt->u.auth)) {
560 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
565 os_memset(&event, 0, sizeof(event));
566 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
567 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
568 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
569 if (len > 24 + sizeof(mgmt->u.auth)) {
570 event.auth.ies = mgmt->u.auth.variable;
571 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
574 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
578 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
579 const u8 *frame, size_t len)
581 const struct ieee80211_mgmt *mgmt;
582 union wpa_event_data event;
585 mgmt = (const struct ieee80211_mgmt *) frame;
586 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
587 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
592 status = le_to_host16(mgmt->u.assoc_resp.status_code);
593 if (status != WLAN_STATUS_SUCCESS) {
594 os_memset(&event, 0, sizeof(event));
595 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
596 event.assoc_reject.resp_ies =
597 (u8 *) mgmt->u.assoc_resp.variable;
598 event.assoc_reject.resp_ies_len =
599 len - 24 - sizeof(mgmt->u.assoc_resp);
601 event.assoc_reject.status_code = status;
603 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
608 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
610 os_memset(&event, 0, sizeof(event));
611 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
612 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
613 event.assoc_info.resp_ies_len =
614 len - 24 - sizeof(mgmt->u.assoc_resp);
617 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
621 static void mlme_event(struct wpa_driver_nl80211_data *drv,
622 enum nl80211_commands cmd, struct nlattr *frame)
625 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
630 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d", cmd);
631 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
632 nla_data(frame), nla_len(frame));
635 case NL80211_CMD_AUTHENTICATE:
636 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
638 case NL80211_CMD_ASSOCIATE:
639 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
641 case NL80211_CMD_DEAUTHENTICATE:
643 wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, NULL);
645 case NL80211_CMD_DISASSOCIATE:
647 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
655 static int process_event(struct nl_msg *msg, void *arg)
657 struct wpa_driver_nl80211_data *drv = arg;
658 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
659 struct nlattr *tb[NL80211_ATTR_MAX + 1];
661 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
662 genlmsg_attrlen(gnlh, 0), NULL);
664 if (tb[NL80211_ATTR_IFINDEX]) {
665 int ifindex = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
666 if (ifindex != drv->ifindex) {
667 wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d)"
668 " for foreign interface (ifindex %d)",
675 case NL80211_CMD_NEW_SCAN_RESULTS:
676 wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
677 drv->scan_complete_events = 1;
678 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
680 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
682 case NL80211_CMD_SCAN_ABORTED:
683 wpa_printf(MSG_DEBUG, "nl80211: Scan aborted");
685 * Need to indicate that scan results are available in order
686 * not to make wpa_supplicant stop its scanning.
688 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
690 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
692 case NL80211_CMD_AUTHENTICATE:
693 case NL80211_CMD_ASSOCIATE:
694 case NL80211_CMD_DEAUTHENTICATE:
695 case NL80211_CMD_DISASSOCIATE:
696 mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]);
699 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
700 "(cmd=%d)", gnlh->cmd);
708 static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
712 struct wpa_driver_nl80211_data *drv = eloop_ctx;
714 wpa_printf(MSG_DEBUG, "nl80211: Event message available");
716 cb = nl_cb_clone(drv->nl_cb);
719 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
720 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv);
721 nl_recvmsgs(drv->nl_handle, cb);
726 static int wpa_driver_nl80211_get_ifflags_ifname(struct wpa_driver_nl80211_data *drv,
727 const char *ifname, int *flags)
731 os_memset(&ifr, 0, sizeof(ifr));
732 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
733 if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
734 perror("ioctl[SIOCGIFFLAGS]");
737 *flags = ifr.ifr_flags & 0xffff;
743 * wpa_driver_nl80211_get_ifflags - Get interface flags (SIOCGIFFLAGS)
744 * @drv: driver_nl80211 private data
745 * @flags: Pointer to returned flags value
746 * Returns: 0 on success, -1 on failure
748 static int wpa_driver_nl80211_get_ifflags(struct wpa_driver_nl80211_data *drv,
751 return wpa_driver_nl80211_get_ifflags_ifname(drv, drv->ifname, flags);
755 static int wpa_driver_nl80211_set_ifflags_ifname(
756 struct wpa_driver_nl80211_data *drv,
757 const char *ifname, int flags)
761 os_memset(&ifr, 0, sizeof(ifr));
762 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
763 ifr.ifr_flags = flags & 0xffff;
764 if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
765 perror("SIOCSIFFLAGS");
773 * wpa_driver_nl80211_set_ifflags - Set interface flags (SIOCSIFFLAGS)
774 * @drv: driver_nl80211 private data
775 * @flags: New value for flags
776 * Returns: 0 on success, -1 on failure
778 static int wpa_driver_nl80211_set_ifflags(struct wpa_driver_nl80211_data *drv,
781 return wpa_driver_nl80211_set_ifflags_ifname(drv, drv->ifname, flags);
786 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
787 * @priv: driver_nl80211 private data
788 * @alpha2_arg: country to which to switch to
789 * Returns: 0 on success, -1 on failure
791 * This asks nl80211 to set the regulatory domain for given
792 * country ISO / IEC alpha2.
794 static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
796 struct wpa_driver_nl80211_data *drv = priv;
802 goto nla_put_failure;
804 alpha2[0] = alpha2_arg[0];
805 alpha2[1] = alpha2_arg[1];
808 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
809 0, NL80211_CMD_REQ_SET_REG, 0);
811 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
812 if (send_and_recv_msgs(drv, msg, NULL, NULL))
820 struct wiphy_info_data {
826 static int wiphy_info_handler(struct nl_msg *msg, void *arg)
828 struct nlattr *tb[NL80211_ATTR_MAX + 1];
829 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
830 struct wiphy_info_data *info = arg;
832 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
833 genlmsg_attrlen(gnlh, 0), NULL);
835 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
836 info->max_scan_ssids =
837 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
839 if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
840 struct nlattr *nl_mode;
842 nla_for_each_nested(nl_mode,
843 tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
844 if (nl_mode->nla_type == NL80211_IFTYPE_AP) {
845 info->ap_supported = 1;
855 static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
856 struct wiphy_info_data *info)
860 os_memset(info, 0, sizeof(*info));
865 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
866 0, NL80211_CMD_GET_WIPHY, 0);
868 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
870 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
879 static void wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
881 struct wiphy_info_data info;
882 if (wpa_driver_nl80211_get_info(drv, &info))
884 drv->has_capability = 1;
885 /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
886 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
887 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
888 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
889 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
890 drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 |
891 WPA_DRIVER_CAPA_ENC_WEP104 |
892 WPA_DRIVER_CAPA_ENC_TKIP |
893 WPA_DRIVER_CAPA_ENC_CCMP;
895 drv->capa.max_scan_ssids = info.max_scan_ssids;
896 if (info.ap_supported)
897 drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
902 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
903 * @ctx: context to be used when calling wpa_supplicant functions,
904 * e.g., wpa_supplicant_event()
905 * @ifname: interface name, e.g., wlan0
906 * Returns: Pointer to private data, %NULL on failure
908 static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
911 struct sockaddr_nl local;
912 struct wpa_driver_nl80211_data *drv;
914 drv = os_zalloc(sizeof(*drv));
918 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
920 drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
921 if (drv->nl_cb == NULL) {
922 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
927 drv->nl_handle = nl_handle_alloc_cb(drv->nl_cb);
928 if (drv->nl_handle == NULL) {
929 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
934 if (genl_connect(drv->nl_handle)) {
935 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
940 drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);
941 if (drv->nl_cache == NULL) {
942 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
947 drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");
948 if (drv->nl80211 == NULL) {
949 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
954 ret = nl_get_multicast_id(drv, "nl80211", "scan");
956 ret = nl_socket_add_membership(drv->nl_handle, ret);
958 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
959 "membership for scan events: %d (%s)",
960 ret, strerror(-ret));
964 ret = nl_get_multicast_id(drv, "nl80211", "mlme");
966 ret = nl_socket_add_membership(drv->nl_handle, ret);
968 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
969 "membership for mlme events: %d (%s)",
970 ret, strerror(-ret));
973 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
975 eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle),
976 wpa_driver_nl80211_event_receive, drv, ctx);
978 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
979 if (drv->ioctl_sock < 0) {
980 perror("socket(PF_INET,SOCK_DGRAM)");
984 s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
986 perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
990 os_memset(&local, 0, sizeof(local));
991 local.nl_family = AF_NETLINK;
992 local.nl_groups = RTMGRP_LINK;
993 if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
994 perror("bind(netlink)");
999 eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_link, drv,
1001 drv->link_event_sock = s;
1003 if (wpa_driver_nl80211_finish_drv_init(drv))
1009 eloop_unregister_read_sock(drv->link_event_sock);
1010 close(drv->link_event_sock);
1012 close(drv->ioctl_sock);
1014 genl_family_put(drv->nl80211);
1016 nl_cache_free(drv->nl_cache);
1018 nl_handle_destroy(drv->nl_handle);
1020 nl_cb_put(drv->nl_cb);
1028 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
1032 drv->ifindex = if_nametoindex(drv->ifname);
1034 if (wpa_driver_nl80211_set_mode(drv, 0) < 0) {
1035 wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
1036 "use managed mode");
1039 if (wpa_driver_nl80211_get_ifflags(drv, &flags) != 0) {
1040 wpa_printf(MSG_ERROR, "Could not get interface '%s' flags",
1044 if (!(flags & IFF_UP)) {
1045 if (wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP) != 0) {
1046 wpa_printf(MSG_ERROR, "Could not set interface '%s' "
1052 wpa_driver_nl80211_capa(drv);
1054 wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
1061 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
1062 * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
1064 * Shut down driver interface and processing of driver events. Free
1065 * private data buffer if one was allocated in wpa_driver_nl80211_init().
1067 static void wpa_driver_nl80211_deinit(void *priv)
1069 struct wpa_driver_nl80211_data *drv = priv;
1072 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
1074 wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED, 0);
1076 wpa_driver_nl80211_send_oper_ifla(priv, 0, IF_OPER_UP);
1078 eloop_unregister_read_sock(drv->link_event_sock);
1080 if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0)
1081 (void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);
1082 wpa_driver_nl80211_set_mode(drv, 0);
1084 close(drv->link_event_sock);
1085 close(drv->ioctl_sock);
1087 eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle));
1088 genl_family_put(drv->nl80211);
1089 nl_cache_free(drv->nl_cache);
1090 nl_handle_destroy(drv->nl_handle);
1091 nl_cb_put(drv->nl_cb);
1098 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
1099 * @eloop_ctx: Unused
1100 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
1102 * This function can be used as registered timeout when starting a scan to
1103 * generate a scan completed event if the driver does not report this.
1105 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1107 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
1108 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
1113 * wpa_driver_nl80211_scan - Request the driver to initiate scan
1114 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
1115 * @params: Scan parameters
1116 * Returns: 0 on success, -1 on failure
1118 static int wpa_driver_nl80211_scan(void *priv,
1119 struct wpa_driver_scan_params *params)
1121 struct wpa_driver_nl80211_data *drv = priv;
1122 int ret = 0, timeout;
1123 struct nl_msg *msg, *ssids, *freqs;
1126 msg = nlmsg_alloc();
1127 ssids = nlmsg_alloc();
1128 freqs = nlmsg_alloc();
1129 if (!msg || !ssids || !freqs) {
1136 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1137 NL80211_CMD_TRIGGER_SCAN, 0);
1139 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1141 for (i = 0; i < params->num_ssids; i++) {
1142 NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
1143 params->ssids[i].ssid);
1145 if (params->num_ssids)
1146 nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
1148 if (params->extra_ies) {
1149 NLA_PUT(msg, NL80211_ATTR_IE, params->extra_ies_len,
1153 if (params->freqs) {
1154 for (i = 0; params->freqs[i]; i++)
1155 NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
1156 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
1159 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1162 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
1163 "(%s)", ret, strerror(-ret));
1164 goto nla_put_failure;
1167 /* Not all drivers generate "scan completed" wireless event, so try to
1168 * read results after a timeout. */
1170 if (drv->scan_complete_events) {
1172 * The driver seems to deliver events to notify when scan is
1173 * complete, so use longer timeout to avoid race conditions
1174 * with scanning and following association request.
1178 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
1179 "seconds", ret, timeout);
1180 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
1181 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
1192 static int bss_info_handler(struct nl_msg *msg, void *arg)
1194 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1195 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1196 struct nlattr *bss[NL80211_BSS_MAX + 1];
1197 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
1198 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
1199 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
1200 [NL80211_BSS_TSF] = { .type = NLA_U64 },
1201 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
1202 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
1203 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
1204 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
1205 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
1207 struct wpa_scan_results *res = arg;
1208 struct wpa_scan_res **tmp;
1209 struct wpa_scan_res *r;
1213 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1214 genlmsg_attrlen(gnlh, 0), NULL);
1215 if (!tb[NL80211_ATTR_BSS])
1217 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
1220 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
1221 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1222 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1228 r = os_zalloc(sizeof(*r) + ie_len);
1231 if (bss[NL80211_BSS_BSSID])
1232 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
1234 if (bss[NL80211_BSS_FREQUENCY])
1235 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
1236 if (bss[NL80211_BSS_BEACON_INTERVAL])
1237 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
1238 if (bss[NL80211_BSS_CAPABILITY])
1239 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
1240 r->flags |= WPA_SCAN_NOISE_INVALID;
1241 if (bss[NL80211_BSS_SIGNAL_MBM]) {
1242 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
1243 r->level /= 100; /* mBm to dBm */
1244 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
1245 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
1246 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
1247 r->flags |= WPA_SCAN_LEVEL_INVALID;
1249 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
1250 if (bss[NL80211_BSS_TSF])
1251 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
1254 os_memcpy(r + 1, ie, ie_len);
1256 tmp = os_realloc(res->res,
1257 (res->num + 1) * sizeof(struct wpa_scan_res *));
1262 tmp[res->num++] = r;
1270 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
1271 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
1272 * Returns: Scan results on success, -1 on failure
1274 static struct wpa_scan_results *
1275 wpa_driver_nl80211_get_scan_results(void *priv)
1277 struct wpa_driver_nl80211_data *drv = priv;
1279 struct wpa_scan_results *res;
1282 res = os_zalloc(sizeof(*res));
1285 msg = nlmsg_alloc();
1287 goto nla_put_failure;
1289 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP,
1290 NL80211_CMD_GET_SCAN, 0);
1291 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1293 ret = send_and_recv_msgs(drv, msg, bss_info_handler, res);
1296 wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)",
1297 (unsigned long) res->num);
1300 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1301 "(%s)", ret, strerror(-ret));
1304 wpa_scan_results_free(res);
1309 static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg,
1310 const u8 *addr, int key_idx,
1311 int set_tx, const u8 *seq,
1313 const u8 *key, size_t key_len)
1315 struct wpa_driver_nl80211_data *drv = priv;
1319 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
1320 "seq_len=%lu key_len=%lu",
1321 __func__, alg, addr, key_idx, set_tx,
1322 (unsigned long) seq_len, (unsigned long) key_len);
1324 msg = nlmsg_alloc();
1328 if (alg == WPA_ALG_NONE) {
1329 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1330 NL80211_CMD_DEL_KEY, 0);
1332 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1333 NL80211_CMD_NEW_KEY, 0);
1334 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
1338 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1341 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1345 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02);
1348 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);
1350 #ifdef CONFIG_IEEE80211W
1352 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC06);
1354 #endif /* CONFIG_IEEE80211W */
1361 if (addr && os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
1363 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
1364 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1366 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1367 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1369 err = send_and_recv_msgs(drv, msg, NULL, NULL);
1371 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d", err);
1375 if (set_tx && alg != WPA_ALG_NONE) {
1376 msg = nlmsg_alloc();
1380 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1381 0, NL80211_CMD_SET_KEY, 0);
1382 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1383 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1384 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
1386 err = send_and_recv_msgs(drv, msg, NULL, NULL);
1388 wpa_printf(MSG_DEBUG, "nl80211: set default key "
1389 "failed; err=%d", err);
1401 static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
1402 const u8 *addr, int cmd, u16 reason_code)
1407 msg = nlmsg_alloc();
1411 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, cmd, 0);
1413 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1414 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
1415 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1417 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1420 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
1421 "(%s)", ret, strerror(-ret));
1422 goto nla_put_failure;
1432 static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,
1435 struct wpa_driver_nl80211_data *drv = priv;
1436 wpa_printf(MSG_DEBUG, "%s", __func__);
1437 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
1442 static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,
1445 struct wpa_driver_nl80211_data *drv = priv;
1446 wpa_printf(MSG_DEBUG, "%s", __func__);
1447 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISASSOCIATE,
1452 static int wpa_driver_nl80211_authenticate(
1453 void *priv, struct wpa_driver_auth_params *params)
1455 struct wpa_driver_nl80211_data *drv = priv;
1458 enum nl80211_auth_type type;
1460 drv->associated = 0;
1462 msg = nlmsg_alloc();
1466 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
1468 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1469 NL80211_CMD_AUTHENTICATE, 0);
1471 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1472 if (params->bssid) {
1473 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
1474 MAC2STR(params->bssid));
1475 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
1478 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
1479 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
1482 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
1483 params->ssid, params->ssid_len);
1484 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
1487 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
1489 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
1491 * TODO: if multiple auth_alg options enabled, try them one by one if
1492 * the AP rejects authentication due to unknown auth alg
1494 if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
1495 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1496 else if (params->auth_alg & AUTH_ALG_SHARED_KEY)
1497 type = NL80211_AUTHTYPE_SHARED_KEY;
1498 else if (params->auth_alg & AUTH_ALG_LEAP)
1499 type = NL80211_AUTHTYPE_NETWORK_EAP;
1500 else if (params->auth_alg & AUTH_ALG_FT)
1501 type = NL80211_AUTHTYPE_FT;
1503 goto nla_put_failure;
1504 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
1505 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
1507 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1510 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
1511 "(%s)", ret, strerror(-ret));
1512 goto nla_put_failure;
1515 wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
1525 static int wpa_driver_nl80211_set_beacon(void *priv,
1526 const u8 *head, size_t head_len,
1527 const u8 *tail, size_t tail_len,
1530 struct wpa_driver_nl80211_data *drv = priv;
1532 u8 cmd = NL80211_CMD_NEW_BEACON;
1535 msg = nlmsg_alloc();
1539 wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
1541 if (drv->beacon_set)
1542 cmd = NL80211_CMD_SET_BEACON;
1544 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1546 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);
1547 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);
1548 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1549 if (!drv->beacon_int)
1550 drv->beacon_int = 100;
1551 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, drv->beacon_int);
1552 NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, dtim_period);
1554 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1556 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
1557 ret, strerror(-ret));
1559 drv->beacon_set = 1;
1566 static int wpa_driver_nl80211_set_beacon_int(void *priv, int value)
1568 struct wpa_driver_nl80211_data *drv = priv;
1571 drv->beacon_int = value;
1573 if (!drv->beacon_set)
1576 msg = nlmsg_alloc();
1580 wpa_printf(MSG_DEBUG, "nl80211: Set beacon interval %d "
1581 "(beacon_set=%d)", value, drv->beacon_set);
1582 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1583 0, NL80211_CMD_SET_BEACON, 0);
1584 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1586 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, value);
1588 return send_and_recv_msgs(drv, msg, NULL, NULL);
1594 static int wpa_driver_nl80211_set_freq2(
1595 struct wpa_driver_nl80211_data *drv,
1596 struct wpa_driver_associate_params *params)
1601 msg = nlmsg_alloc();
1605 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1606 NL80211_CMD_SET_WIPHY, 0);
1608 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1610 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
1612 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1615 wpa_printf(MSG_DEBUG, "nl80211: MLME Failed to set channel (freq=%d): "
1616 "%d (%s)", params->freq, ret, strerror(-ret));
1622 static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
1623 struct wpa_driver_associate_params *params)
1625 if (wpa_driver_nl80211_set_mode(drv, params->mode) ||
1626 wpa_driver_nl80211_set_freq2(drv, params))
1629 /* TODO: setup monitor interface (and add code somewhere to remove this
1630 * when AP mode is stopped; associate with mode != 2 or drv_deinit) */
1634 #endif /* CONFIG_AP */
1637 static int wpa_driver_nl80211_associate(
1638 void *priv, struct wpa_driver_associate_params *params)
1640 struct wpa_driver_nl80211_data *drv = priv;
1645 if (params->mode == 2)
1646 return wpa_driver_nl80211_ap(drv, params);
1647 #endif /* CONFIG_AP */
1649 wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
1650 params->drop_unencrypted);
1652 drv->associated = 0;
1654 msg = nlmsg_alloc();
1658 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
1660 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1661 NL80211_CMD_ASSOCIATE, 0);
1663 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1664 if (params->bssid) {
1665 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
1666 MAC2STR(params->bssid));
1667 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
1670 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
1671 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
1674 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
1675 params->ssid, params->ssid_len);
1676 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
1678 if (params->ssid_len > sizeof(drv->ssid))
1679 goto nla_put_failure;
1680 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
1681 drv->ssid_len = params->ssid_len;
1683 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
1685 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
1688 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1691 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
1692 "(%s)", ret, strerror(-ret));
1693 goto nla_put_failure;
1696 wpa_printf(MSG_DEBUG, "nl80211: Association request send "
1706 * wpa_driver_nl80211_set_mode - Set wireless mode (infra/adhoc)
1707 * @drv: Pointer to private driver data from wpa_driver_nl80211_init()
1708 * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS
1709 * Returns: 0 on success, -1 on failure
1711 static int wpa_driver_nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
1714 int ret = -1, flags;
1720 nlmode = NL80211_IFTYPE_STATION;
1723 nlmode = NL80211_IFTYPE_ADHOC;
1726 nlmode = NL80211_IFTYPE_AP;
1732 msg = nlmsg_alloc();
1736 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1737 0, NL80211_CMD_SET_INTERFACE, 0);
1738 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1739 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, nlmode);
1741 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1748 wpa_printf(MSG_ERROR, "nl80211: Failed to set interface mode: %d (%s)",
1749 ret, strerror(-ret));
1753 /* mac80211 doesn't allow mode changes while the device is up, so
1754 * take the device down, try to set the mode again, and bring the
1757 if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0) {
1758 (void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);
1760 /* Try to set the mode again while the interface is down */
1761 msg = nlmsg_alloc();
1765 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1766 0, NL80211_CMD_SET_INTERFACE, 0);
1767 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1768 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, nlmode);
1769 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1771 wpa_printf(MSG_ERROR, "Failed to set interface %s "
1772 "mode(try_again): %d (%s)",
1773 drv->ifname, ret, strerror(-ret));
1776 /* Ignore return value of get_ifflags to ensure that the device
1777 * is always up like it was before this function was called.
1779 (void) wpa_driver_nl80211_get_ifflags(drv, &flags);
1780 (void) wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP);
1787 static int wpa_driver_nl80211_get_capa(void *priv,
1788 struct wpa_driver_capa *capa)
1790 struct wpa_driver_nl80211_data *drv = priv;
1791 if (!drv->has_capability)
1793 os_memcpy(capa, &drv->capa, sizeof(*capa));
1798 static int wpa_driver_nl80211_set_operstate(void *priv, int state)
1800 struct wpa_driver_nl80211_data *drv = priv;
1802 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
1803 __func__, drv->operstate, state, state ? "UP" : "DORMANT");
1804 drv->operstate = state;
1805 return wpa_driver_nl80211_send_oper_ifla(
1806 drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT);
1810 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
1812 .desc = "Linux nl80211/cfg80211",
1813 .get_bssid = wpa_driver_nl80211_get_bssid,
1814 .get_ssid = wpa_driver_nl80211_get_ssid,
1815 .set_key = wpa_driver_nl80211_set_key,
1816 .scan2 = wpa_driver_nl80211_scan,
1817 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
1818 .deauthenticate = wpa_driver_nl80211_deauthenticate,
1819 .disassociate = wpa_driver_nl80211_disassociate,
1820 .authenticate = wpa_driver_nl80211_authenticate,
1821 .associate = wpa_driver_nl80211_associate,
1822 .init = wpa_driver_nl80211_init,
1823 .deinit = wpa_driver_nl80211_deinit,
1824 .get_capa = wpa_driver_nl80211_get_capa,
1825 .set_operstate = wpa_driver_nl80211_set_operstate,
1826 .set_country = wpa_driver_nl80211_set_country,
1828 .set_beacon = wpa_driver_nl80211_set_beacon,
1829 .set_beacon_int = wpa_driver_nl80211_set_beacon_int,
1830 #endif /* CONFIG_AP */