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;
53 int we_version_compiled;
57 char mlmedev[IFNAMSIZ + 1];
59 int scan_complete_events;
61 struct nl_handle *nl_handle;
62 struct nl_cache *nl_cache;
64 struct genl_family *nl80211;
73 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
75 static int wpa_driver_nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
77 static int wpa_driver_nl80211_get_range(void *priv);
79 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
83 static int ack_handler(struct nl_msg *msg, void *arg)
90 static int finish_handler(struct nl_msg *msg, void *arg)
97 static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
105 static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
107 int (*valid_handler)(struct nl_msg *, void *),
113 cb = nl_cb_clone(drv->nl_cb);
117 err = nl_send_auto_complete(drv->nl_handle, msg);
123 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
124 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
125 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
128 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
129 valid_handler, valid_data);
132 nl_recvmsgs(drv->nl_handle, cb);
146 static int family_handler(struct nl_msg *msg, void *arg)
148 struct family_data *res = arg;
149 struct nlattr *tb[CTRL_ATTR_MAX + 1];
150 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
151 struct nlattr *mcgrp;
154 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
155 genlmsg_attrlen(gnlh, 0), NULL);
156 if (!tb[CTRL_ATTR_MCAST_GROUPS])
159 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
160 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
161 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
162 nla_len(mcgrp), NULL);
163 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
164 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
165 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
167 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
169 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
177 static int nl_get_multicast_id(struct wpa_driver_nl80211_data *drv,
178 const char *family, const char *group)
182 struct family_data res = { group, -ENOENT };
187 genlmsg_put(msg, 0, 0, genl_ctrl_resolve(drv->nl_handle, "nlctrl"),
188 0, 0, CTRL_CMD_GETFAMILY, 0);
189 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
191 ret = send_and_recv_msgs(drv, msg, family_handler, &res);
202 static int wpa_driver_nl80211_send_oper_ifla(
203 struct wpa_driver_nl80211_data *drv,
204 int linkmode, int operstate)
208 struct ifinfomsg ifinfo;
215 os_memset(&req, 0, sizeof(req));
217 req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
218 req.hdr.nlmsg_type = RTM_SETLINK;
219 req.hdr.nlmsg_flags = NLM_F_REQUEST;
220 req.hdr.nlmsg_seq = ++nl_seq;
221 req.hdr.nlmsg_pid = 0;
223 req.ifinfo.ifi_family = AF_UNSPEC;
224 req.ifinfo.ifi_type = 0;
225 req.ifinfo.ifi_index = drv->ifindex;
226 req.ifinfo.ifi_flags = 0;
227 req.ifinfo.ifi_change = 0;
229 if (linkmode != -1) {
230 rta = (struct rtattr *)
231 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
232 rta->rta_type = IFLA_LINKMODE;
233 rta->rta_len = RTA_LENGTH(sizeof(char));
234 *((char *) RTA_DATA(rta)) = linkmode;
235 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
236 RTA_LENGTH(sizeof(char));
238 if (operstate != -1) {
239 rta = (struct rtattr *)
240 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
241 rta->rta_type = IFLA_OPERSTATE;
242 rta->rta_len = RTA_LENGTH(sizeof(char));
243 *((char *) RTA_DATA(rta)) = operstate;
244 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
245 RTA_LENGTH(sizeof(char));
248 wpa_printf(MSG_DEBUG, "WEXT: Operstate: linkmode=%d, operstate=%d",
249 linkmode, operstate);
251 ret = send(drv->wext_event_sock, &req, req.hdr.nlmsg_len, 0);
253 wpa_printf(MSG_DEBUG, "WEXT: Sending operstate IFLA failed: "
254 "%s (assume operstate is not supported)",
258 return ret < 0 ? -1 : 0;
262 static int wpa_driver_nl80211_set_auth_param(
263 struct wpa_driver_nl80211_data *drv, int idx, u32 value)
268 os_memset(&iwr, 0, sizeof(iwr));
269 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
270 iwr.u.param.flags = idx & IW_AUTH_INDEX;
271 iwr.u.param.value = value;
273 if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) {
274 if (errno != EOPNOTSUPP) {
275 wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d "
276 "value 0x%x) failed: %s)",
277 idx, value, strerror(errno));
279 ret = errno == EOPNOTSUPP ? -2 : -1;
286 static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
288 struct wpa_driver_nl80211_data *drv = priv;
289 if (!drv->associated)
291 os_memcpy(bssid, drv->bssid, ETH_ALEN);
296 static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
298 struct wpa_driver_nl80211_data *drv = priv;
299 if (!drv->associated)
301 os_memcpy(ssid, drv->ssid, drv->ssid_len);
302 return drv->ssid_len;
306 static int wpa_driver_nl80211_event_wireless_michaelmicfailure(
307 void *ctx, const char *ev, size_t len)
309 const struct iw_michaelmicfailure *mic;
310 union wpa_event_data data;
312 if (len < sizeof(*mic))
315 mic = (const struct iw_michaelmicfailure *) ev;
317 wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: "
318 "flags=0x%x src_addr=" MACSTR, mic->flags,
319 MAC2STR(mic->src_addr.sa_data));
321 os_memset(&data, 0, sizeof(data));
322 data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP);
323 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
329 static void wpa_driver_nl80211_event_wireless(struct wpa_driver_nl80211_data *drv,
330 void *ctx, char *data, int len)
332 struct iw_event iwe_buf, *iwe = &iwe_buf;
333 char *pos, *end, *custom;
338 while (pos + IW_EV_LCP_LEN <= end) {
339 /* Event data may be unaligned, so make a local, aligned copy
340 * before processing. */
341 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
342 wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d",
344 if (iwe->len <= IW_EV_LCP_LEN)
347 custom = pos + IW_EV_POINT_LEN;
348 if (drv->we_version_compiled > 18 &&
349 (iwe->cmd == IWEVMICHAELMICFAILURE ||
350 iwe->cmd == IWEVCUSTOM ||
351 iwe->cmd == IWEVASSOCREQIE ||
352 iwe->cmd == IWEVASSOCRESPIE ||
353 iwe->cmd == IWEVPMKIDCAND)) {
354 /* WE-19 removed the pointer from struct iw_point */
355 char *dpos = (char *) &iwe_buf.u.data.length;
356 int dlen = dpos - (char *) &iwe_buf;
357 os_memcpy(dpos, pos + IW_EV_LCP_LEN,
358 sizeof(struct iw_event) - dlen);
360 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
361 custom += IW_EV_POINT_OFF;
365 case IWEVMICHAELMICFAILURE:
366 wpa_driver_nl80211_event_wireless_michaelmicfailure(
367 ctx, custom, iwe->u.data.length);
376 static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
377 void *ctx, char *buf, size_t len,
380 union wpa_event_data event;
382 os_memset(&event, 0, sizeof(event));
383 if (len > sizeof(event.interface_status.ifname))
384 len = sizeof(event.interface_status.ifname) - 1;
385 os_memcpy(event.interface_status.ifname, buf, len);
386 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
387 EVENT_INTERFACE_ADDED;
389 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
391 event.interface_status.ifname,
392 del ? "removed" : "added");
394 if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
401 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
405 static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
408 struct ifinfomsg *ifi;
409 int attrlen, _nlmsg_len, rta_len;
414 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
416 attrlen = h->nlmsg_len - _nlmsg_len;
420 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
422 rta_len = RTA_ALIGN(sizeof(struct rtattr));
423 while (RTA_OK(attr, attrlen)) {
424 if (attr->rta_type == IFLA_IFNAME) {
425 if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
431 attr = RTA_NEXT(attr, attrlen);
438 static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
439 int ifindex, struct nlmsghdr *h)
441 if (drv->ifindex == ifindex)
444 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, h)) {
445 drv->ifindex = if_nametoindex(drv->ifname);
446 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
448 wpa_driver_nl80211_finish_drv_init(drv);
456 static void wpa_driver_nl80211_event_rtm_newlink(struct wpa_driver_nl80211_data *drv,
457 void *ctx, struct nlmsghdr *h,
460 struct ifinfomsg *ifi;
461 int attrlen, _nlmsg_len, rta_len;
462 struct rtattr * attr;
464 if (len < sizeof(*ifi))
469 if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, h)) {
470 wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
475 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
477 drv->operstate, ifi->ifi_flags,
478 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
479 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
480 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
481 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
483 * Some drivers send the association event before the operup event--in
484 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
485 * fails. This will hit us when wpa_supplicant does not need to do
486 * IEEE 802.1X authentication
488 if (drv->operstate == 1 &&
489 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
490 !(ifi->ifi_flags & IFF_RUNNING))
491 wpa_driver_nl80211_send_oper_ifla(drv, -1, IF_OPER_UP);
493 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
495 attrlen = h->nlmsg_len - _nlmsg_len;
499 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
501 rta_len = RTA_ALIGN(sizeof(struct rtattr));
502 while (RTA_OK(attr, attrlen)) {
503 if (attr->rta_type == IFLA_WIRELESS) {
504 wpa_driver_nl80211_event_wireless(
505 drv, ctx, ((char *) attr) + rta_len,
506 attr->rta_len - rta_len);
507 } else if (attr->rta_type == IFLA_IFNAME) {
508 wpa_driver_nl80211_event_link(
510 ((char *) attr) + rta_len,
511 attr->rta_len - rta_len, 0);
513 attr = RTA_NEXT(attr, attrlen);
518 static void wpa_driver_nl80211_event_rtm_dellink(struct wpa_driver_nl80211_data *drv,
519 void *ctx, struct nlmsghdr *h,
522 struct ifinfomsg *ifi;
523 int attrlen, _nlmsg_len, rta_len;
524 struct rtattr * attr;
526 if (len < sizeof(*ifi))
531 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
533 attrlen = h->nlmsg_len - _nlmsg_len;
537 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
539 rta_len = RTA_ALIGN(sizeof(struct rtattr));
540 while (RTA_OK(attr, attrlen)) {
541 if (attr->rta_type == IFLA_IFNAME) {
542 wpa_driver_nl80211_event_link(
544 ((char *) attr) + rta_len,
545 attr->rta_len - rta_len, 1);
547 attr = RTA_NEXT(attr, attrlen);
552 static void wpa_driver_nl80211_event_receive_wext(int sock, void *eloop_ctx,
557 struct sockaddr_nl from;
563 fromlen = sizeof(from);
564 left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
565 (struct sockaddr *) &from, &fromlen);
567 if (errno != EINTR && errno != EAGAIN)
568 perror("recvfrom(netlink)");
572 h = (struct nlmsghdr *) buf;
573 while (left >= (int) sizeof(*h)) {
577 plen = len - sizeof(*h);
578 if (len > left || plen < 0) {
579 wpa_printf(MSG_DEBUG, "Malformed netlink message: "
580 "len=%d left=%d plen=%d",
585 switch (h->nlmsg_type) {
587 wpa_driver_nl80211_event_rtm_newlink(eloop_ctx, sock_ctx,
591 wpa_driver_nl80211_event_rtm_dellink(eloop_ctx, sock_ctx,
596 len = NLMSG_ALIGN(len);
598 h = (struct nlmsghdr *) ((char *) h + len);
602 wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "
606 if (--max_events > 0) {
608 * Try to receive all events in one eloop call in order to
609 * limit race condition on cases where AssocInfo event, Assoc
610 * event, and EAPOL frames are received more or less at the
611 * same time. We want to process the event messages first
612 * before starting EAPOL processing.
619 static int no_seq_check(struct nl_msg *msg, void *arg)
625 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
626 const u8 *frame, size_t len)
628 const struct ieee80211_mgmt *mgmt;
629 union wpa_event_data event;
631 mgmt = (const struct ieee80211_mgmt *) frame;
632 if (len < 24 + sizeof(mgmt->u.auth)) {
633 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
638 os_memset(&event, 0, sizeof(event));
639 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
640 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
641 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
642 if (len > 24 + sizeof(mgmt->u.auth)) {
643 event.auth.ies = mgmt->u.auth.variable;
644 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
647 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
651 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
652 const u8 *frame, size_t len)
654 const struct ieee80211_mgmt *mgmt;
655 union wpa_event_data event;
658 mgmt = (const struct ieee80211_mgmt *) frame;
659 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
660 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
665 status = le_to_host16(mgmt->u.assoc_resp.status_code);
666 if (status != WLAN_STATUS_SUCCESS) {
667 wpa_printf(MSG_DEBUG, "nl80211: Association failed: status "
669 /* TODO: notify SME so that things like SA Query and comeback
670 * time can be implemented */
675 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
677 os_memset(&event, 0, sizeof(event));
678 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
679 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
680 event.assoc_info.resp_ies_len =
681 len - 24 - sizeof(mgmt->u.assoc_req);
684 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
688 static void mlme_event(struct wpa_driver_nl80211_data *drv,
689 enum nl80211_commands cmd, struct nlattr *frame)
692 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
697 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d", cmd);
698 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
699 nla_data(frame), nla_len(frame));
702 case NL80211_CMD_AUTHENTICATE:
703 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
705 case NL80211_CMD_ASSOCIATE:
706 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
708 case NL80211_CMD_DEAUTHENTICATE:
710 wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, NULL);
712 case NL80211_CMD_DISASSOCIATE:
714 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
722 static int process_event(struct nl_msg *msg, void *arg)
724 struct wpa_driver_nl80211_data *drv = arg;
725 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
726 struct nlattr *tb[NL80211_ATTR_MAX + 1];
728 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
729 genlmsg_attrlen(gnlh, 0), NULL);
731 if (tb[NL80211_ATTR_IFINDEX]) {
732 int ifindex = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
733 if (ifindex != drv->ifindex) {
734 wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d)"
735 " for foreign interface (ifindex %d)",
742 case NL80211_CMD_NEW_SCAN_RESULTS:
743 wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
744 drv->scan_complete_events = 1;
745 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
747 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
749 case NL80211_CMD_SCAN_ABORTED:
750 wpa_printf(MSG_DEBUG, "nl80211: Scan aborted");
752 * Need to indicate that scan results are available in order
753 * not to make wpa_supplicant stop its scanning.
755 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
757 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
759 case NL80211_CMD_AUTHENTICATE:
760 case NL80211_CMD_ASSOCIATE:
761 case NL80211_CMD_DEAUTHENTICATE:
762 case NL80211_CMD_DISASSOCIATE:
763 mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]);
766 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
767 "(cmd=%d)", gnlh->cmd);
775 static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
779 struct wpa_driver_nl80211_data *drv = eloop_ctx;
781 wpa_printf(MSG_DEBUG, "nl80211: Event message available");
783 cb = nl_cb_clone(drv->nl_cb);
786 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
787 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv);
788 nl_recvmsgs(drv->nl_handle, cb);
793 static int wpa_driver_nl80211_get_ifflags_ifname(struct wpa_driver_nl80211_data *drv,
794 const char *ifname, int *flags)
798 os_memset(&ifr, 0, sizeof(ifr));
799 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
800 if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
801 perror("ioctl[SIOCGIFFLAGS]");
804 *flags = ifr.ifr_flags & 0xffff;
810 * wpa_driver_nl80211_get_ifflags - Get interface flags (SIOCGIFFLAGS)
811 * @drv: driver_nl80211 private data
812 * @flags: Pointer to returned flags value
813 * Returns: 0 on success, -1 on failure
815 static int wpa_driver_nl80211_get_ifflags(struct wpa_driver_nl80211_data *drv,
818 return wpa_driver_nl80211_get_ifflags_ifname(drv, drv->ifname, flags);
822 static int wpa_driver_nl80211_set_ifflags_ifname(
823 struct wpa_driver_nl80211_data *drv,
824 const char *ifname, int flags)
828 os_memset(&ifr, 0, sizeof(ifr));
829 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
830 ifr.ifr_flags = flags & 0xffff;
831 if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
832 perror("SIOCSIFFLAGS");
840 * wpa_driver_nl80211_set_ifflags - Set interface flags (SIOCSIFFLAGS)
841 * @drv: driver_nl80211 private data
842 * @flags: New value for flags
843 * Returns: 0 on success, -1 on failure
845 static int wpa_driver_nl80211_set_ifflags(struct wpa_driver_nl80211_data *drv,
848 return wpa_driver_nl80211_set_ifflags_ifname(drv, drv->ifname, flags);
853 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
854 * @priv: driver_nl80211 private data
855 * @alpha2_arg: country to which to switch to
856 * Returns: 0 on success, -1 on failure
858 * This asks nl80211 to set the regulatory domain for given
859 * country ISO / IEC alpha2.
861 static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
863 struct wpa_driver_nl80211_data *drv = priv;
869 goto nla_put_failure;
871 alpha2[0] = alpha2_arg[0];
872 alpha2[1] = alpha2_arg[1];
875 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
876 0, NL80211_CMD_REQ_SET_REG, 0);
878 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
879 if (send_and_recv_msgs(drv, msg, NULL, NULL))
887 struct wiphy_info_data {
893 static int wiphy_info_handler(struct nl_msg *msg, void *arg)
895 struct nlattr *tb[NL80211_ATTR_MAX + 1];
896 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
897 struct wiphy_info_data *info = arg;
899 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
900 genlmsg_attrlen(gnlh, 0), NULL);
902 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
903 info->max_scan_ssids =
904 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
906 if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
907 struct nlattr *nl_mode;
909 nla_for_each_nested(nl_mode,
910 tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
911 if (nl_mode->nla_type == NL80211_IFTYPE_AP) {
912 info->ap_supported = 1;
922 static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
923 struct wiphy_info_data *info)
927 os_memset(info, 0, sizeof(*info));
932 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
933 0, NL80211_CMD_GET_WIPHY, 0);
935 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
937 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
946 static void wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
948 struct wiphy_info_data info;
949 if (wpa_driver_nl80211_get_info(drv, &info))
951 drv->has_capability = 1;
952 drv->capa.max_scan_ssids = info.max_scan_ssids;
953 if (info.ap_supported)
954 drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
959 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
960 * @ctx: context to be used when calling wpa_supplicant functions,
961 * e.g., wpa_supplicant_event()
962 * @ifname: interface name, e.g., wlan0
963 * Returns: Pointer to private data, %NULL on failure
965 static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
968 struct sockaddr_nl local;
969 struct wpa_driver_nl80211_data *drv;
971 drv = os_zalloc(sizeof(*drv));
975 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
977 drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
978 if (drv->nl_cb == NULL) {
979 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
984 drv->nl_handle = nl_handle_alloc_cb(drv->nl_cb);
985 if (drv->nl_handle == NULL) {
986 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
991 if (genl_connect(drv->nl_handle)) {
992 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
997 drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);
998 if (drv->nl_cache == NULL) {
999 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1004 drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");
1005 if (drv->nl80211 == NULL) {
1006 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
1011 ret = nl_get_multicast_id(drv, "nl80211", "scan");
1013 ret = nl_socket_add_membership(drv->nl_handle, ret);
1015 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1016 "membership for scan events: %d (%s)",
1017 ret, strerror(-ret));
1021 ret = nl_get_multicast_id(drv, "nl80211", "mlme");
1023 ret = nl_socket_add_membership(drv->nl_handle, ret);
1025 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1026 "membership for mlme events: %d (%s)",
1027 ret, strerror(-ret));
1030 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
1032 eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle),
1033 wpa_driver_nl80211_event_receive, drv, ctx);
1035 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
1036 if (drv->ioctl_sock < 0) {
1037 perror("socket(PF_INET,SOCK_DGRAM)");
1041 s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1043 perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
1047 os_memset(&local, 0, sizeof(local));
1048 local.nl_family = AF_NETLINK;
1049 local.nl_groups = RTMGRP_LINK;
1050 if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
1051 perror("bind(netlink)");
1056 eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_wext, drv,
1058 drv->wext_event_sock = s;
1060 if (wpa_driver_nl80211_finish_drv_init(drv))
1066 eloop_unregister_read_sock(drv->wext_event_sock);
1067 close(drv->wext_event_sock);
1069 close(drv->ioctl_sock);
1071 genl_family_put(drv->nl80211);
1073 nl_cache_free(drv->nl_cache);
1075 nl_handle_destroy(drv->nl_handle);
1077 nl_cb_put(drv->nl_cb);
1085 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
1089 drv->ifindex = if_nametoindex(drv->ifname);
1091 if (wpa_driver_nl80211_set_mode(drv, 0) < 0) {
1092 wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
1093 "use managed mode");
1096 if (wpa_driver_nl80211_get_ifflags(drv, &flags) != 0) {
1097 wpa_printf(MSG_ERROR, "Could not get interface '%s' flags",
1101 if (!(flags & IFF_UP)) {
1102 if (wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP) != 0) {
1103 wpa_printf(MSG_ERROR, "Could not set interface '%s' "
1109 wpa_driver_nl80211_get_range(drv);
1111 wpa_driver_nl80211_capa(drv);
1113 wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
1120 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
1121 * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
1123 * Shut down driver interface and processing of driver events. Free
1124 * private data buffer if one was allocated in wpa_driver_nl80211_init().
1126 static void wpa_driver_nl80211_deinit(void *priv)
1128 struct wpa_driver_nl80211_data *drv = priv;
1131 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
1133 wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED, 0);
1135 wpa_driver_nl80211_send_oper_ifla(priv, 0, IF_OPER_UP);
1137 eloop_unregister_read_sock(drv->wext_event_sock);
1139 if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0)
1140 (void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);
1141 wpa_driver_nl80211_set_mode(drv, 0);
1143 close(drv->wext_event_sock);
1144 close(drv->ioctl_sock);
1146 eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle));
1147 genl_family_put(drv->nl80211);
1148 nl_cache_free(drv->nl_cache);
1149 nl_handle_destroy(drv->nl_handle);
1150 nl_cb_put(drv->nl_cb);
1157 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
1158 * @eloop_ctx: Unused
1159 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
1161 * This function can be used as registered timeout when starting a scan to
1162 * generate a scan completed event if the driver does not report this.
1164 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1166 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
1167 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
1172 * wpa_driver_nl80211_scan - Request the driver to initiate scan
1173 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
1174 * @params: Scan parameters
1175 * Returns: 0 on success, -1 on failure
1177 static int wpa_driver_nl80211_scan(void *priv,
1178 struct wpa_driver_scan_params *params)
1180 struct wpa_driver_nl80211_data *drv = priv;
1181 int ret = 0, timeout;
1182 struct nl_msg *msg, *ssids, *freqs;
1185 msg = nlmsg_alloc();
1186 ssids = nlmsg_alloc();
1187 freqs = nlmsg_alloc();
1188 if (!msg || !ssids || !freqs) {
1195 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1196 NL80211_CMD_TRIGGER_SCAN, 0);
1198 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1200 for (i = 0; i < params->num_ssids; i++) {
1201 NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
1202 params->ssids[i].ssid);
1204 if (params->num_ssids)
1205 nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
1207 if (params->extra_ies) {
1208 NLA_PUT(msg, NL80211_ATTR_IE, params->extra_ies_len,
1212 if (params->freqs) {
1213 for (i = 0; params->freqs[i]; i++)
1214 NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
1215 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
1218 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1221 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
1222 "(%s)", ret, strerror(-ret));
1223 goto nla_put_failure;
1226 /* Not all drivers generate "scan completed" wireless event, so try to
1227 * read results after a timeout. */
1229 if (drv->scan_complete_events) {
1231 * The driver seems to deliver events to notify when scan is
1232 * complete, so use longer timeout to avoid race conditions
1233 * with scanning and following association request.
1237 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
1238 "seconds", ret, timeout);
1239 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
1240 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
1251 static int bss_info_handler(struct nl_msg *msg, void *arg)
1253 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1254 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1255 struct nlattr *bss[NL80211_BSS_MAX + 1];
1256 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
1257 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
1258 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
1259 [NL80211_BSS_TSF] = { .type = NLA_U64 },
1260 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
1261 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
1262 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
1263 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
1264 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
1266 struct wpa_scan_results *res = arg;
1267 struct wpa_scan_res **tmp;
1268 struct wpa_scan_res *r;
1272 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1273 genlmsg_attrlen(gnlh, 0), NULL);
1274 if (!tb[NL80211_ATTR_BSS])
1276 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
1279 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
1280 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1281 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1287 r = os_zalloc(sizeof(*r) + ie_len);
1290 if (bss[NL80211_BSS_BSSID])
1291 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
1293 if (bss[NL80211_BSS_FREQUENCY])
1294 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
1295 if (bss[NL80211_BSS_BEACON_INTERVAL])
1296 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
1297 if (bss[NL80211_BSS_CAPABILITY])
1298 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
1299 r->flags |= WPA_SCAN_NOISE_INVALID;
1300 if (bss[NL80211_BSS_SIGNAL_MBM]) {
1301 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
1302 r->level /= 100; /* mBm to dBm */
1303 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
1304 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
1305 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
1306 r->flags |= WPA_SCAN_LEVEL_INVALID;
1308 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
1309 if (bss[NL80211_BSS_TSF])
1310 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
1313 os_memcpy(r + 1, ie, ie_len);
1315 tmp = os_realloc(res->res,
1316 (res->num + 1) * sizeof(struct wpa_scan_res *));
1321 tmp[res->num++] = r;
1329 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
1330 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
1331 * Returns: Scan results on success, -1 on failure
1333 static struct wpa_scan_results *
1334 wpa_driver_nl80211_get_scan_results(void *priv)
1336 struct wpa_driver_nl80211_data *drv = priv;
1338 struct wpa_scan_results *res;
1341 res = os_zalloc(sizeof(*res));
1344 msg = nlmsg_alloc();
1346 goto nla_put_failure;
1348 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP,
1349 NL80211_CMD_GET_SCAN, 0);
1350 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1352 ret = send_and_recv_msgs(drv, msg, bss_info_handler, res);
1355 wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)",
1356 (unsigned long) res->num);
1359 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1360 "(%s)", ret, strerror(-ret));
1363 wpa_scan_results_free(res);
1368 static int wpa_driver_nl80211_get_range(void *priv)
1370 struct wpa_driver_nl80211_data *drv = priv;
1371 struct iw_range *range;
1377 * Use larger buffer than struct iw_range in order to allow the
1378 * structure to grow in the future.
1380 buflen = sizeof(struct iw_range) + 500;
1381 range = os_zalloc(buflen);
1385 os_memset(&iwr, 0, sizeof(iwr));
1386 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1387 iwr.u.data.pointer = (caddr_t) range;
1388 iwr.u.data.length = buflen;
1390 minlen = ((char *) &range->enc_capa) - (char *) range +
1391 sizeof(range->enc_capa);
1393 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
1394 perror("ioctl[SIOCGIWRANGE]");
1397 } else if (iwr.u.data.length >= minlen &&
1398 range->we_version_compiled >= 18) {
1399 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
1400 "WE(source)=%d enc_capa=0x%x",
1401 range->we_version_compiled,
1402 range->we_version_source,
1404 drv->has_capability = 1;
1405 drv->we_version_compiled = range->we_version_compiled;
1406 if (range->enc_capa & IW_ENC_CAPA_WPA) {
1407 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1408 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
1410 if (range->enc_capa & IW_ENC_CAPA_WPA2) {
1411 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1412 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1414 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
1415 WPA_DRIVER_CAPA_ENC_WEP104;
1416 if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
1417 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
1418 if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
1419 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
1420 wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x",
1421 drv->capa.key_mgmt, drv->capa.enc);
1423 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "
1424 "assuming WPA is not supported");
1432 static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg,
1433 const u8 *addr, int key_idx,
1434 int set_tx, const u8 *seq,
1436 const u8 *key, size_t key_len)
1438 struct wpa_driver_nl80211_data *drv = priv;
1442 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
1443 "seq_len=%lu key_len=%lu",
1444 __func__, alg, addr, key_idx, set_tx,
1445 (unsigned long) seq_len, (unsigned long) key_len);
1447 msg = nlmsg_alloc();
1451 if (alg == WPA_ALG_NONE) {
1452 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1453 NL80211_CMD_DEL_KEY, 0);
1455 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1456 NL80211_CMD_NEW_KEY, 0);
1457 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
1461 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1464 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1468 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02);
1471 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);
1479 if (addr && os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
1481 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
1482 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1484 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1485 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1487 err = send_and_recv_msgs(drv, msg, NULL, NULL);
1489 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d", err);
1493 if (set_tx && alg != WPA_ALG_NONE) {
1494 msg = nlmsg_alloc();
1498 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1499 0, NL80211_CMD_SET_KEY, 0);
1500 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1501 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1502 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
1504 err = send_and_recv_msgs(drv, msg, NULL, NULL);
1506 wpa_printf(MSG_DEBUG, "nl80211: set default key "
1507 "failed; err=%d", err);
1519 static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
1520 const u8 *addr, int cmd, u16 reason_code)
1525 msg = nlmsg_alloc();
1529 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, cmd, 0);
1531 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1532 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
1533 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1535 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1538 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
1539 "(%s)", ret, strerror(-ret));
1540 goto nla_put_failure;
1550 static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,
1553 struct wpa_driver_nl80211_data *drv = priv;
1554 wpa_printf(MSG_DEBUG, "%s", __func__);
1555 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
1560 static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,
1563 struct wpa_driver_nl80211_data *drv = priv;
1564 wpa_printf(MSG_DEBUG, "%s", __func__);
1565 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISASSOCIATE,
1570 static int wpa_driver_nl80211_authenticate(
1571 void *priv, struct wpa_driver_auth_params *params)
1573 struct wpa_driver_nl80211_data *drv = priv;
1576 enum nl80211_auth_type type;
1578 drv->associated = 0;
1580 msg = nlmsg_alloc();
1584 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
1586 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1587 NL80211_CMD_AUTHENTICATE, 0);
1589 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1590 if (params->bssid) {
1591 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
1592 MAC2STR(params->bssid));
1593 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
1596 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
1597 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
1600 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
1601 params->ssid, params->ssid_len);
1602 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
1605 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
1607 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
1609 * TODO: if multiple auth_alg options enabled, try them one by one if
1610 * the AP rejects authentication due to unknown auth alg
1612 if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
1613 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1614 else if (params->auth_alg & AUTH_ALG_SHARED_KEY)
1615 type = NL80211_AUTHTYPE_SHARED_KEY;
1616 else if (params->auth_alg & AUTH_ALG_LEAP)
1617 type = NL80211_AUTHTYPE_NETWORK_EAP;
1618 else if (params->auth_alg & AUTH_ALG_FT)
1619 type = NL80211_AUTHTYPE_FT;
1621 goto nla_put_failure;
1622 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
1623 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
1625 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1628 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
1629 "(%s)", ret, strerror(-ret));
1630 goto nla_put_failure;
1633 wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
1643 static int wpa_driver_nl80211_set_freq2(
1644 struct wpa_driver_nl80211_data *drv,
1645 struct wpa_driver_associate_params *params)
1649 msg = nlmsg_alloc();
1653 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1654 NL80211_CMD_SET_WIPHY, 0);
1656 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1658 /* TODO: proper channel configuration */
1659 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, 2437);
1661 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
1668 static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
1669 struct wpa_driver_associate_params *params)
1671 if (wpa_driver_nl80211_set_mode(drv, params->mode) ||
1672 wpa_driver_nl80211_set_freq2(drv, params))
1675 /* TODO: setup monitor interface (and add code somewhere to remove this
1676 * when AP mode is stopped; associate with mode != 2 or drv_deinit) */
1677 /* TODO: setup beacon */
1681 #endif /* CONFIG_AP */
1684 static int wpa_driver_nl80211_associate(
1685 void *priv, struct wpa_driver_associate_params *params)
1687 struct wpa_driver_nl80211_data *drv = priv;
1692 if (params->mode == 2)
1693 return wpa_driver_nl80211_ap(drv, params);
1694 #endif /* CONFIG_AP */
1696 wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
1697 params->drop_unencrypted);
1699 drv->associated = 0;
1701 msg = nlmsg_alloc();
1705 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
1707 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1708 NL80211_CMD_ASSOCIATE, 0);
1710 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1711 if (params->bssid) {
1712 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
1713 MAC2STR(params->bssid));
1714 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
1717 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
1718 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
1721 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
1722 params->ssid, params->ssid_len);
1723 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
1725 if (params->ssid_len > sizeof(drv->ssid))
1726 goto nla_put_failure;
1727 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
1728 drv->ssid_len = params->ssid_len;
1730 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
1732 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
1735 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1738 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
1739 "(%s)", ret, strerror(-ret));
1740 goto nla_put_failure;
1743 wpa_printf(MSG_DEBUG, "nl80211: Association request send "
1753 * wpa_driver_nl80211_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE
1754 * @drv: Pointer to private driver data from wpa_driver_nl80211_init()
1755 * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS
1756 * Returns: 0 on success, -1 on failure
1758 static int wpa_driver_nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
1761 int ret = -1, flags;
1767 nlmode = NL80211_IFTYPE_STATION;
1770 nlmode = NL80211_IFTYPE_ADHOC;
1773 nlmode = NL80211_IFTYPE_AP;
1779 msg = nlmsg_alloc();
1783 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1784 0, NL80211_CMD_SET_INTERFACE, 0);
1785 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1786 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, nlmode);
1788 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1795 wpa_printf(MSG_ERROR, "nl80211: Failed to set interface mode: %d (%s)",
1796 ret, strerror(-ret));
1800 /* mac80211 doesn't allow mode changes while the device is up, so
1801 * take the device down, try to set the mode again, and bring the
1804 if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0) {
1805 (void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);
1807 /* Try to set the mode again while the interface is down */
1808 msg = nlmsg_alloc();
1812 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1813 0, NL80211_CMD_SET_INTERFACE, 0);
1814 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1815 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, nlmode);
1816 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1818 wpa_printf(MSG_ERROR, "Failed to set interface %s "
1819 "mode(try_again): %d (%s)",
1820 drv->ifname, ret, strerror(-ret));
1823 /* Ignore return value of get_ifflags to ensure that the device
1824 * is always up like it was before this function was called.
1826 (void) wpa_driver_nl80211_get_ifflags(drv, &flags);
1827 (void) wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP);
1834 static int wpa_driver_nl80211_get_capa(void *priv,
1835 struct wpa_driver_capa *capa)
1837 struct wpa_driver_nl80211_data *drv = priv;
1838 if (!drv->has_capability)
1840 os_memcpy(capa, &drv->capa, sizeof(*capa));
1845 static int wpa_driver_nl80211_set_operstate(void *priv, int state)
1847 struct wpa_driver_nl80211_data *drv = priv;
1849 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
1850 __func__, drv->operstate, state, state ? "UP" : "DORMANT");
1851 drv->operstate = state;
1852 return wpa_driver_nl80211_send_oper_ifla(
1853 drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT);
1857 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
1859 .desc = "Linux nl80211/cfg80211",
1860 .get_bssid = wpa_driver_nl80211_get_bssid,
1861 .get_ssid = wpa_driver_nl80211_get_ssid,
1862 .set_key = wpa_driver_nl80211_set_key,
1863 .scan2 = wpa_driver_nl80211_scan,
1864 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
1865 .deauthenticate = wpa_driver_nl80211_deauthenticate,
1866 .disassociate = wpa_driver_nl80211_disassociate,
1867 .authenticate = wpa_driver_nl80211_authenticate,
1868 .associate = wpa_driver_nl80211_associate,
1869 .init = wpa_driver_nl80211_init,
1870 .deinit = wpa_driver_nl80211_deinit,
1871 .get_capa = wpa_driver_nl80211_get_capa,
1872 .set_operstate = wpa_driver_nl80211_set_operstate,
1873 .set_country = wpa_driver_nl80211_set_country,