driver_nl80211.c
Go to the documentation of this file.
00001 /*
00002  * Driver interaction with Linux nl80211/cfg80211
00003  * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
00004  * Copyright (c) 2003-2004, Instant802 Networks, Inc.
00005  * Copyright (c) 2005-2006, Devicescape Software, Inc.
00006  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
00007  * Copyright (c) 2009-2010, Atheros Communications
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License version 2 as
00011  * published by the Free Software Foundation.
00012  *
00013  * Alternatively, this software may be distributed under the terms of BSD
00014  * license.
00015  *
00016  * See README and COPYING for more details.
00017  */
00018 
00019 #include "includes.h"
00020 #include <sys/ioctl.h>
00021 #include <net/if.h>
00022 #include <netlink/genl/genl.h>
00023 #include <netlink/genl/family.h>
00024 #include <netlink/genl/ctrl.h>
00025 #include <netpacket/packet.h>
00026 #include <linux/filter.h>
00027 #include "nl80211_copy.h"
00028 
00029 #include "common.h"
00030 #include "eloop.h"
00031 #include "common/ieee802_11_defs.h"
00032 #include "netlink.h"
00033 #include "linux_ioctl.h"
00034 #include "radiotap.h"
00035 #include "radiotap_iter.h"
00036 #include "driver.h"
00037 
00038 #ifdef CONFIG_LIBNL20
00039 /* libnl 2.0 compatibility code */
00040 #define nl_handle nl_sock
00041 #define nl_handle_alloc_cb nl_socket_alloc_cb
00042 #define nl_handle_destroy nl_socket_free
00043 #endif /* CONFIG_LIBNL20 */
00044 
00045 
00046 #ifndef IFF_LOWER_UP
00047 #define IFF_LOWER_UP   0x10000         /* driver signals L1 up         */
00048 #endif
00049 #ifndef IFF_DORMANT
00050 #define IFF_DORMANT    0x20000         /* driver signals dormant       */
00051 #endif
00052 
00053 #ifndef IF_OPER_DORMANT
00054 #define IF_OPER_DORMANT 5
00055 #endif
00056 #ifndef IF_OPER_UP
00057 #define IF_OPER_UP 6
00058 #endif
00059 
00060 struct i802_bss {
00061         struct wpa_driver_nl80211_data *drv;
00062         struct i802_bss *next;
00063         int ifindex;
00064         char ifname[IFNAMSIZ + 1];
00065         unsigned int beacon_set:1;
00066 };
00067 
00068 struct wpa_driver_nl80211_data {
00069         void *ctx;
00070         struct netlink_data *netlink;
00071         int ioctl_sock; /* socket for ioctl() use */
00072         char brname[IFNAMSIZ];
00073         int ifindex;
00074         int if_removed;
00075         struct wpa_driver_capa capa;
00076         int has_capability;
00077 
00078         int operstate;
00079 
00080         int scan_complete_events;
00081 
00082         struct nl_handle *nl_handle;
00083         struct nl_handle *nl_handle_event;
00084         struct nl_cache *nl_cache;
00085         struct nl_cache *nl_cache_event;
00086         struct nl_cb *nl_cb;
00087         struct genl_family *nl80211;
00088 
00089         u8 auth_bssid[ETH_ALEN];
00090         u8 bssid[ETH_ALEN];
00091         int associated;
00092         u8 ssid[32];
00093         size_t ssid_len;
00094         int nlmode;
00095         int ap_scan_as_station;
00096         unsigned int assoc_freq;
00097 
00098         int monitor_sock;
00099         int monitor_ifidx;
00100         int probe_req_report;
00101         int disable_11b_rates;
00102 
00103         unsigned int pending_remain_on_chan:1;
00104         unsigned int pending_send_action:1;
00105         unsigned int added_bridge:1;
00106         unsigned int added_if_into_bridge:1;
00107 
00108         u64 remain_on_chan_cookie;
00109         u64 send_action_cookie;
00110 
00111         struct wpa_driver_scan_filter *filter_ssids;
00112         size_t num_filter_ssids;
00113 
00114         struct i802_bss first_bss;
00115 
00116         int deauth_before_reauth;
00117 
00118 #ifdef HOSTAPD
00119         int eapol_sock; /* socket for EAPOL frames */
00120 
00121         int default_if_indices[16];
00122         int *if_indices;
00123         int num_if_indices;
00124 
00125         int last_freq;
00126         int last_freq_ht;
00127 #endif /* HOSTAPD */
00128 };
00129 
00130 
00131 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
00132                                             void *timeout_ctx);
00133 static int wpa_driver_nl80211_set_mode(void *priv, int mode);
00134 static int
00135 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
00136 static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
00137                                    const u8 *addr, int cmd, u16 reason_code,
00138                                    int local_state_change);
00139 static void nl80211_remove_monitor_interface(
00140         struct wpa_driver_nl80211_data *drv);
00141 
00142 #ifdef HOSTAPD
00143 static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
00144 static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
00145 static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
00146 static int wpa_driver_nl80211_if_remove(void *priv,
00147                                         enum wpa_driver_if_type type,
00148                                         const char *ifname);
00149 #else /* HOSTAPD */
00150 static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
00151 {
00152         return 0;
00153 }
00154 #endif /* HOSTAPD */
00155 
00156 static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
00157 static void wpa_driver_nl80211_probe_req_report_timeout(void *eloop_ctx,
00158                                                         void *timeout_ctx);
00159 static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
00160                                      int ifindex, int disabled);
00161 
00162 
00163 /* nl80211 code */
00164 static int ack_handler(struct nl_msg *msg, void *arg)
00165 {
00166         int *err = arg;
00167         *err = 0;
00168         return NL_STOP;
00169 }
00170 
00171 static int finish_handler(struct nl_msg *msg, void *arg)
00172 {
00173         int *ret = arg;
00174         *ret = 0;
00175         return NL_SKIP;
00176 }
00177 
00178 static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
00179                          void *arg)
00180 {
00181         int *ret = arg;
00182         *ret = err->error;
00183         return NL_SKIP;
00184 }
00185 
00186 
00187 static int no_seq_check(struct nl_msg *msg, void *arg)
00188 {
00189         return NL_OK;
00190 }
00191 
00192 
00193 static int send_and_recv(struct wpa_driver_nl80211_data *drv,
00194                          struct nl_handle *nl_handle, struct nl_msg *msg,
00195                          int (*valid_handler)(struct nl_msg *, void *),
00196                          void *valid_data)
00197 {
00198         struct nl_cb *cb;
00199         int err = -ENOMEM;
00200 
00201         cb = nl_cb_clone(drv->nl_cb);
00202         if (!cb)
00203                 goto out;
00204 
00205         err = nl_send_auto_complete(nl_handle, msg);
00206         if (err < 0)
00207                 goto out;
00208 
00209         err = 1;
00210 
00211         nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
00212         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
00213         nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
00214 
00215         if (valid_handler)
00216                 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
00217                           valid_handler, valid_data);
00218 
00219         while (err > 0)
00220                 nl_recvmsgs(nl_handle, cb);
00221  out:
00222         nl_cb_put(cb);
00223         nlmsg_free(msg);
00224         return err;
00225 }
00226 
00227 
00228 static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
00229                               struct nl_msg *msg,
00230                               int (*valid_handler)(struct nl_msg *, void *),
00231                               void *valid_data)
00232 {
00233         return send_and_recv(drv, drv->nl_handle, msg, valid_handler,
00234                              valid_data);
00235 }
00236 
00237 
00238 struct family_data {
00239         const char *group;
00240         int id;
00241 };
00242 
00243 
00244 static int family_handler(struct nl_msg *msg, void *arg)
00245 {
00246         struct family_data *res = arg;
00247         struct nlattr *tb[CTRL_ATTR_MAX + 1];
00248         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
00249         struct nlattr *mcgrp;
00250         int i;
00251 
00252         nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
00253                   genlmsg_attrlen(gnlh, 0), NULL);
00254         if (!tb[CTRL_ATTR_MCAST_GROUPS])
00255                 return NL_SKIP;
00256 
00257         nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
00258                 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
00259                 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
00260                           nla_len(mcgrp), NULL);
00261                 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
00262                     !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
00263                     os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
00264                                res->group,
00265                                nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
00266                         continue;
00267                 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
00268                 break;
00269         };
00270 
00271         return NL_SKIP;
00272 }
00273 
00274 
00275 static int nl_get_multicast_id(struct wpa_driver_nl80211_data *drv,
00276                                const char *family, const char *group)
00277 {
00278         struct nl_msg *msg;
00279         int ret = -1;
00280         struct family_data res = { group, -ENOENT };
00281 
00282         msg = nlmsg_alloc();
00283         if (!msg)
00284                 return -ENOMEM;
00285         genlmsg_put(msg, 0, 0, genl_ctrl_resolve(drv->nl_handle, "nlctrl"),
00286                     0, 0, CTRL_CMD_GETFAMILY, 0);
00287         NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
00288 
00289         ret = send_and_recv_msgs(drv, msg, family_handler, &res);
00290         msg = NULL;
00291         if (ret == 0)
00292                 ret = res.id;
00293 
00294 nla_put_failure:
00295         nlmsg_free(msg);
00296         return ret;
00297 }
00298 
00299 
00300 static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
00301 {
00302         struct i802_bss *bss = priv;
00303         struct wpa_driver_nl80211_data *drv = bss->drv;
00304         if (!drv->associated)
00305                 return -1;
00306         os_memcpy(bssid, drv->bssid, ETH_ALEN);
00307         return 0;
00308 }
00309 
00310 
00311 static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
00312 {
00313         struct i802_bss *bss = priv;
00314         struct wpa_driver_nl80211_data *drv = bss->drv;
00315         if (!drv->associated)
00316                 return -1;
00317         os_memcpy(ssid, drv->ssid, drv->ssid_len);
00318         return drv->ssid_len;
00319 }
00320 
00321 
00322 static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
00323                                           char *buf, size_t len, int del)
00324 {
00325         union wpa_event_data event;
00326 
00327         os_memset(&event, 0, sizeof(event));
00328         if (len > sizeof(event.interface_status.ifname))
00329                 len = sizeof(event.interface_status.ifname) - 1;
00330         os_memcpy(event.interface_status.ifname, buf, len);
00331         event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
00332                 EVENT_INTERFACE_ADDED;
00333 
00334         wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
00335                    del ? "DEL" : "NEW",
00336                    event.interface_status.ifname,
00337                    del ? "removed" : "added");
00338 
00339         if (os_strcmp(drv->first_bss.ifname, event.interface_status.ifname) == 0) {
00340                 if (del)
00341                         drv->if_removed = 1;
00342                 else
00343                         drv->if_removed = 0;
00344         }
00345 
00346         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
00347 }
00348 
00349 
00350 static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
00351                                          u8 *buf, size_t len)
00352 {
00353         int attrlen, rta_len;
00354         struct rtattr *attr;
00355 
00356         attrlen = len;
00357         attr = (struct rtattr *) buf;
00358 
00359         rta_len = RTA_ALIGN(sizeof(struct rtattr));
00360         while (RTA_OK(attr, attrlen)) {
00361                 if (attr->rta_type == IFLA_IFNAME) {
00362                         if (os_strcmp(((char *) attr) + rta_len, drv->first_bss.ifname)
00363                             == 0)
00364                                 return 1;
00365                         else
00366                                 break;
00367                 }
00368                 attr = RTA_NEXT(attr, attrlen);
00369         }
00370 
00371         return 0;
00372 }
00373 
00374 
00375 static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
00376                                           int ifindex, u8 *buf, size_t len)
00377 {
00378         if (drv->ifindex == ifindex)
00379                 return 1;
00380 
00381         if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
00382                 drv->first_bss.ifindex = if_nametoindex(drv->first_bss.ifname);
00383                 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
00384                            "interface");
00385                 wpa_driver_nl80211_finish_drv_init(drv);
00386                 return 1;
00387         }
00388 
00389         return 0;
00390 }
00391 
00392 
00393 static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
00394                                                  struct ifinfomsg *ifi,
00395                                                  u8 *buf, size_t len)
00396 {
00397         struct wpa_driver_nl80211_data *drv = ctx;
00398         int attrlen, rta_len;
00399         struct rtattr *attr;
00400         u32 brid = 0;
00401 
00402         if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, buf, len) &&
00403             !have_ifidx(drv, ifi->ifi_index)) {
00404                 wpa_printf(MSG_DEBUG, "nl80211: Ignore event for foreign "
00405                            "ifindex %d", ifi->ifi_index);
00406                 return;
00407         }
00408 
00409         wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
00410                    "(%s%s%s%s)",
00411                    drv->operstate, ifi->ifi_flags,
00412                    (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
00413                    (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
00414                    (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
00415                    (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
00416         /*
00417          * Some drivers send the association event before the operup event--in
00418          * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
00419          * fails. This will hit us when wpa_supplicant does not need to do
00420          * IEEE 802.1X authentication
00421          */
00422         if (drv->operstate == 1 &&
00423             (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
00424             !(ifi->ifi_flags & IFF_RUNNING))
00425                 netlink_send_oper_ifla(drv->netlink, drv->ifindex,
00426                                        -1, IF_OPER_UP);
00427 
00428         attrlen = len;
00429         attr = (struct rtattr *) buf;
00430         rta_len = RTA_ALIGN(sizeof(struct rtattr));
00431         while (RTA_OK(attr, attrlen)) {
00432                 if (attr->rta_type == IFLA_IFNAME) {
00433                         wpa_driver_nl80211_event_link(
00434                                 drv,
00435                                 ((char *) attr) + rta_len,
00436                                 attr->rta_len - rta_len, 0);
00437                 } else if (attr->rta_type == IFLA_MASTER)
00438                         brid = nla_get_u32((struct nlattr *) attr);
00439                 attr = RTA_NEXT(attr, attrlen);
00440         }
00441 
00442 #ifdef HOSTAPD
00443         if (ifi->ifi_family == AF_BRIDGE && brid) {
00444                 /* device has been added to bridge */
00445                 char namebuf[IFNAMSIZ];
00446                 if_indextoname(brid, namebuf);
00447                 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
00448                            brid, namebuf);
00449                 add_ifidx(drv, brid);
00450         }
00451 #endif /* HOSTAPD */
00452 }
00453 
00454 
00455 static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
00456                                                  struct ifinfomsg *ifi,
00457                                                  u8 *buf, size_t len)
00458 {
00459         struct wpa_driver_nl80211_data *drv = ctx;
00460         int attrlen, rta_len;
00461         struct rtattr *attr;
00462         u32 brid = 0;
00463 
00464         attrlen = len;
00465         attr = (struct rtattr *) buf;
00466 
00467         rta_len = RTA_ALIGN(sizeof(struct rtattr));
00468         while (RTA_OK(attr, attrlen)) {
00469                 if (attr->rta_type == IFLA_IFNAME) {
00470                         wpa_driver_nl80211_event_link(
00471                                 drv,
00472                                 ((char *) attr) + rta_len,
00473                                 attr->rta_len - rta_len, 1);
00474                 } else if (attr->rta_type == IFLA_MASTER)
00475                         brid = nla_get_u32((struct nlattr *) attr);
00476                 attr = RTA_NEXT(attr, attrlen);
00477         }
00478 
00479 #ifdef HOSTAPD
00480         if (ifi->ifi_family == AF_BRIDGE && brid) {
00481                 /* device has been removed from bridge */
00482                 char namebuf[IFNAMSIZ];
00483                 if_indextoname(brid, namebuf);
00484                 wpa_printf(MSG_DEBUG, "nl80211: Remove ifindex %u for bridge "
00485                            "%s", brid, namebuf);
00486                 del_ifidx(drv, brid);
00487         }
00488 #endif /* HOSTAPD */
00489 }
00490 
00491 
00492 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
00493                             const u8 *frame, size_t len)
00494 {
00495         const struct ieee80211_mgmt *mgmt;
00496         union wpa_event_data event;
00497 
00498         mgmt = (const struct ieee80211_mgmt *) frame;
00499         if (len < 24 + sizeof(mgmt->u.auth)) {
00500                 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
00501                            "frame");
00502                 return;
00503         }
00504 
00505         os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
00506         os_memset(&event, 0, sizeof(event));
00507         os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
00508         event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
00509         event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
00510         if (len > 24 + sizeof(mgmt->u.auth)) {
00511                 event.auth.ies = mgmt->u.auth.variable;
00512                 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
00513         }
00514 
00515         wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
00516 }
00517 
00518 
00519 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
00520                             const u8 *frame, size_t len)
00521 {
00522         const struct ieee80211_mgmt *mgmt;
00523         union wpa_event_data event;
00524         u16 status;
00525 
00526         mgmt = (const struct ieee80211_mgmt *) frame;
00527         if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
00528                 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
00529                            "frame");
00530                 return;
00531         }
00532 
00533         status = le_to_host16(mgmt->u.assoc_resp.status_code);
00534         if (status != WLAN_STATUS_SUCCESS) {
00535                 os_memset(&event, 0, sizeof(event));
00536                 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
00537                         event.assoc_reject.resp_ies =
00538                                 (u8 *) mgmt->u.assoc_resp.variable;
00539                         event.assoc_reject.resp_ies_len =
00540                                 len - 24 - sizeof(mgmt->u.assoc_resp);
00541                 }
00542                 event.assoc_reject.status_code = status;
00543 
00544                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
00545                 return;
00546         }
00547 
00548         drv->associated = 1;
00549         os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
00550 
00551         os_memset(&event, 0, sizeof(event));
00552         if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
00553                 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
00554                 event.assoc_info.resp_ies_len =
00555                         len - 24 - sizeof(mgmt->u.assoc_resp);
00556         }
00557 
00558         event.assoc_info.freq = drv->assoc_freq;
00559 
00560         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
00561 }
00562 
00563 
00564 static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
00565                                enum nl80211_commands cmd, struct nlattr *status,
00566                                struct nlattr *addr, struct nlattr *req_ie,
00567                                struct nlattr *resp_ie)
00568 {
00569         union wpa_event_data event;
00570 
00571         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
00572                 /*
00573                  * Avoid reporting two association events that would confuse
00574                  * the core code.
00575                  */
00576                 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
00577                            "when using userspace SME", cmd);
00578                 return;
00579         }
00580 
00581         os_memset(&event, 0, sizeof(event));
00582         if (cmd == NL80211_CMD_CONNECT &&
00583             nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
00584                 if (resp_ie) {
00585                         event.assoc_reject.resp_ies = nla_data(resp_ie);
00586                         event.assoc_reject.resp_ies_len = nla_len(resp_ie);
00587                 }
00588                 event.assoc_reject.status_code = nla_get_u16(status);
00589                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
00590                 return;
00591         }
00592 
00593         drv->associated = 1;
00594         if (addr)
00595                 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
00596 
00597         if (req_ie) {
00598                 event.assoc_info.req_ies = nla_data(req_ie);
00599                 event.assoc_info.req_ies_len = nla_len(req_ie);
00600         }
00601         if (resp_ie) {
00602                 event.assoc_info.resp_ies = nla_data(resp_ie);
00603                 event.assoc_info.resp_ies_len = nla_len(resp_ie);
00604         }
00605 
00606         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
00607 }
00608 
00609 
00610 static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
00611                                enum nl80211_commands cmd, struct nlattr *addr)
00612 {
00613         union wpa_event_data event;
00614         enum wpa_event_type ev;
00615 
00616         if (nla_len(addr) != ETH_ALEN)
00617                 return;
00618 
00619         wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
00620                    cmd, MAC2STR((u8 *) nla_data(addr)));
00621 
00622         if (cmd == NL80211_CMD_AUTHENTICATE)
00623                 ev = EVENT_AUTH_TIMED_OUT;
00624         else if (cmd == NL80211_CMD_ASSOCIATE)
00625                 ev = EVENT_ASSOC_TIMED_OUT;
00626         else
00627                 return;
00628 
00629         os_memset(&event, 0, sizeof(event));
00630         os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
00631         wpa_supplicant_event(drv->ctx, ev, &event);
00632 }
00633 
00634 
00635 static void mlme_event_action(struct wpa_driver_nl80211_data *drv,
00636                               struct nlattr *freq, const u8 *frame, size_t len)
00637 {
00638         const struct ieee80211_mgmt *mgmt;
00639         union wpa_event_data event;
00640         u16 fc, stype;
00641 
00642         mgmt = (const struct ieee80211_mgmt *) frame;
00643         if (len < 24) {
00644                 wpa_printf(MSG_DEBUG, "nl80211: Too short action frame");
00645                 return;
00646         }
00647 
00648         fc = le_to_host16(mgmt->frame_control);
00649         stype = WLAN_FC_GET_STYPE(fc);
00650 
00651         os_memset(&event, 0, sizeof(event));
00652         event.rx_action.da = mgmt->da;
00653         event.rx_action.sa = mgmt->sa;
00654         event.rx_action.bssid = mgmt->bssid;
00655         event.rx_action.category = mgmt->u.action.category;
00656         event.rx_action.data = &mgmt->u.action.category + 1;
00657         event.rx_action.len = frame + len - event.rx_action.data;
00658         if (freq)
00659                 event.rx_action.freq = nla_get_u32(freq);
00660         wpa_supplicant_event(drv->ctx, EVENT_RX_ACTION, &event);
00661 }
00662 
00663 
00664 static void mlme_event_action_tx_status(struct wpa_driver_nl80211_data *drv,
00665                                         struct nlattr *cookie, const u8 *frame,
00666                                         size_t len, struct nlattr *ack)
00667 {
00668         union wpa_event_data event;
00669         const struct ieee80211_hdr *hdr;
00670         u16 fc;
00671         u64 cookie_val;
00672 
00673         if (!cookie)
00674                 return;
00675 
00676         cookie_val = nla_get_u64(cookie);
00677         wpa_printf(MSG_DEBUG, "nl80211: Action TX status: cookie=0%llx%s",
00678                    (long long unsigned int) cookie_val,
00679                    cookie_val == drv->send_action_cookie ?
00680                    " (match)" : " (unknown)");
00681         if (cookie_val != drv->send_action_cookie)
00682                 return;
00683 
00684         hdr = (const struct ieee80211_hdr *) frame;
00685         fc = le_to_host16(hdr->frame_control);
00686 
00687         os_memset(&event, 0, sizeof(event));
00688         event.tx_status.type = WLAN_FC_GET_TYPE(fc);
00689         event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
00690         event.tx_status.dst = hdr->addr1;
00691         event.tx_status.data = frame;
00692         event.tx_status.data_len = len;
00693         event.tx_status.ack = ack != NULL;
00694         wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
00695 }
00696 
00697 
00698 static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
00699                                        enum wpa_event_type type,
00700                                        const u8 *frame, size_t len)
00701 {
00702         const struct ieee80211_mgmt *mgmt;
00703         union wpa_event_data event;
00704         const u8 *bssid = NULL;
00705         u16 reason_code = 0;
00706 
00707         mgmt = (const struct ieee80211_mgmt *) frame;
00708         if (len >= 24) {
00709                 bssid = mgmt->bssid;
00710  
00711                 if (drv->associated != 0 &&
00712                     os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
00713                     os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
00714                         /*
00715                          * We have presumably received this deauth as a
00716                          * response to a clear_state_mismatch() outgoing
00717                          * deauth.  Don't let it take us offline!
00718                          */
00719                         wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
00720                                    "from Unknown BSSID " MACSTR " -- ignoring",
00721                                    MAC2STR(bssid));
00722                         return;
00723                 }
00724                 
00725                 if (drv->deauth_before_reauth && type == EVENT_DEAUTH) {
00726                         /*
00727                          * Authentication returned EAGAIN so we are doing a
00728                          * deauthenticate followed by reauthenticate. We
00729                          * can ignore this event.
00730                          */
00731                         drv->deauth_before_reauth = 0;
00732                         wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
00733                                    "as expected (from " MACSTR ") -- ignoring",
00734                                    MAC2STR(bssid));
00735                         return;
00736                 }
00737         }
00738 
00739         drv->associated = 0;
00740         os_memset(&event, 0, sizeof(event));
00741 
00742         /* Note: Same offset for Reason Code in both frame subtypes */
00743         if (len >= 24 + sizeof(mgmt->u.deauth))
00744                 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
00745 
00746         if (type == EVENT_DISASSOC) {
00747                 event.disassoc_info.addr = bssid;
00748                 event.disassoc_info.reason_code = reason_code;
00749         } else {
00750                 event.deauth_info.addr = bssid;
00751                 event.deauth_info.reason_code = reason_code;
00752         }
00753 
00754         wpa_supplicant_event(drv->ctx, type, &event);
00755 }
00756 
00757 
00758 static void mlme_event(struct wpa_driver_nl80211_data *drv,
00759                        enum nl80211_commands cmd, struct nlattr *frame,
00760                        struct nlattr *addr, struct nlattr *timed_out,
00761                        struct nlattr *freq, struct nlattr *ack,
00762                        struct nlattr *cookie)
00763 {
00764         if (timed_out && addr) {
00765                 mlme_timeout_event(drv, cmd, addr);
00766                 return;
00767         }
00768 
00769         if (frame == NULL) {
00770                 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
00771                            "data", cmd);
00772                 return;
00773         }
00774 
00775         wpa_printf(MSG_DEBUG, "nl80211: MLME event %d", cmd);
00776         wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
00777                     nla_data(frame), nla_len(frame));
00778 
00779         switch (cmd) {
00780         case NL80211_CMD_AUTHENTICATE:
00781                 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
00782                 break;
00783         case NL80211_CMD_ASSOCIATE:
00784                 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
00785                 break;
00786         case NL80211_CMD_DEAUTHENTICATE:
00787                 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
00788                                            nla_data(frame), nla_len(frame));
00789                 break;
00790         case NL80211_CMD_DISASSOCIATE:
00791                 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
00792                                            nla_data(frame), nla_len(frame));
00793                 break;
00794         case NL80211_CMD_ACTION:
00795                 mlme_event_action(drv, freq, nla_data(frame), nla_len(frame));
00796                 break;
00797         case NL80211_CMD_ACTION_TX_STATUS:
00798                 mlme_event_action_tx_status(drv, cookie, nla_data(frame),
00799                                             nla_len(frame), ack);
00800                 break;
00801         default:
00802                 break;
00803         }
00804 }
00805 
00806 
00807 static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv,
00808                                            struct nlattr *tb[])
00809 {
00810         union wpa_event_data data;
00811 
00812         wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
00813         os_memset(&data, 0, sizeof(data));
00814         if (tb[NL80211_ATTR_MAC]) {
00815                 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
00816                             nla_data(tb[NL80211_ATTR_MAC]),
00817                             nla_len(tb[NL80211_ATTR_MAC]));
00818                 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
00819         }
00820         if (tb[NL80211_ATTR_KEY_SEQ]) {
00821                 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
00822                             nla_data(tb[NL80211_ATTR_KEY_SEQ]),
00823                             nla_len(tb[NL80211_ATTR_KEY_SEQ]));
00824         }
00825         if (tb[NL80211_ATTR_KEY_TYPE]) {
00826                 enum nl80211_key_type key_type =
00827                         nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
00828                 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
00829                 if (key_type == NL80211_KEYTYPE_PAIRWISE)
00830                         data.michael_mic_failure.unicast = 1;
00831         } else
00832                 data.michael_mic_failure.unicast = 1;
00833 
00834         if (tb[NL80211_ATTR_KEY_IDX]) {
00835                 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
00836                 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
00837         }
00838 
00839         wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
00840 }
00841 
00842 
00843 static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
00844                                  struct nlattr *tb[])
00845 {
00846         if (tb[NL80211_ATTR_MAC] == NULL) {
00847                 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
00848                            "event");
00849                 return;
00850         }
00851         os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
00852         drv->associated = 1;
00853         wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
00854                    MAC2STR(drv->bssid));
00855 
00856         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
00857 }
00858 
00859 
00860 static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
00861                                          int cancel_event, struct nlattr *tb[])
00862 {
00863         unsigned int freq, chan_type, duration;
00864         union wpa_event_data data;
00865         u64 cookie;
00866 
00867         if (tb[NL80211_ATTR_WIPHY_FREQ])
00868                 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
00869         else
00870                 freq = 0;
00871 
00872         if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
00873                 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
00874         else
00875                 chan_type = 0;
00876 
00877         if (tb[NL80211_ATTR_DURATION])
00878                 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
00879         else
00880                 duration = 0;
00881 
00882         if (tb[NL80211_ATTR_COOKIE])
00883                 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
00884         else
00885                 cookie = 0;
00886 
00887         wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
00888                    "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
00889                    cancel_event, freq, chan_type, duration,
00890                    (long long unsigned int) cookie,
00891                    cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
00892 
00893         if (cookie != drv->remain_on_chan_cookie)
00894                 return; /* not for us */
00895 
00896         drv->pending_remain_on_chan = !cancel_event;
00897 
00898         os_memset(&data, 0, sizeof(data));
00899         data.remain_on_channel.freq = freq;
00900         data.remain_on_channel.duration = duration;
00901         wpa_supplicant_event(drv->ctx, cancel_event ?
00902                              EVENT_CANCEL_REMAIN_ON_CHANNEL :
00903                              EVENT_REMAIN_ON_CHANNEL, &data);
00904 }
00905 
00906 
00907 static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
00908                             struct nlattr *tb[])
00909 {
00910         union wpa_event_data event;
00911         struct nlattr *nl;
00912         int rem;
00913         struct scan_info *info;
00914 #define MAX_REPORT_FREQS 50
00915         int freqs[MAX_REPORT_FREQS];
00916         int num_freqs = 0;
00917 
00918         os_memset(&event, 0, sizeof(event));
00919         info = &event.scan_info;
00920         info->aborted = aborted;
00921 
00922         if (tb[NL80211_ATTR_SCAN_SSIDS]) {
00923                 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
00924                         struct wpa_driver_scan_ssid *s =
00925                                 &info->ssids[info->num_ssids];
00926                         s->ssid = nla_data(nl);
00927                         s->ssid_len = nla_len(nl);
00928                         info->num_ssids++;
00929                         if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
00930                                 break;
00931                 }
00932         }
00933         if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
00934                 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
00935                 {
00936                         freqs[num_freqs] = nla_get_u32(nl);
00937                         num_freqs++;
00938                         if (num_freqs == MAX_REPORT_FREQS - 1)
00939                                 break;
00940                 }
00941                 info->freqs = freqs;
00942                 info->num_freqs = num_freqs;
00943         }
00944         wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
00945 }
00946 
00947 
00948 static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
00949                               struct nlattr *tb[])
00950 {
00951         static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
00952                 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
00953                 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
00954                 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
00955         };
00956         struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
00957         enum nl80211_cqm_rssi_threshold_event event;
00958         union wpa_event_data ed;
00959 
00960         if (tb[NL80211_ATTR_CQM] == NULL ||
00961             nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
00962                              cqm_policy)) {
00963                 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
00964                 return;
00965         }
00966 
00967         if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
00968                 return;
00969         event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
00970 
00971         os_memset(&ed, 0, sizeof(ed));
00972 
00973         if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
00974                 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
00975                            "event: RSSI high");
00976                 ed.signal_change.above_threshold = 1;
00977         } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
00978                 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
00979                            "event: RSSI low");
00980                 ed.signal_change.above_threshold = 0;
00981         } else
00982                 return;
00983 
00984         wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
00985 }
00986 
00987 
00988 static int process_event(struct nl_msg *msg, void *arg)
00989 {
00990         struct wpa_driver_nl80211_data *drv = arg;
00991         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
00992         struct nlattr *tb[NL80211_ATTR_MAX + 1];
00993         union wpa_event_data data;
00994 
00995         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
00996                   genlmsg_attrlen(gnlh, 0), NULL);
00997 
00998         if (tb[NL80211_ATTR_IFINDEX]) {
00999                 int ifindex = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
01000                 if (ifindex != drv->ifindex && !have_ifidx(drv, ifindex)) {
01001                         wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d)"
01002                                    " for foreign interface (ifindex %d)",
01003                                    gnlh->cmd, ifindex);
01004                         return NL_SKIP;
01005                 }
01006         }
01007 
01008         if (drv->ap_scan_as_station &&
01009             (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
01010              gnlh->cmd == NL80211_CMD_SCAN_ABORTED)) {
01011                 wpa_driver_nl80211_set_mode(&drv->first_bss,
01012                                             IEEE80211_MODE_AP);
01013                 drv->ap_scan_as_station = 0;
01014         }
01015 
01016         switch (gnlh->cmd) {
01017         case NL80211_CMD_TRIGGER_SCAN:
01018                 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger");
01019                 break;
01020         case NL80211_CMD_NEW_SCAN_RESULTS:
01021                 wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
01022                 drv->scan_complete_events = 1;
01023                 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
01024                                      drv->ctx);
01025                 send_scan_event(drv, 0, tb);
01026                 break;
01027         case NL80211_CMD_SCAN_ABORTED:
01028                 wpa_printf(MSG_DEBUG, "nl80211: Scan aborted");
01029                 /*
01030                  * Need to indicate that scan results are available in order
01031                  * not to make wpa_supplicant stop its scanning.
01032                  */
01033                 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
01034                                      drv->ctx);
01035                 send_scan_event(drv, 1, tb);
01036                 break;
01037         case NL80211_CMD_AUTHENTICATE:
01038         case NL80211_CMD_ASSOCIATE:
01039         case NL80211_CMD_DEAUTHENTICATE:
01040         case NL80211_CMD_DISASSOCIATE:
01041         case NL80211_CMD_ACTION:
01042         case NL80211_CMD_ACTION_TX_STATUS:
01043                 mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME],
01044                            tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
01045                            tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
01046                            tb[NL80211_ATTR_COOKIE]);
01047                 break;
01048         case NL80211_CMD_CONNECT:
01049         case NL80211_CMD_ROAM:
01050                 mlme_event_connect(drv, gnlh->cmd,
01051                                    tb[NL80211_ATTR_STATUS_CODE],
01052                                    tb[NL80211_ATTR_MAC],
01053                                    tb[NL80211_ATTR_REQ_IE],
01054                                    tb[NL80211_ATTR_RESP_IE]);
01055                 break;
01056         case NL80211_CMD_DISCONNECT:
01057                 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
01058                         /*
01059                          * Avoid reporting two disassociation events that could
01060                          * confuse the core code.
01061                          */
01062                         wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
01063                                    "event when using userspace SME");
01064                         break;
01065                 }
01066                 drv->associated = 0;
01067                 os_memset(&data, 0, sizeof(data));
01068                 if (tb[NL80211_ATTR_REASON_CODE])
01069                         data.disassoc_info.reason_code =
01070                                 nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
01071                 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
01072                 break;
01073         case NL80211_CMD_MICHAEL_MIC_FAILURE:
01074                 mlme_event_michael_mic_failure(drv, tb);
01075                 break;
01076         case NL80211_CMD_JOIN_IBSS:
01077                 mlme_event_join_ibss(drv, tb);
01078                 break;
01079         case NL80211_CMD_REMAIN_ON_CHANNEL:
01080                 mlme_event_remain_on_channel(drv, 0, tb);
01081                 break;
01082         case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
01083                 mlme_event_remain_on_channel(drv, 1, tb);
01084                 break;
01085         case NL80211_CMD_NOTIFY_CQM:
01086                 nl80211_cqm_event(drv, tb);
01087                 break;
01088         default:
01089                 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
01090                            "(cmd=%d)", gnlh->cmd);
01091                 break;
01092         }
01093 
01094         return NL_SKIP;
01095 }
01096 
01097 
01098 static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
01099                                              void *sock_ctx)
01100 {
01101         struct nl_cb *cb;
01102         struct wpa_driver_nl80211_data *drv = eloop_ctx;
01103 
01104         wpa_printf(MSG_DEBUG, "nl80211: Event message available");
01105 
01106         cb = nl_cb_clone(drv->nl_cb);
01107         if (!cb)
01108                 return;
01109         nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
01110         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv);
01111         nl_recvmsgs(drv->nl_handle_event, cb);
01112         nl_cb_put(cb);
01113 }
01114 
01115 
01125 static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
01126 {
01127         struct i802_bss *bss = priv;
01128         struct wpa_driver_nl80211_data *drv = bss->drv;
01129         char alpha2[3];
01130         struct nl_msg *msg;
01131 
01132         msg = nlmsg_alloc();
01133         if (!msg)
01134                 return -ENOMEM;
01135 
01136         alpha2[0] = alpha2_arg[0];
01137         alpha2[1] = alpha2_arg[1];
01138         alpha2[2] = '\0';
01139 
01140         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
01141                     0, NL80211_CMD_REQ_SET_REG, 0);
01142 
01143         NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
01144         if (send_and_recv_msgs(drv, msg, NULL, NULL))
01145                 return -EINVAL;
01146         return 0;
01147 nla_put_failure:
01148         return -EINVAL;
01149 }
01150 
01151 
01152 #ifndef HOSTAPD
01153 struct wiphy_info_data {
01154         int max_scan_ssids;
01155         int ap_supported;
01156         int auth_supported;
01157         int connect_supported;
01158 };
01159 
01160 
01161 static int wiphy_info_handler(struct nl_msg *msg, void *arg)
01162 {
01163         struct nlattr *tb[NL80211_ATTR_MAX + 1];
01164         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
01165         struct wiphy_info_data *info = arg;
01166 
01167         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
01168                   genlmsg_attrlen(gnlh, 0), NULL);
01169 
01170         if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
01171                 info->max_scan_ssids =
01172                         nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
01173 
01174         if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
01175                 struct nlattr *nl_mode;
01176                 int i;
01177                 nla_for_each_nested(nl_mode,
01178                                     tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
01179                         if (nl_mode->nla_type == NL80211_IFTYPE_AP) {
01180                                 info->ap_supported = 1;
01181                                 break;
01182                         }
01183                 }
01184         }
01185 
01186         if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
01187                 struct nlattr *nl_cmd;
01188                 int i;
01189 
01190                 nla_for_each_nested(nl_cmd,
01191                                     tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
01192                         u32 cmd = nla_get_u32(nl_cmd);
01193                         if (cmd == NL80211_CMD_AUTHENTICATE)
01194                                 info->auth_supported = 1;
01195                         else if (cmd == NL80211_CMD_CONNECT)
01196                                 info->connect_supported = 1;
01197                 }
01198         }
01199 
01200         return NL_SKIP;
01201 }
01202 
01203 
01204 static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
01205                                        struct wiphy_info_data *info)
01206 {
01207         struct nl_msg *msg;
01208 
01209         os_memset(info, 0, sizeof(*info));
01210         msg = nlmsg_alloc();
01211         if (!msg)
01212                 return -1;
01213 
01214         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
01215                     0, NL80211_CMD_GET_WIPHY, 0);
01216 
01217         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->first_bss.ifindex);
01218 
01219         if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
01220                 return 0;
01221         msg = NULL;
01222 nla_put_failure:
01223         nlmsg_free(msg);
01224         return -1;
01225 }
01226 
01227 
01228 static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
01229 {
01230         struct wiphy_info_data info;
01231         if (wpa_driver_nl80211_get_info(drv, &info))
01232                 return -1;
01233         drv->has_capability = 1;
01234         /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
01235         drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
01236                 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
01237                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
01238                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
01239         drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 |
01240                 WPA_DRIVER_CAPA_ENC_WEP104 |
01241                 WPA_DRIVER_CAPA_ENC_TKIP |
01242                 WPA_DRIVER_CAPA_ENC_CCMP;
01243         drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
01244                 WPA_DRIVER_AUTH_SHARED |
01245                 WPA_DRIVER_AUTH_LEAP;
01246 
01247         drv->capa.max_scan_ssids = info.max_scan_ssids;
01248         if (info.ap_supported)
01249                 drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
01250 
01251         if (info.auth_supported)
01252                 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
01253         else if (!info.connect_supported) {
01254                 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
01255                            "authentication/association or connect commands");
01256                 return -1;
01257         }
01258 
01259         drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
01260         drv->capa.max_remain_on_chan = 5000;
01261 
01262         return 0;
01263 }
01264 #endif /* HOSTAPD */
01265 
01266 
01267 static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv,
01268                                       void *ctx)
01269 {
01270         int ret;
01271 
01272         /* Initialize generic netlink and nl80211 */
01273 
01274         drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
01275         if (drv->nl_cb == NULL) {
01276                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
01277                            "callbacks");
01278                 goto err1;
01279         }
01280 
01281         drv->nl_handle = nl_handle_alloc_cb(drv->nl_cb);
01282         if (drv->nl_handle == NULL) {
01283                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
01284                            "callbacks");
01285                 goto err2;
01286         }
01287 
01288         drv->nl_handle_event = nl_handle_alloc_cb(drv->nl_cb);
01289         if (drv->nl_handle_event == NULL) {
01290                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
01291                            "callbacks (event)");
01292                 goto err2b;
01293         }
01294 
01295         if (genl_connect(drv->nl_handle)) {
01296                 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
01297                            "netlink");
01298                 goto err3;
01299         }
01300 
01301         if (genl_connect(drv->nl_handle_event)) {
01302                 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
01303                            "netlink (event)");
01304                 goto err3;
01305         }
01306 
01307 #ifdef CONFIG_LIBNL20
01308         if (genl_ctrl_alloc_cache(drv->nl_handle, &drv->nl_cache) < 0) {
01309                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
01310                            "netlink cache");
01311                 goto err3;
01312         }
01313         if (genl_ctrl_alloc_cache(drv->nl_handle_event, &drv->nl_cache_event) <
01314             0) {
01315                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
01316                            "netlink cache (event)");
01317                 goto err3b;
01318         }
01319 #else /* CONFIG_LIBNL20 */
01320         drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);
01321         if (drv->nl_cache == NULL) {
01322                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
01323                            "netlink cache");
01324                 goto err3;
01325         }
01326         drv->nl_cache_event = genl_ctrl_alloc_cache(drv->nl_handle_event);
01327         if (drv->nl_cache_event == NULL) {
01328                 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
01329                            "netlink cache (event)");
01330                 goto err3b;
01331         }
01332 #endif /* CONFIG_LIBNL20 */
01333 
01334         drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");
01335         if (drv->nl80211 == NULL) {
01336                 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
01337                            "found");
01338                 goto err4;
01339         }
01340 
01341         ret = nl_get_multicast_id(drv, "nl80211", "scan");
01342         if (ret >= 0)
01343                 ret = nl_socket_add_membership(drv->nl_handle_event, ret);
01344         if (ret < 0) {
01345                 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
01346                            "membership for scan events: %d (%s)",
01347                            ret, strerror(-ret));
01348                 goto err4;
01349         }
01350 
01351         ret = nl_get_multicast_id(drv, "nl80211", "mlme");
01352         if (ret >= 0)
01353                 ret = nl_socket_add_membership(drv->nl_handle_event, ret);
01354         if (ret < 0) {
01355                 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
01356                            "membership for mlme events: %d (%s)",
01357                            ret, strerror(-ret));
01358                 goto err4;
01359         }
01360 
01361         eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle_event),
01362                                  wpa_driver_nl80211_event_receive, drv, ctx);
01363 
01364         return 0;
01365 
01366 err4:
01367         nl_cache_free(drv->nl_cache_event);
01368 err3b:
01369         nl_cache_free(drv->nl_cache);
01370 err3:
01371         nl_handle_destroy(drv->nl_handle_event);
01372 err2b:
01373         nl_handle_destroy(drv->nl_handle);
01374 err2:
01375         nl_cb_put(drv->nl_cb);
01376 err1:
01377         return -1;
01378 }
01379 
01380 
01388 static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
01389 {
01390         struct wpa_driver_nl80211_data *drv;
01391         struct netlink_config *cfg;
01392         struct i802_bss *bss;
01393 
01394         drv = os_zalloc(sizeof(*drv));
01395         if (drv == NULL)
01396                 return NULL;
01397         drv->ctx = ctx;
01398         bss = &drv->first_bss;
01399         bss->drv = drv;
01400         os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
01401         drv->monitor_ifidx = -1;
01402         drv->monitor_sock = -1;
01403         drv->ioctl_sock = -1;
01404 
01405         if (wpa_driver_nl80211_init_nl(drv, ctx)) {
01406                 os_free(drv);
01407                 return NULL;
01408         }
01409 
01410         drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
01411         if (drv->ioctl_sock < 0) {
01412                 perror("socket(PF_INET,SOCK_DGRAM)");
01413                 goto failed;
01414         }
01415 
01416         cfg = os_zalloc(sizeof(*cfg));
01417         if (cfg == NULL)
01418                 goto failed;
01419         cfg->ctx = drv;
01420         cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
01421         cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
01422         drv->netlink = netlink_init(cfg);
01423         if (drv->netlink == NULL) {
01424                 os_free(cfg);
01425                 goto failed;
01426         }
01427         if (wpa_driver_nl80211_finish_drv_init(drv))
01428                 goto failed;
01429 
01430         return bss;
01431 
01432 failed:
01433         netlink_deinit(drv->netlink);
01434         if (drv->ioctl_sock >= 0)
01435                 close(drv->ioctl_sock);
01436 
01437         genl_family_put(drv->nl80211);
01438         nl_cache_free(drv->nl_cache);
01439         nl_handle_destroy(drv->nl_handle);
01440         nl_cb_put(drv->nl_cb);
01441         eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle_event));
01442 
01443         os_free(drv);
01444         return NULL;
01445 }
01446 
01447 
01448 static int nl80211_register_action_frame(struct wpa_driver_nl80211_data *drv,
01449                                          const u8 *match, size_t match_len)
01450 {
01451         struct nl_msg *msg;
01452         int ret = -1;
01453 
01454         msg = nlmsg_alloc();
01455         if (!msg)
01456                 return -1;
01457 
01458         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
01459                     NL80211_CMD_REGISTER_ACTION, 0);
01460 
01461         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
01462         NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
01463 
01464         ret = send_and_recv(drv, drv->nl_handle_event, msg, NULL, NULL);
01465         msg = NULL;
01466         if (ret) {
01467                 wpa_printf(MSG_DEBUG, "nl80211: Register Action command "
01468                            "failed: ret=%d (%s)", ret, strerror(-ret));
01469                 wpa_hexdump(MSG_DEBUG, "nl80211: Register Action match",
01470                             match, match_len);
01471                 goto nla_put_failure;
01472         }
01473         ret = 0;
01474 nla_put_failure:
01475         nlmsg_free(msg);
01476         return ret;
01477 }
01478 
01479 
01480 static int nl80211_register_action_frames(struct wpa_driver_nl80211_data *drv)
01481 {
01482         /* FT Action frames */
01483         if (nl80211_register_action_frame(drv, (u8 *) "\x06", 1) < 0)
01484                 return -1;
01485         else
01486                 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
01487                         WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
01488 
01489         return 0;
01490 }
01491 
01492 
01493 static int
01494 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
01495 {
01496         struct i802_bss *bss = &drv->first_bss;
01497 
01498         drv->ifindex = if_nametoindex(bss->ifname);
01499         drv->first_bss.ifindex = drv->ifindex;
01500 
01501 #ifndef HOSTAPD
01502         if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA) < 0) {
01503                 wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
01504                            "use managed mode");
01505         }
01506 
01507         if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1)) {
01508                 wpa_printf(MSG_ERROR, "Could not set interface '%s' UP",
01509                            bss->ifname);
01510                 return -1;
01511         }
01512 
01513         if (wpa_driver_nl80211_capa(drv))
01514                 return -1;
01515 
01516         netlink_send_oper_ifla(drv->netlink, drv->ifindex,
01517                                1, IF_OPER_DORMANT);
01518 #endif /* HOSTAPD */
01519 
01520         if (nl80211_register_action_frames(drv) < 0) {
01521                 wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
01522                            "frame processing - ignore for now");
01523                 /*
01524                  * Older kernel versions did not support this, so ignore the
01525                  * error for now. Some functionality may not be available
01526                  * because of this.
01527                  */
01528         }
01529 
01530         return 0;
01531 }
01532 
01533 
01534 static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
01535 {
01536         struct nl_msg *msg;
01537 
01538         msg = nlmsg_alloc();
01539         if (!msg)
01540                 return -ENOMEM;
01541 
01542         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
01543                     0, NL80211_CMD_DEL_BEACON, 0);
01544         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
01545 
01546         return send_and_recv_msgs(drv, msg, NULL, NULL);
01547  nla_put_failure:
01548         return -ENOBUFS;
01549 }
01550 
01551 
01559 static void wpa_driver_nl80211_deinit(void *priv)
01560 {
01561         struct i802_bss *bss = priv;
01562         struct wpa_driver_nl80211_data *drv = bss->drv;
01563 
01564         if (drv->added_if_into_bridge) {
01565                 if (linux_br_del_if(drv->ioctl_sock, drv->brname, bss->ifname)
01566                     < 0)
01567                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
01568                                    "interface %s from bridge %s: %s",
01569                                    bss->ifname, drv->brname, strerror(errno));
01570         }
01571         if (drv->added_bridge) {
01572                 if (linux_br_del(drv->ioctl_sock, drv->brname) < 0)
01573                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
01574                                    "bridge %s: %s",
01575                                    drv->brname, strerror(errno));
01576         }
01577 
01578         nl80211_remove_monitor_interface(drv);
01579 
01580         if (drv->nlmode == NL80211_IFTYPE_AP)
01581                 wpa_driver_nl80211_del_beacon(drv);
01582 
01583 #ifdef HOSTAPD
01584         if (drv->last_freq_ht) {
01585                 /* Clear HT flags from the driver */
01586                 struct hostapd_freq_params freq;
01587                 os_memset(&freq, 0, sizeof(freq));
01588                 freq.freq = drv->last_freq;
01589                 i802_set_freq(priv, &freq);
01590         }
01591 
01592         if (drv->eapol_sock >= 0) {
01593                 eloop_unregister_read_sock(drv->eapol_sock);
01594                 close(drv->eapol_sock);
01595         }
01596 
01597         if (drv->if_indices != drv->default_if_indices)
01598                 os_free(drv->if_indices);
01599 #endif /* HOSTAPD */
01600 
01601         if (drv->disable_11b_rates)
01602                 nl80211_disable_11b_rates(drv, drv->ifindex, 0);
01603 
01604         netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP);
01605         netlink_deinit(drv->netlink);
01606 
01607         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
01608 
01609         (void) linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
01610         wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA);
01611 
01612         if (drv->ioctl_sock >= 0)
01613                 close(drv->ioctl_sock);
01614 
01615         eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle_event));
01616         genl_family_put(drv->nl80211);
01617         nl_cache_free(drv->nl_cache);
01618         nl_cache_free(drv->nl_cache_event);
01619         nl_handle_destroy(drv->nl_handle);
01620         nl_handle_destroy(drv->nl_handle_event);
01621         nl_cb_put(drv->nl_cb);
01622 
01623         eloop_cancel_timeout(wpa_driver_nl80211_probe_req_report_timeout,
01624                              drv, NULL);
01625 
01626         os_free(drv->filter_ssids);
01627 
01628         os_free(drv);
01629 }
01630 
01631 
01640 static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
01641 {
01642         struct wpa_driver_nl80211_data *drv = eloop_ctx;
01643         if (drv->ap_scan_as_station) {
01644                 wpa_driver_nl80211_set_mode(&drv->first_bss,
01645                                             IEEE80211_MODE_AP);
01646                 drv->ap_scan_as_station = 0;
01647         }
01648         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
01649         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
01650 }
01651 
01652 
01659 static int wpa_driver_nl80211_scan(void *priv,
01660                                    struct wpa_driver_scan_params *params)
01661 {
01662         struct i802_bss *bss = priv;
01663         struct wpa_driver_nl80211_data *drv = bss->drv;
01664         int ret = 0, timeout;
01665         struct nl_msg *msg, *ssids, *freqs;
01666         size_t i;
01667         int num_freqs = 0;
01668 
01669         msg = nlmsg_alloc();
01670         ssids = nlmsg_alloc();
01671         freqs = nlmsg_alloc();
01672         if (!msg || !ssids || !freqs) {
01673                 nlmsg_free(msg);
01674                 nlmsg_free(ssids);
01675                 nlmsg_free(freqs);
01676                 return -1;
01677         }
01678 
01679         os_free(drv->filter_ssids);
01680         drv->filter_ssids = params->filter_ssids;
01681         params->filter_ssids = NULL;
01682         drv->num_filter_ssids = params->num_filter_ssids;
01683 
01684         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
01685                     NL80211_CMD_TRIGGER_SCAN, 0);
01686 
01687         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
01688 
01689         for (i = 0; i < params->num_ssids; i++) {
01690                 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
01691                                   params->ssids[i].ssid,
01692                                   params->ssids[i].ssid_len);
01693                 NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
01694                         params->ssids[i].ssid);
01695         }
01696         if (!params->num_ssids)
01697           NLA_PUT(ssids, 1, 0, "");
01698         nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
01699 
01700         if (params->extra_ies) {
01701                 wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan extra IEs",
01702                                   params->extra_ies, params->extra_ies_len);
01703                 NLA_PUT(msg, NL80211_ATTR_IE, params->extra_ies_len,
01704                         params->extra_ies);
01705         }
01706 
01707         if (params->freqs) {
01708                 for (i = 0; params->freqs[i]; i++) {
01709                         wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
01710                                    "MHz", params->freqs[i]);
01711                         NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
01712                 }
01713                 num_freqs = i;
01714                 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
01715         }
01716 
01717         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
01718         msg = NULL;
01719         if (ret) {
01720                 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
01721                            "(%s)", ret, strerror(-ret));
01722 #ifdef HOSTAPD
01723                 if (drv->nlmode == NL80211_IFTYPE_AP) {
01724                         /*
01725                          * mac80211 does not allow scan requests in AP mode, so
01726                          * try to do this in station mode.
01727                          */
01728                         if (wpa_driver_nl80211_set_mode(bss,
01729                                                         IEEE80211_MODE_INFRA))
01730                                 goto nla_put_failure;
01731 
01732                         if (wpa_driver_nl80211_scan(drv, params)) {
01733                                 wpa_driver_nl80211_set_mode(bss,
01734                                                             IEEE80211_MODE_AP);
01735                                 goto nla_put_failure;
01736                         }
01737 
01738                         /* Restore AP mode when processing scan results */
01739                         drv->ap_scan_as_station = 1;
01740                         ret = 0;
01741                 } else
01742                         goto nla_put_failure;
01743 #else /* HOSTAPD */
01744                 goto nla_put_failure;
01745 #endif /* HOSTAPD */
01746         }
01747 
01748         /* Not all drivers generate "scan completed" wireless event, so try to
01749          * read results after a timeout. */
01750         timeout = 10000;
01751         if (num_freqs)
01752           timeout = num_freqs * 450;
01753         wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
01754                    "milliseconds", ret, timeout);
01755         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
01756         eloop_register_timeout(timeout / 1000, (timeout % 1000) * 1000, wpa_driver_nl80211_scan_timeout,
01757                                drv, drv->ctx);
01758 
01759 nla_put_failure:
01760         nlmsg_free(ssids);
01761         nlmsg_free(msg);
01762         nlmsg_free(freqs);
01763         return ret;
01764 }
01765 
01766 
01767 static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
01768 {
01769         const u8 *end, *pos;
01770 
01771         if (ies == NULL)
01772                 return NULL;
01773 
01774         pos = ies;
01775         end = ies + ies_len;
01776 
01777         while (pos + 1 < end) {
01778                 if (pos + 2 + pos[1] > end)
01779                         break;
01780                 if (pos[0] == ie)
01781                         return pos;
01782                 pos += 2 + pos[1];
01783         }
01784 
01785         return NULL;
01786 }
01787 
01788 
01789 static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
01790                                  const u8 *ie, size_t ie_len)
01791 {
01792         const u8 *ssid;
01793         size_t i;
01794 
01795         if (drv->filter_ssids == NULL)
01796                 return 0;
01797 
01798         ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
01799         if (ssid == NULL)
01800                 return 1;
01801 
01802         for (i = 0; i < drv->num_filter_ssids; i++) {
01803                 if (ssid[1] == drv->filter_ssids[i].ssid_len &&
01804                     os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
01805                     0)
01806                         return 0;
01807         }
01808 
01809         return 1;
01810 }
01811 
01812 
01813 struct nl80211_bss_info_arg {
01814         struct wpa_driver_nl80211_data *drv;
01815         struct wpa_scan_results *res;
01816 };
01817 
01818 static int bss_info_handler(struct nl_msg *msg, void *arg)
01819 {
01820         struct nlattr *tb[NL80211_ATTR_MAX + 1];
01821         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
01822         struct nlattr *bss[NL80211_BSS_MAX + 1];
01823         static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
01824                 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
01825                 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
01826                 [NL80211_BSS_TSF] = { .type = NLA_U64 },
01827                 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
01828                 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
01829                 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
01830                 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
01831                 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
01832                 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
01833                 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
01834                 [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
01835         };
01836         struct nl80211_bss_info_arg *_arg = arg;
01837         struct wpa_scan_results *res = _arg->res;
01838         struct wpa_scan_res **tmp;
01839         struct wpa_scan_res *r;
01840         const u8 *ie, *beacon_ie;
01841         size_t ie_len, beacon_ie_len;
01842         u8 *pos;
01843 
01844         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
01845                   genlmsg_attrlen(gnlh, 0), NULL);
01846         if (!tb[NL80211_ATTR_BSS])
01847                 return NL_SKIP;
01848         if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
01849                              bss_policy))
01850                 return NL_SKIP;
01851         if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
01852                 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
01853                 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
01854         } else {
01855                 ie = NULL;
01856                 ie_len = 0;
01857         }
01858         if (bss[NL80211_BSS_BEACON_IES]) {
01859                 beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
01860                 beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
01861         } else {
01862                 beacon_ie = NULL;
01863                 beacon_ie_len = 0;
01864         }
01865 
01866         if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
01867                                   ie ? ie_len : beacon_ie_len))
01868                 return NL_SKIP;
01869 
01870         r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
01871         if (r == NULL)
01872                 return NL_SKIP;
01873         if (bss[NL80211_BSS_BSSID])
01874                 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
01875                           ETH_ALEN);
01876         if (bss[NL80211_BSS_FREQUENCY])
01877                 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
01878         if (bss[NL80211_BSS_BEACON_INTERVAL])
01879                 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
01880         if (bss[NL80211_BSS_CAPABILITY])
01881                 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
01882         r->flags |= WPA_SCAN_NOISE_INVALID;
01883         if (bss[NL80211_BSS_SIGNAL_MBM]) {
01884                 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
01885                 r->level /= 100; /* mBm to dBm */
01886                 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
01887         } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
01888                 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
01889                 r->flags |= WPA_SCAN_LEVEL_INVALID;
01890         } else
01891                 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
01892         if (bss[NL80211_BSS_TSF])
01893                 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
01894         if (bss[NL80211_BSS_SEEN_MS_AGO])
01895                 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
01896         r->ie_len = ie_len;
01897         pos = (u8 *) (r + 1);
01898         if (ie) {
01899                 os_memcpy(pos, ie, ie_len);
01900                 pos += ie_len;
01901         }
01902         r->beacon_ie_len = beacon_ie_len;
01903         if (beacon_ie)
01904                 os_memcpy(pos, beacon_ie, beacon_ie_len);
01905 
01906         if (bss[NL80211_BSS_STATUS]) {
01907                 enum nl80211_bss_status status;
01908                 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
01909                 switch (status) {
01910                 case NL80211_BSS_STATUS_AUTHENTICATED:
01911                         r->flags |= WPA_SCAN_AUTHENTICATED;
01912                         break;
01913                 case NL80211_BSS_STATUS_ASSOCIATED:
01914                         r->flags |= WPA_SCAN_ASSOCIATED;
01915                         break;
01916                 default:
01917                         break;
01918                 }
01919         }
01920 
01921         tmp = os_realloc(res->res,
01922                          (res->num + 1) * sizeof(struct wpa_scan_res *));
01923         if (tmp == NULL) {
01924                 os_free(r);
01925                 return NL_SKIP;
01926         }
01927         tmp[res->num++] = r;
01928         res->res = tmp;
01929 
01930         return NL_SKIP;
01931 }
01932 
01933 
01934 static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
01935                                  const u8 *addr)
01936 {
01937         if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
01938                 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
01939                            "mismatch (" MACSTR ")", MAC2STR(addr));
01940                 wpa_driver_nl80211_mlme(drv, addr,
01941                                         NL80211_CMD_DEAUTHENTICATE,
01942                                         WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
01943         }
01944 }
01945 
01946 
01947 static void wpa_driver_nl80211_check_bss_status(
01948         struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
01949 {
01950         size_t i;
01951 
01952         for (i = 0; i < res->num; i++) {
01953                 struct wpa_scan_res *r = res->res[i];
01954                 if (r->flags & WPA_SCAN_AUTHENTICATED) {
01955                         wpa_printf(MSG_DEBUG, "nl80211: Scan results "
01956                                    "indicates BSS status with " MACSTR
01957                                    " as authenticated",
01958                                    MAC2STR(r->bssid));
01959                         if (drv->nlmode == NL80211_IFTYPE_STATION &&
01960                             os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
01961                             os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
01962                             0) {
01963                                 wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
01964                                            " in local state (auth=" MACSTR
01965                                            " assoc=" MACSTR ")",
01966                                            MAC2STR(drv->auth_bssid),
01967                                            MAC2STR(drv->bssid));
01968                                 clear_state_mismatch(drv, r->bssid);
01969                         }
01970                 }
01971 
01972                 if (r->flags & WPA_SCAN_ASSOCIATED) {
01973                         wpa_printf(MSG_DEBUG, "nl80211: Scan results "
01974                                    "indicate BSS status with " MACSTR
01975                                    " as associated",
01976                                    MAC2STR(r->bssid));
01977                         if (drv->nlmode == NL80211_IFTYPE_STATION &&
01978                             !drv->associated) {
01979                                 wpa_printf(MSG_DEBUG, "nl80211: Local state "
01980                                            "(not associated) does not match "
01981                                            "with BSS state");
01982                                 clear_state_mismatch(drv, r->bssid);
01983                         } else if (drv->nlmode == NL80211_IFTYPE_STATION &&
01984                                    os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
01985                                    0) {
01986                                 wpa_printf(MSG_DEBUG, "nl80211: Local state "
01987                                            "(associated with " MACSTR ") does "
01988                                            "not match with BSS state",
01989                                            MAC2STR(drv->bssid));
01990                                 clear_state_mismatch(drv, r->bssid);
01991                                 clear_state_mismatch(drv, drv->bssid);
01992                         }
01993                 }
01994         }
01995 }
01996 
01997 
01998 static void wpa_scan_results_free(struct wpa_scan_results *res)
01999 {
02000         size_t i;
02001 
02002         if (res == NULL)
02003                 return;
02004 
02005         for (i = 0; i < res->num; i++)
02006                 os_free(res->res[i]);
02007         os_free(res->res);
02008         os_free(res);
02009 }
02010 
02011 
02012 static struct wpa_scan_results *
02013 nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
02014 {
02015         struct nl_msg *msg;
02016         struct wpa_scan_results *res;
02017         int ret;
02018         struct nl80211_bss_info_arg arg;
02019 
02020         res = os_zalloc(sizeof(*res));
02021         if (res == NULL)
02022                 return NULL;
02023         msg = nlmsg_alloc();
02024         if (!msg)
02025                 goto nla_put_failure;
02026 
02027         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP,
02028                     NL80211_CMD_GET_SCAN, 0);
02029         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
02030 
02031         arg.drv = drv;
02032         arg.res = res;
02033         ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
02034         msg = NULL;
02035         if (ret == 0) {
02036                 wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)",
02037                            (unsigned long) res->num);
02038                 return res;
02039         }
02040         wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
02041                    "(%s)", ret, strerror(-ret));
02042 nla_put_failure:
02043         nlmsg_free(msg);
02044         wpa_scan_results_free(res);
02045         return NULL;
02046 }
02047 
02048 
02054 static struct wpa_scan_results *
02055 wpa_driver_nl80211_get_scan_results(void *priv)
02056 {
02057         struct i802_bss *bss = priv;
02058         struct wpa_driver_nl80211_data *drv = bss->drv;
02059         struct wpa_scan_results *res;
02060 
02061         res = nl80211_get_scan_results(drv);
02062         if (res)
02063                 wpa_driver_nl80211_check_bss_status(drv, res);
02064         return res;
02065 }
02066 
02067 
02068 static void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
02069 {
02070         struct wpa_scan_results *res;
02071         size_t i;
02072 
02073         res = nl80211_get_scan_results(drv);
02074         if (res == NULL) {
02075                 wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
02076                 return;
02077         }
02078 
02079         wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
02080         for (i = 0; i < res->num; i++) {
02081                 struct wpa_scan_res *r = res->res[i];
02082                 wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s%s",
02083                            (int) i, (int) res->num, MAC2STR(r->bssid),
02084                            r->flags & WPA_SCAN_AUTHENTICATED ? " [auth]" : "",
02085                            r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
02086         }
02087 
02088         wpa_scan_results_free(res);
02089 }
02090 
02091 
02092 static int wpa_driver_nl80211_set_key(const char *ifname, void *priv,
02093                                       enum wpa_alg alg, const u8 *addr,
02094                                       int key_idx, int set_tx,
02095                                       const u8 *seq, size_t seq_len,
02096                                       const u8 *key, size_t key_len)
02097 {
02098         struct i802_bss *bss = priv;
02099         struct wpa_driver_nl80211_data *drv = bss->drv;
02100         int ifindex = if_nametoindex(ifname);
02101         struct nl_msg *msg;
02102         int ret;
02103 
02104         wpa_printf(MSG_DEBUG, "%s: ifindex=%d alg=%d addr=%p key_idx=%d "
02105                    "set_tx=%d seq_len=%lu key_len=%lu",
02106                    __func__, ifindex, alg, addr, key_idx, set_tx,
02107                    (unsigned long) seq_len, (unsigned long) key_len);
02108 
02109         msg = nlmsg_alloc();
02110         if (!msg)
02111                 return -ENOMEM;
02112 
02113         if (alg == WPA_ALG_NONE) {
02114                 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
02115                             0, NL80211_CMD_DEL_KEY, 0);
02116         } else {
02117                 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
02118                             0, NL80211_CMD_NEW_KEY, 0);
02119                 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
02120                 switch (alg) {
02121                 case WPA_ALG_WEP:
02122                         if (key_len == 5)
02123                                 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
02124                                             WLAN_CIPHER_SUITE_WEP40);
02125                         else
02126                                 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
02127                                             WLAN_CIPHER_SUITE_WEP104);
02128                         break;
02129                 case WPA_ALG_TKIP:
02130                         NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
02131                                     WLAN_CIPHER_SUITE_TKIP);
02132                         break;
02133                 case WPA_ALG_CCMP:
02134                         NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
02135                                     WLAN_CIPHER_SUITE_CCMP);
02136                         break;
02137                 case WPA_ALG_IGTK:
02138                         NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
02139                                     WLAN_CIPHER_SUITE_AES_CMAC);
02140                         break;
02141                 default:
02142                         wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
02143                                    "algorithm %d", __func__, alg);
02144                         nlmsg_free(msg);
02145                         return -1;
02146                 }
02147         }
02148 
02149         if (seq && seq_len)
02150                 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
02151 
02152         if (addr && os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
02153         {
02154                 wpa_printf(MSG_DEBUG, "   addr=" MACSTR, MAC2STR(addr));
02155                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
02156         }
02157         NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
02158         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
02159 
02160         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
02161         if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
02162                 ret = 0;
02163         if (ret)
02164                 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
02165                            ret, strerror(-ret));
02166 
02167         /*
02168          * If we failed or don't need to set the default TX key (below),
02169          * we're done here.
02170          */
02171         if (ret || !set_tx || alg == WPA_ALG_NONE)
02172                 return ret;
02173 #ifdef HOSTAPD
02174         if (addr)
02175                 return ret;
02176 #else /* HOSTAPD */
02177         if (drv->nlmode == NL80211_IFTYPE_AP && addr)
02178                 return ret;
02179 #endif /* HOSTAPD */
02180 
02181         msg = nlmsg_alloc();
02182         if (!msg)
02183                 return -ENOMEM;
02184 
02185         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
02186                     0, NL80211_CMD_SET_KEY, 0);
02187         NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
02188         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
02189         if (alg == WPA_ALG_IGTK)
02190                 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
02191         else
02192                 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
02193 
02194         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
02195         if (ret == -ENOENT)
02196                 ret = 0;
02197         if (ret)
02198                 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
02199                            "err=%d %s)", ret, strerror(-ret));
02200         return ret;
02201 
02202 nla_put_failure:
02203         return -ENOBUFS;
02204 }
02205 
02206 
02207 static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
02208                       int key_idx, int defkey,
02209                       const u8 *seq, size_t seq_len,
02210                       const u8 *key, size_t key_len)
02211 {
02212         struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
02213         if (!key_attr)
02214                 return -1;
02215 
02216         if (defkey && alg == WPA_ALG_IGTK)
02217                 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
02218         else if (defkey)
02219                 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
02220 
02221         NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
02222 
02223         switch (alg) {
02224         case WPA_ALG_WEP:
02225                 if (key_len == 5)
02226                         NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
02227                                     WLAN_CIPHER_SUITE_WEP40);
02228                 else
02229                         NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
02230                                     WLAN_CIPHER_SUITE_WEP104);
02231                 break;
02232         case WPA_ALG_TKIP:
02233                 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_TKIP);
02234                 break;
02235         case WPA_ALG_CCMP:
02236                 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_CCMP);
02237                 break;
02238         case WPA_ALG_IGTK:
02239                 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
02240                             WLAN_CIPHER_SUITE_AES_CMAC);
02241                 break;
02242         default:
02243                 wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
02244                            "algorithm %d", __func__, alg);
02245                 return -1;
02246         }
02247 
02248         if (seq && seq_len)
02249                 NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
02250 
02251         NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
02252 
02253         nla_nest_end(msg, key_attr);
02254 
02255         return 0;
02256  nla_put_failure:
02257         return -1;
02258 }
02259 
02260 
02261 static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
02262                                  struct nl_msg *msg)
02263 {
02264         int i, privacy = 0;
02265         struct nlattr *nl_keys, *nl_key;
02266 
02267         for (i = 0; i < 4; i++) {
02268                 if (!params->wep_key[i])
02269                         continue;
02270                 privacy = 1;
02271                 break;
02272         }
02273         if (!privacy)
02274                 return 0;
02275 
02276         NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
02277 
02278         nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
02279         if (!nl_keys)
02280                 goto nla_put_failure;
02281 
02282         for (i = 0; i < 4; i++) {
02283                 if (!params->wep_key[i])
02284                         continue;
02285 
02286                 nl_key = nla_nest_start(msg, i);
02287                 if (!nl_key)
02288                         goto nla_put_failure;
02289 
02290                 NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
02291                         params->wep_key[i]);
02292                 if (params->wep_key_len[i] == 5)
02293                         NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
02294                                     WLAN_CIPHER_SUITE_WEP40);
02295                 else
02296                         NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
02297                                     WLAN_CIPHER_SUITE_WEP104);
02298 
02299                 NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
02300 
02301                 if (i == params->wep_tx_keyidx)
02302                         NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
02303 
02304                 nla_nest_end(msg, nl_key);
02305         }
02306         nla_nest_end(msg, nl_keys);
02307 
02308         return 0;
02309 
02310 nla_put_failure:
02311         return -ENOBUFS;
02312 }
02313 
02314 
02315 static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
02316                                    const u8 *addr, int cmd, u16 reason_code,
02317                                    int local_state_change)
02318 {
02319         int ret = -1;
02320         struct nl_msg *msg;
02321 
02322         msg = nlmsg_alloc();
02323         if (!msg)
02324                 return -1;
02325 
02326         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, cmd, 0);
02327 
02328         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
02329         NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
02330         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
02331         if (local_state_change)
02332                 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
02333 
02334         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
02335         msg = NULL;
02336         if (ret) {
02337                 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
02338                            "(%s)", ret, strerror(-ret));
02339                 goto nla_put_failure;
02340         }
02341         ret = 0;
02342 
02343 nla_put_failure:
02344         nlmsg_free(msg);
02345         return ret;
02346 }
02347 
02348 
02349 static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
02350                                          const u8 *addr, int reason_code)
02351 {
02352         wpa_printf(MSG_DEBUG, "%s", __func__);
02353         drv->associated = 0;
02354         return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISCONNECT,
02355                                        reason_code, 0);
02356 }
02357 
02358 
02359 static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,
02360                                              int reason_code)
02361 {
02362         struct i802_bss *bss = priv;
02363         struct wpa_driver_nl80211_data *drv = bss->drv;
02364         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
02365                 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
02366         wpa_printf(MSG_DEBUG, "%s", __func__);
02367         drv->associated = 0;
02368         return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
02369                                        reason_code, 0);
02370 }
02371 
02372 
02373 static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,
02374                                            int reason_code)
02375 {
02376         struct i802_bss *bss = priv;
02377         struct wpa_driver_nl80211_data *drv = bss->drv;
02378         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
02379                 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
02380         wpa_printf(MSG_DEBUG, "%s", __func__);
02381         drv->associated = 0;
02382         return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISASSOCIATE,
02383                                        reason_code, 0);
02384 }
02385 
02386 
02387 static int wpa_driver_nl80211_authenticate(
02388         void *priv, struct wpa_driver_auth_params *params)
02389 {
02390         struct i802_bss *bss = priv;
02391         struct wpa_driver_nl80211_data *drv = bss->drv;
02392         int ret = -1, i;
02393         struct nl_msg *msg;
02394         enum nl80211_auth_type type;
02395         int count = 0;
02396 
02397         drv->associated = 0;
02398         os_memset(drv->auth_bssid, 0, ETH_ALEN);
02399         /* FIX: IBSS mode */
02400         if (drv->nlmode != NL80211_IFTYPE_STATION)
02401                 wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
02402 
02403         if (wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA) < 0)
02404                 return -1;
02405 
02406 retry:
02407         msg = nlmsg_alloc();
02408         if (!msg)
02409                 return -1;
02410 
02411         wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
02412                    drv->ifindex);
02413 
02414         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
02415                     NL80211_CMD_AUTHENTICATE, 0);
02416 
02417         for (i = 0; i < 4; i++) {
02418                 if (!params->wep_key[i])
02419                         continue;
02420                 wpa_driver_nl80211_set_key(bss->ifname, priv, WPA_ALG_WEP,
02421                                            NULL, i,
02422                                            i == params->wep_tx_keyidx, NULL, 0,
02423                                            params->wep_key[i],
02424                                            params->wep_key_len[i]);
02425                 if (params->wep_tx_keyidx != i)
02426                         continue;
02427                 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
02428                                params->wep_key[i], params->wep_key_len[i])) {
02429                         nlmsg_free(msg);
02430                         return -1;
02431                 }
02432         }
02433 
02434         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
02435         if (params->bssid) {
02436                 wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
02437                            MAC2STR(params->bssid));
02438                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
02439         }
02440         if (params->freq) {
02441                 wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
02442                 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
02443         }
02444         if (params->ssid) {
02445                 wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
02446                                   params->ssid, params->ssid_len);
02447                 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
02448                         params->ssid);
02449         }
02450         wpa_hexdump(MSG_DEBUG, "  * IEs", params->ie, params->ie_len);
02451         if (params->ie)
02452                 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
02453         /*
02454          * TODO: if multiple auth_alg options enabled, try them one by one if
02455          * the AP rejects authentication due to unknown auth alg
02456          */
02457         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
02458                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
02459         else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
02460                 type = NL80211_AUTHTYPE_SHARED_KEY;
02461         else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
02462                 type = NL80211_AUTHTYPE_NETWORK_EAP;
02463         else if (params->auth_alg & WPA_AUTH_ALG_FT)
02464                 type = NL80211_AUTHTYPE_FT;
02465         else
02466                 goto nla_put_failure;
02467         wpa_printf(MSG_DEBUG, "  * Auth Type %d", type);
02468         NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
02469         if (params->local_state_change) {
02470                 wpa_printf(MSG_DEBUG, "  * Local state change only");
02471                 NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
02472         }
02473 
02474         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
02475         msg = NULL;
02476         if (ret) {
02477                 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
02478                            "(%s)", ret, strerror(-ret));
02479                 count++;
02480                 if (ret == -EALREADY && count == 1 && params->bssid &&
02481                     !params->local_state_change) {
02482                         /*
02483                          * mac80211 does not currently accept new
02484                          * authentication if we are already authenticated. As a
02485                          * workaround, force deauthentication and try again.
02486                          */
02487                         drv->deauth_before_reauth = 1;
02488                         wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
02489                                    "after forced deauthentication");
02490                         wpa_driver_nl80211_deauthenticate(
02491                                 bss, params->bssid,
02492                                 WLAN_REASON_PREV_AUTH_NOT_VALID);
02493                         nlmsg_free(msg);
02494                         goto retry;
02495                 }
02496                 goto nla_put_failure;
02497         }
02498         ret = 0;
02499         wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
02500                    "successfully");
02501 
02502 nla_put_failure:
02503         nlmsg_free(msg);
02504         return ret;
02505 }
02506 
02507 
02508 struct phy_info_arg {
02509         u16 *num_modes;
02510         struct hostapd_hw_modes *modes;
02511 };
02512 
02513 static int phy_info_handler(struct nl_msg *msg, void *arg)
02514 {
02515         struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
02516         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
02517         struct phy_info_arg *phy_info = arg;
02518 
02519         struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
02520 
02521         struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
02522         static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
02523                 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
02524                 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
02525                 [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
02526                 [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },
02527                 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
02528                 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
02529         };
02530 
02531         struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
02532         static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
02533                 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
02534                 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG },
02535         };
02536 
02537         struct nlattr *nl_band;
02538         struct nlattr *nl_freq;
02539         struct nlattr *nl_rate;
02540         int rem_band, rem_freq, rem_rate;
02541         struct hostapd_hw_modes *mode;
02542         int idx, mode_is_set;
02543 
02544         nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
02545                   genlmsg_attrlen(gnlh, 0), NULL);
02546 
02547         if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
02548                 return NL_SKIP;
02549 
02550         nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) {
02551                 mode = os_realloc(phy_info->modes, (*phy_info->num_modes + 1) * sizeof(*mode));
02552                 if (!mode)
02553                         return NL_SKIP;
02554                 phy_info->modes = mode;
02555 
02556                 mode_is_set = 0;
02557 
02558                 mode = &phy_info->modes[*(phy_info->num_modes)];
02559                 memset(mode, 0, sizeof(*mode));
02560                 *(phy_info->num_modes) += 1;
02561 
02562                 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
02563                           nla_len(nl_band), NULL);
02564 
02565                 if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
02566                         mode->ht_capab = nla_get_u16(
02567                                 tb_band[NL80211_BAND_ATTR_HT_CAPA]);
02568                 }
02569 
02570                 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) {
02571                         mode->a_mpdu_params |= nla_get_u8(
02572                                 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) &
02573                                 0x03;
02574                 }
02575 
02576                 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) {
02577                         mode->a_mpdu_params |= nla_get_u8(
02578                                 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) <<
02579                                 2;
02580                 }
02581 
02582                 if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] &&
02583                     nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET])) {
02584                         u8 *mcs;
02585                         mcs = nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
02586                         os_memcpy(mode->mcs_set, mcs, 16);
02587                 }
02588 
02589                 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
02590                         nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
02591                                   nla_len(nl_freq), freq_policy);
02592                         if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
02593                                 continue;
02594                         mode->num_channels++;
02595                 }
02596 
02597                 mode->channels = os_zalloc(mode->num_channels * sizeof(struct hostapd_channel_data));
02598                 if (!mode->channels)
02599                         return NL_SKIP;
02600 
02601                 idx = 0;
02602 
02603                 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
02604                         nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
02605                                   nla_len(nl_freq), freq_policy);
02606                         if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
02607                                 continue;
02608 
02609                         mode->channels[idx].freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
02610                         mode->channels[idx].flag = 0;
02611 
02612                         if (!mode_is_set) {
02613                                 /* crude heuristic */
02614                                 if (mode->channels[idx].freq < 4000)
02615                                         mode->mode = HOSTAPD_MODE_IEEE80211B;
02616                                 else
02617                                         mode->mode = HOSTAPD_MODE_IEEE80211A;
02618                                 mode_is_set = 1;
02619                         }
02620 
02621                         /* crude heuristic */
02622                         if (mode->channels[idx].freq < 4000)
02623                                 if (mode->channels[idx].freq == 2484)
02624                                         mode->channels[idx].chan = 14;
02625                                 else
02626                                         mode->channels[idx].chan = (mode->channels[idx].freq - 2407) / 5;
02627                         else
02628                                 mode->channels[idx].chan = mode->channels[idx].freq/5 - 1000;
02629 
02630                         if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
02631                                 mode->channels[idx].flag |=
02632                                         HOSTAPD_CHAN_DISABLED;
02633                         if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
02634                                 mode->channels[idx].flag |=
02635                                         HOSTAPD_CHAN_PASSIVE_SCAN;
02636                         if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])
02637                                 mode->channels[idx].flag |=
02638                                         HOSTAPD_CHAN_NO_IBSS;
02639                         if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
02640                                 mode->channels[idx].flag |=
02641                                         HOSTAPD_CHAN_RADAR;
02642 
02643                         if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] &&
02644                             !tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
02645                                 mode->channels[idx].max_tx_power =
02646                                         nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) / 100;
02647 
02648                         idx++;
02649                 }
02650 
02651                 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
02652                         nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
02653                                   nla_len(nl_rate), rate_policy);
02654                         if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
02655                                 continue;
02656                         mode->num_rates++;
02657                 }
02658 
02659                 mode->rates = os_zalloc(mode->num_rates * sizeof(int));
02660                 if (!mode->rates)
02661                         return NL_SKIP;
02662 
02663                 idx = 0;
02664 
02665                 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
02666                         nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
02667                                   nla_len(nl_rate), rate_policy);
02668                         if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
02669                                 continue;
02670                         mode->rates[idx] = nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE]);
02671 
02672                         /* crude heuristic */
02673                         if (mode->mode == HOSTAPD_MODE_IEEE80211B &&
02674                             mode->rates[idx] > 200)
02675                                 mode->mode = HOSTAPD_MODE_IEEE80211G;
02676 
02677                         idx++;
02678                 }
02679         }
02680 
02681         return NL_SKIP;
02682 }
02683 
02684 static struct hostapd_hw_modes *
02685 wpa_driver_nl80211_add_11b(struct hostapd_hw_modes *modes, u16 *num_modes)
02686 {
02687         u16 m;
02688         struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
02689         int i, mode11g_idx = -1;
02690 
02691         /* If only 802.11g mode is included, use it to construct matching
02692          * 802.11b mode data. */
02693 
02694         for (m = 0; m < *num_modes; m++) {
02695                 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
02696                         return modes; /* 802.11b already included */
02697                 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
02698                         mode11g_idx = m;
02699         }
02700 
02701         if (mode11g_idx < 0)
02702                 return modes; /* 2.4 GHz band not supported at all */
02703 
02704         nmodes = os_realloc(modes, (*num_modes + 1) * sizeof(*nmodes));
02705         if (nmodes == NULL)
02706                 return modes; /* Could not add 802.11b mode */
02707 
02708         mode = &nmodes[*num_modes];
02709         os_memset(mode, 0, sizeof(*mode));
02710         (*num_modes)++;
02711         modes = nmodes;
02712 
02713         mode->mode = HOSTAPD_MODE_IEEE80211B;
02714 
02715         mode11g = &modes[mode11g_idx];
02716         mode->num_channels = mode11g->num_channels;
02717         mode->channels = os_malloc(mode11g->num_channels *
02718                                    sizeof(struct hostapd_channel_data));
02719         if (mode->channels == NULL) {
02720                 (*num_modes)--;
02721                 return modes; /* Could not add 802.11b mode */
02722         }
02723         os_memcpy(mode->channels, mode11g->channels,
02724                   mode11g->num_channels * sizeof(struct hostapd_channel_data));
02725 
02726         mode->num_rates = 0;
02727         mode->rates = os_malloc(4 * sizeof(int));
02728         if (mode->rates == NULL) {
02729                 os_free(mode->channels);
02730                 (*num_modes)--;
02731                 return modes; /* Could not add 802.11b mode */
02732         }
02733 
02734         for (i = 0; i < mode11g->num_rates; i++) {
02735                 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
02736                     mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
02737                         continue;
02738                 mode->rates[mode->num_rates] = mode11g->rates[i];
02739                 mode->num_rates++;
02740                 if (mode->num_rates == 4)
02741                         break;
02742         }
02743 
02744         if (mode->num_rates == 0) {
02745                 os_free(mode->channels);
02746                 os_free(mode->rates);
02747                 (*num_modes)--;
02748                 return modes; /* No 802.11b rates */
02749         }
02750 
02751         wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
02752                    "information");
02753 
02754         return modes;
02755 }
02756 
02757 
02758 static struct hostapd_hw_modes *
02759 wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
02760 {
02761         struct i802_bss *bss = priv;
02762         struct wpa_driver_nl80211_data *drv = bss->drv;
02763         struct nl_msg *msg;
02764         struct phy_info_arg result = {
02765                 .num_modes = num_modes,
02766                 .modes = NULL,
02767         };
02768 
02769         *num_modes = 0;
02770         *flags = 0;
02771 
02772         msg = nlmsg_alloc();
02773         if (!msg)
02774                 return NULL;
02775 
02776         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
02777                     0, NL80211_CMD_GET_WIPHY, 0);
02778 
02779         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
02780 
02781         if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0)
02782                 return wpa_driver_nl80211_add_11b(result.modes, num_modes);
02783  nla_put_failure:
02784         return NULL;
02785 }
02786 
02787 
02788 static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
02789                                          const void *data, size_t len,
02790                                          int encrypt)
02791 {
02792         __u8 rtap_hdr[] = {
02793                 0x00, 0x00, /* radiotap version */
02794                 0x0e, 0x00, /* radiotap length */
02795                 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
02796                 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
02797                 0x00,       /* padding */
02798                 0x00, 0x00, /* RX and TX flags to indicate that */
02799                 0x00, 0x00, /* this is the injected frame directly */
02800         };
02801         struct iovec iov[2] = {
02802                 {
02803                         .iov_base = &rtap_hdr,
02804                         .iov_len = sizeof(rtap_hdr),
02805                 },
02806                 {
02807                         .iov_base = (void *) data,
02808                         .iov_len = len,
02809                 }
02810         };
02811         struct msghdr msg = {
02812                 .msg_name = NULL,
02813                 .msg_namelen = 0,
02814                 .msg_iov = iov,
02815                 .msg_iovlen = 2,
02816                 .msg_control = NULL,
02817                 .msg_controllen = 0,
02818                 .msg_flags = 0,
02819         };
02820 
02821         if (encrypt)
02822                 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
02823 
02824         return sendmsg(drv->monitor_sock, &msg, 0);
02825 }
02826 
02827 
02828 static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
02829                                         size_t data_len)
02830 {
02831         struct i802_bss *bss = priv;
02832         struct wpa_driver_nl80211_data *drv = bss->drv;
02833         struct ieee80211_mgmt *mgmt;
02834         int encrypt = 1;
02835         u16 fc;
02836 
02837         mgmt = (struct ieee80211_mgmt *) data;
02838         fc = le_to_host16(mgmt->frame_control);
02839 
02840         if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
02841             WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
02842                 /*
02843                  * Only one of the authentication frame types is encrypted.
02844                  * In order for static WEP encryption to work properly (i.e.,
02845                  * to not encrypt the frame), we need to tell mac80211 about
02846                  * the frames that must not be encrypted.
02847                  */
02848                 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
02849                 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
02850                 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
02851                         encrypt = 0;
02852         }
02853 
02854         return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt);
02855 }
02856 
02857 
02858 static int wpa_driver_nl80211_set_beacon(void *priv,
02859                                          const u8 *head, size_t head_len,
02860                                          const u8 *tail, size_t tail_len,
02861                                          int dtim_period, int beacon_int)
02862 {
02863         struct i802_bss *bss = priv;
02864         struct wpa_driver_nl80211_data *drv = bss->drv;
02865         struct nl_msg *msg;
02866         u8 cmd = NL80211_CMD_NEW_BEACON;
02867         int ret;
02868         int beacon_set;
02869         int ifindex = if_nametoindex(bss->ifname);
02870 
02871         beacon_set = bss->beacon_set;
02872 
02873         msg = nlmsg_alloc();
02874         if (!msg)
02875                 return -ENOMEM;
02876 
02877         wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
02878                    beacon_set);
02879         if (beacon_set)
02880                 cmd = NL80211_CMD_SET_BEACON;
02881 
02882         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
02883                     0, cmd, 0);
02884         NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);
02885         NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);
02886         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
02887         NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, beacon_int);
02888         NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, dtim_period);
02889 
02890         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
02891         if (ret) {
02892                 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
02893                            ret, strerror(-ret));
02894         } else {
02895                 bss->beacon_set = 1;
02896         }
02897         return ret;
02898  nla_put_failure:
02899         return -ENOBUFS;
02900 }
02901 
02902 
02903 static int wpa_driver_nl80211_set_freq(struct wpa_driver_nl80211_data *drv,
02904                                        int freq, int ht_enabled,
02905                                        int sec_channel_offset)
02906 {
02907         struct nl_msg *msg;
02908         int ret;
02909 
02910         msg = nlmsg_alloc();
02911         if (!msg)
02912                 return -1;
02913 
02914         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
02915                     NL80211_CMD_SET_WIPHY, 0);
02916 
02917         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
02918         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
02919         if (ht_enabled) {
02920                 switch (sec_channel_offset) {
02921                 case -1:
02922                         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
02923                                     NL80211_CHAN_HT40MINUS);
02924                         break;
02925                 case 1:
02926                         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
02927                                     NL80211_CHAN_HT40PLUS);
02928                         break;
02929                 default:
02930                         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
02931                                     NL80211_CHAN_HT20);
02932                         break;
02933                 }
02934         }
02935 
02936         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
02937         if (ret == 0)
02938                 return 0;
02939         wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
02940                    "%d (%s)", freq, ret, strerror(-ret));
02941 nla_put_failure:
02942         return -1;
02943 }
02944 
02945 
02946 static int wpa_driver_nl80211_sta_add(void *priv,
02947                                       struct hostapd_sta_add_params *params)
02948 {
02949         struct i802_bss *bss = priv;
02950         struct wpa_driver_nl80211_data *drv = bss->drv;
02951         struct nl_msg *msg;
02952         int ret = -ENOBUFS;
02953 
02954         msg = nlmsg_alloc();
02955         if (!msg)
02956                 return -ENOMEM;
02957 
02958         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
02959                     0, NL80211_CMD_NEW_STATION, 0);
02960 
02961         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
02962         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
02963         NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
02964         NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
02965                 params->supp_rates);
02966         NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
02967                     params->listen_interval);
02968         if (params->ht_capabilities) {
02969                 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
02970                         sizeof(*params->ht_capabilities),
02971                         params->ht_capabilities);
02972         }
02973 
02974         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
02975         if (ret)
02976                 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_NEW_STATION "
02977                            "result: %d (%s)", ret, strerror(-ret));
02978         if (ret == -EEXIST)
02979                 ret = 0;
02980  nla_put_failure:
02981         return ret;
02982 }
02983 
02984 
02985 static int wpa_driver_nl80211_sta_remove(void *priv, const u8 *addr)
02986 {
02987         struct i802_bss *bss = priv;
02988         struct wpa_driver_nl80211_data *drv = bss->drv;
02989         struct nl_msg *msg;
02990         int ret;
02991 
02992         msg = nlmsg_alloc();
02993         if (!msg)
02994                 return -ENOMEM;
02995 
02996         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
02997                     0, NL80211_CMD_DEL_STATION, 0);
02998 
02999         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
03000                     if_nametoindex(bss->ifname));
03001         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
03002 
03003         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
03004         if (ret == -ENOENT)
03005                 return 0;
03006         return ret;
03007  nla_put_failure:
03008         return -ENOBUFS;
03009 }
03010 
03011 
03012 static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
03013                                  int ifidx)
03014 {
03015         struct nl_msg *msg;
03016 
03017         wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
03018 
03019 #ifdef HOSTAPD
03020         /* stop listening for EAPOL on this interface */
03021         del_ifidx(drv, ifidx);
03022 #endif /* HOSTAPD */
03023 
03024         msg = nlmsg_alloc();
03025         if (!msg)
03026                 goto nla_put_failure;
03027 
03028         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
03029                     0, NL80211_CMD_DEL_INTERFACE, 0);
03030         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
03031 
03032         if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
03033                 return;
03034  nla_put_failure:
03035         wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
03036 }
03037 
03038 
03039 static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
03040                                      const char *ifname,
03041                                      enum nl80211_iftype iftype,
03042                                      const u8 *addr, int wds)
03043 {
03044         struct nl_msg *msg, *flags = NULL;
03045         int ifidx;
03046         int ret = -ENOBUFS;
03047 
03048         msg = nlmsg_alloc();
03049         if (!msg)
03050                 return -1;
03051 
03052         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
03053                     0, NL80211_CMD_NEW_INTERFACE, 0);
03054         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
03055         NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
03056         NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
03057 
03058         if (iftype == NL80211_IFTYPE_MONITOR) {
03059                 int err;
03060 
03061                 flags = nlmsg_alloc();
03062                 if (!flags)
03063                         goto nla_put_failure;
03064 
03065                 NLA_PUT_FLAG(flags, NL80211_MNTR_FLAG_COOK_FRAMES);
03066 
03067                 err = nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);
03068 
03069                 nlmsg_free(flags);
03070 
03071                 if (err)
03072                         goto nla_put_failure;
03073         } else if (wds) {
03074                 NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
03075         }
03076 
03077         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
03078         if (ret) {
03079  nla_put_failure:
03080                 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
03081                            ifname, ret, strerror(-ret));
03082                 return ret;
03083         }
03084 
03085         ifidx = if_nametoindex(ifname);
03086         wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
03087                    ifname, ifidx);
03088 
03089         if (ifidx <= 0)
03090                 return -1;
03091 
03092 #ifdef HOSTAPD
03093         /* start listening for EAPOL on this interface */
03094         add_ifidx(drv, ifidx);
03095 #endif /* HOSTAPD */
03096 
03097         if (addr && iftype != NL80211_IFTYPE_MONITOR &&
03098             linux_set_ifhwaddr(drv->ioctl_sock, ifname, addr)) {
03099                 nl80211_remove_iface(drv, ifidx);
03100                 return -1;
03101         }
03102 
03103         return ifidx;
03104 }
03105 
03106 
03107 static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
03108                                 const char *ifname, enum nl80211_iftype iftype,
03109                                 const u8 *addr, int wds)
03110 {
03111         int ret;
03112 
03113         ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds);
03114 
03115         /* if error occured and interface exists already */
03116         if (ret == -ENFILE && if_nametoindex(ifname)) {
03117                 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
03118 
03119                 /* Try to remove the interface that was already there. */
03120                 nl80211_remove_iface(drv, if_nametoindex(ifname));
03121 
03122                 /* Try to create the interface again */
03123                 ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
03124                                                 wds);
03125         }
03126 
03127         if (ret >= 0 && drv->disable_11b_rates)
03128                 nl80211_disable_11b_rates(drv, ret, 1);
03129 
03130         return ret;
03131 }
03132 
03133 
03134 static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
03135 {
03136         struct ieee80211_hdr *hdr;
03137         u16 fc;
03138         union wpa_event_data event;
03139 
03140         hdr = (struct ieee80211_hdr *) buf;
03141         fc = le_to_host16(hdr->frame_control);
03142 
03143         os_memset(&event, 0, sizeof(event));
03144         event.tx_status.type = WLAN_FC_GET_TYPE(fc);
03145         event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
03146         event.tx_status.dst = hdr->addr1;
03147         event.tx_status.data = buf;
03148         event.tx_status.data_len = len;
03149         event.tx_status.ack = ok;
03150         wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event);
03151 }
03152 
03153 
03154 static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
03155                              u8 *buf, size_t len)
03156 {
03157         union wpa_event_data event;
03158         os_memset(&event, 0, sizeof(event));
03159         event.rx_from_unknown.frame = buf;
03160         event.rx_from_unknown.len = len;
03161         wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
03162 }
03163 
03164 
03165 static void handle_frame(struct wpa_driver_nl80211_data *drv,
03166                          u8 *buf, size_t len, int datarate, int ssi_signal)
03167 {
03168         struct ieee80211_hdr *hdr;
03169         u16 fc;
03170         union wpa_event_data event;
03171 
03172         hdr = (struct ieee80211_hdr *) buf;
03173         fc = le_to_host16(hdr->frame_control);
03174 
03175         switch (WLAN_FC_GET_TYPE(fc)) {
03176         case WLAN_FC_TYPE_MGMT:
03177                 os_memset(&event, 0, sizeof(event));
03178                 event.rx_mgmt.frame = buf;
03179                 event.rx_mgmt.frame_len = len;
03180                 event.rx_mgmt.datarate = datarate;
03181                 event.rx_mgmt.ssi_signal = ssi_signal;
03182                 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
03183                 break;
03184         case WLAN_FC_TYPE_CTRL:
03185                 /* can only get here with PS-Poll frames */
03186                 wpa_printf(MSG_DEBUG, "CTRL");
03187                 from_unknown_sta(drv, buf, len);
03188                 break;
03189         case WLAN_FC_TYPE_DATA:
03190                 from_unknown_sta(drv, buf, len);
03191                 break;
03192         }
03193 }
03194 
03195 
03196 static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
03197 {
03198         struct wpa_driver_nl80211_data *drv = eloop_ctx;
03199         int len;
03200         unsigned char buf[3000];
03201         struct ieee80211_radiotap_iterator iter;
03202         int ret;
03203         int datarate = 0, ssi_signal = 0;
03204         int injected = 0, failed = 0, rxflags = 0;
03205 
03206         len = recv(sock, buf, sizeof(buf), 0);
03207         if (len < 0) {
03208                 perror("recv");
03209                 return;
03210         }
03211 
03212         if (drv->nlmode == NL80211_IFTYPE_STATION && !drv->probe_req_report) {
03213                 wpa_printf(MSG_DEBUG, "nl80211: Ignore monitor interface "
03214                            "frame since Probe Request reporting is disabled");
03215                 return;
03216         }
03217 
03218         if (ieee80211_radiotap_iterator_init(&iter, (void*)buf, len)) {
03219                 printf("received invalid radiotap frame\n");
03220                 return;
03221         }
03222 
03223         while (1) {
03224                 ret = ieee80211_radiotap_iterator_next(&iter);
03225                 if (ret == -ENOENT)
03226                         break;
03227                 if (ret) {
03228                         printf("received invalid radiotap frame (%d)\n", ret);
03229                         return;
03230                 }
03231                 switch (iter.this_arg_index) {
03232                 case IEEE80211_RADIOTAP_FLAGS:
03233                         if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
03234                                 len -= 4;
03235                         break;
03236                 case IEEE80211_RADIOTAP_RX_FLAGS:
03237                         rxflags = 1;
03238                         break;
03239                 case IEEE80211_RADIOTAP_TX_FLAGS:
03240                         injected = 1;
03241                         failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
03242                                         IEEE80211_RADIOTAP_F_TX_FAIL;
03243                         break;
03244                 case IEEE80211_RADIOTAP_DATA_RETRIES:
03245                         break;
03246                 case IEEE80211_RADIOTAP_CHANNEL:
03247                         /* TODO: convert from freq/flags to channel number */
03248                         break;
03249                 case IEEE80211_RADIOTAP_RATE:
03250                         datarate = *iter.this_arg * 5;
03251                         break;
03252                 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
03253                         ssi_signal = *iter.this_arg;
03254                         break;
03255                 }
03256         }
03257 
03258         if (rxflags && injected)
03259                 return;
03260 
03261         if (!injected)
03262                 handle_frame(drv, buf + iter.max_length,
03263                              len - iter.max_length, datarate, ssi_signal);
03264         else
03265                 handle_tx_callback(drv->ctx, buf + iter.max_length,
03266                                    len - iter.max_length, !failed);
03267 }
03268 
03269 
03270 /*
03271  * we post-process the filter code later and rewrite
03272  * this to the offset to the last instruction
03273  */
03274 #define PASS    0xFF
03275 #define FAIL    0xFE
03276 
03277 static struct sock_filter msock_filter_insns[] = {
03278         /*
03279          * do a little-endian load of the radiotap length field
03280          */
03281         /* load lower byte into A */
03282         BPF_STMT(BPF_LD  | BPF_B | BPF_ABS, 2),
03283         /* put it into X (== index register) */
03284         BPF_STMT(BPF_MISC| BPF_TAX, 0),
03285         /* load upper byte into A */
03286         BPF_STMT(BPF_LD  | BPF_B | BPF_ABS, 3),
03287         /* left-shift it by 8 */
03288         BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
03289         /* or with X */
03290         BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
03291         /* put result into X */
03292         BPF_STMT(BPF_MISC| BPF_TAX, 0),
03293 
03294         /*
03295          * Allow management frames through, this also gives us those
03296          * management frames that we sent ourselves with status
03297          */
03298         /* load the lower byte of the IEEE 802.11 frame control field */
03299         BPF_STMT(BPF_LD  | BPF_B | BPF_IND, 0),
03300         /* mask off frame type and version */
03301         BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
03302         /* accept frame if it's both 0, fall through otherwise */
03303         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
03304 
03305         /*
03306          * TODO: add a bit to radiotap RX flags that indicates
03307          * that the sending station is not associated, then
03308          * add a filter here that filters on our DA and that flag
03309          * to allow us to deauth frames to that bad station.
03310          *
03311          * Not a regression -- we didn't do it before either.
03312          */
03313 
03314 #if 0
03315         /*
03316          * drop non-data frames
03317          */
03318         /* load the lower byte of the frame control field */
03319         BPF_STMT(BPF_LD   | BPF_B | BPF_IND, 0),
03320         /* mask off QoS bit */
03321         BPF_STMT(BPF_ALU  | BPF_AND | BPF_K, 0x0c),
03322         /* drop non-data frames */
03323         BPF_JUMP(BPF_JMP  | BPF_JEQ | BPF_K, 8, 0, FAIL),
03324 #endif
03325         /* load the upper byte of the frame control field */
03326         BPF_STMT(BPF_LD   | BPF_B | BPF_IND, 1),
03327         /* mask off toDS/fromDS */
03328         BPF_STMT(BPF_ALU  | BPF_AND | BPF_K, 0x03),
03329         /* accept WDS frames */
03330         BPF_JUMP(BPF_JMP  | BPF_JEQ | BPF_K, 3, PASS, 0),
03331 
03332         /*
03333          * add header length to index
03334          */
03335         /* load the lower byte of the frame control field */
03336         BPF_STMT(BPF_LD   | BPF_B | BPF_IND, 0),
03337         /* mask off QoS bit */
03338         BPF_STMT(BPF_ALU  | BPF_AND | BPF_K, 0x80),
03339         /* right shift it by 6 to give 0 or 2 */
03340         BPF_STMT(BPF_ALU  | BPF_RSH | BPF_K, 6),
03341         /* add data frame header length */
03342         BPF_STMT(BPF_ALU  | BPF_ADD | BPF_K, 24),
03343         /* add index, was start of 802.11 header */
03344         BPF_STMT(BPF_ALU  | BPF_ADD | BPF_X, 0),
03345         /* move to index, now start of LL header */
03346         BPF_STMT(BPF_MISC | BPF_TAX, 0),
03347 
03348         /*
03349          * Accept empty data frames, we use those for
03350          * polling activity.
03351          */
03352         BPF_STMT(BPF_LD  | BPF_W | BPF_LEN, 0),
03353         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
03354 
03355         /*
03356          * Accept EAPOL frames
03357          */
03358         BPF_STMT(BPF_LD  | BPF_W | BPF_IND, 0),
03359         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
03360         BPF_STMT(BPF_LD  | BPF_W | BPF_IND, 4),
03361         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
03362 
03363         /* keep these last two statements or change the code below */
03364         /* return 0 == "DROP" */
03365         BPF_STMT(BPF_RET | BPF_K, 0),
03366         /* return ~0 == "keep all" */
03367         BPF_STMT(BPF_RET | BPF_K, ~0),
03368 };
03369 
03370 static struct sock_fprog msock_filter = {
03371         .len = sizeof(msock_filter_insns)/sizeof(msock_filter_insns[0]),
03372         .filter = msock_filter_insns,
03373 };
03374 
03375 
03376 static int add_monitor_filter(int s)
03377 {
03378         int idx;
03379 
03380         /* rewrite all PASS/FAIL jump offsets */
03381         for (idx = 0; idx < msock_filter.len; idx++) {
03382                 struct sock_filter *insn = &msock_filter_insns[idx];
03383 
03384                 if (BPF_CLASS(insn->code) == BPF_JMP) {
03385                         if (insn->code == (BPF_JMP|BPF_JA)) {
03386                                 if (insn->k == PASS)
03387                                         insn->k = msock_filter.len - idx - 2;
03388                                 else if (insn->k == FAIL)
03389                                         insn->k = msock_filter.len - idx - 3;
03390                         }
03391 
03392                         if (insn->jt == PASS)
03393                                 insn->jt = msock_filter.len - idx - 2;
03394                         else if (insn->jt == FAIL)
03395                                 insn->jt = msock_filter.len - idx - 3;
03396 
03397                         if (insn->jf == PASS)
03398                                 insn->jf = msock_filter.len - idx - 2;
03399                         else if (insn->jf == FAIL)
03400                                 insn->jf = msock_filter.len - idx - 3;
03401                 }
03402         }
03403 
03404         if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
03405                        &msock_filter, sizeof(msock_filter))) {
03406                 perror("SO_ATTACH_FILTER");
03407                 return -1;
03408         }
03409 
03410         return 0;
03411 }
03412 
03413 
03414 static void nl80211_remove_monitor_interface(
03415         struct wpa_driver_nl80211_data *drv)
03416 {
03417         if (drv->monitor_ifidx >= 0) {
03418                 nl80211_remove_iface(drv, drv->monitor_ifidx);
03419                 drv->monitor_ifidx = -1;
03420         }
03421         if (drv->monitor_sock >= 0) {
03422                 eloop_unregister_read_sock(drv->monitor_sock);
03423                 close(drv->monitor_sock);
03424                 drv->monitor_sock = -1;
03425         }
03426 }
03427 
03428 
03429 static int
03430 nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
03431 {
03432         char buf[IFNAMSIZ];
03433         struct sockaddr_ll ll;
03434         int optval;
03435         socklen_t optlen;
03436 
03437         snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss.ifname);
03438         buf[IFNAMSIZ - 1] = '\0';
03439 
03440         drv->monitor_ifidx =
03441                 nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
03442                                      0);
03443 
03444         if (drv->monitor_ifidx < 0)
03445                 return -1;
03446 
03447         if (linux_set_iface_flags(drv->ioctl_sock, buf, 1))
03448                 goto error;
03449 
03450         memset(&ll, 0, sizeof(ll));
03451         ll.sll_family = AF_PACKET;
03452         ll.sll_ifindex = drv->monitor_ifidx;
03453         drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
03454         if (drv->monitor_sock < 0) {
03455                 perror("socket[PF_PACKET,SOCK_RAW]");
03456                 goto error;
03457         }
03458 
03459         if (add_monitor_filter(drv->monitor_sock)) {
03460                 wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
03461                            "interface; do filtering in user space");
03462                 /* This works, but will cost in performance. */
03463         }
03464 
03465         if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
03466                 perror("monitor socket bind");
03467                 goto error;
03468         }
03469 
03470         optlen = sizeof(optval);
03471         optval = 20;
03472         if (setsockopt
03473             (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
03474                 perror("Failed to set socket priority");
03475                 goto error;
03476         }
03477 
03478         if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
03479                                      drv, NULL)) {
03480                 printf("Could not register monitor read socket\n");
03481                 goto error;
03482         }
03483 
03484         return 0;
03485  error:
03486         nl80211_remove_monitor_interface(drv);
03487         return -1;
03488 }
03489 
03490 
03491 static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
03492 
03493 static int wpa_driver_nl80211_hapd_send_eapol(
03494         void *priv, const u8 *addr, const u8 *data,
03495         size_t data_len, int encrypt, const u8 *own_addr)
03496 {
03497         struct i802_bss *bss = priv;
03498         struct wpa_driver_nl80211_data *drv = bss->drv;
03499         struct ieee80211_hdr *hdr;
03500         size_t len;
03501         u8 *pos;
03502         int res;
03503 #if 0 /* FIX */
03504         int qos = sta->flags & WPA_STA_WMM;
03505 #else
03506         int qos = 0;
03507 #endif
03508 
03509         len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
03510                 data_len;
03511         hdr = os_zalloc(len);
03512         if (hdr == NULL) {
03513                 printf("malloc() failed for i802_send_data(len=%lu)\n",
03514                        (unsigned long) len);
03515                 return -1;
03516         }
03517 
03518         hdr->frame_control =
03519                 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
03520         hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
03521         if (encrypt)
03522                 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
03523 #if 0 /* To be enabled if qos determination is added above */
03524         if (qos) {
03525                 hdr->frame_control |=
03526                         host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
03527         }
03528 #endif
03529 
03530         memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
03531         memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
03532         memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
03533         pos = (u8 *) (hdr + 1);
03534 
03535 #if 0 /* To be enabled if qos determination is added above */
03536         if (qos) {
03537                 /* add an empty QoS header if needed */
03538                 pos[0] = 0;
03539                 pos[1] = 0;
03540                 pos += 2;
03541         }
03542 #endif
03543 
03544         memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
03545         pos += sizeof(rfc1042_header);
03546         WPA_PUT_BE16(pos, ETH_P_PAE);
03547         pos += 2;
03548         memcpy(pos, data, data_len);
03549 
03550         res = wpa_driver_nl80211_send_frame(drv, (u8 *) hdr, len, encrypt);
03551         if (res < 0) {
03552                 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
03553                            "failed: %d (%s)",
03554                            (unsigned long) len, errno, strerror(errno));
03555         }
03556         os_free(hdr);
03557 
03558         return res;
03559 }
03560 
03561 
03562 static u32 sta_flags_nl80211(int flags)
03563 {
03564         u32 f = 0;
03565 
03566         if (flags & WPA_STA_AUTHORIZED)
03567                 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
03568         if (flags & WPA_STA_WMM)
03569                 f |= BIT(NL80211_STA_FLAG_WME);
03570         if (flags & WPA_STA_SHORT_PREAMBLE)
03571                 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
03572         if (flags & WPA_STA_MFP)
03573                 f |= BIT(NL80211_STA_FLAG_MFP);
03574 
03575         return f;
03576 }
03577 
03578 
03579 static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
03580                                             int total_flags,
03581                                             int flags_or, int flags_and)
03582 {
03583         struct i802_bss *bss = priv;
03584         struct wpa_driver_nl80211_data *drv = bss->drv;
03585         struct nl_msg *msg, *flags = NULL;
03586         struct nl80211_sta_flag_update upd;
03587 
03588         msg = nlmsg_alloc();
03589         if (!msg)
03590                 return -ENOMEM;
03591 
03592         flags = nlmsg_alloc();
03593         if (!flags) {
03594                 nlmsg_free(msg);
03595                 return -ENOMEM;
03596         }
03597 
03598         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
03599                     0, NL80211_CMD_SET_STATION, 0);
03600 
03601         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
03602                     if_nametoindex(bss->ifname));
03603         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
03604 
03605         /*
03606          * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
03607          * can be removed eventually.
03608          */
03609         if (total_flags & WPA_STA_AUTHORIZED)
03610                 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);
03611 
03612         if (total_flags & WPA_STA_WMM)
03613                 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);
03614 
03615         if (total_flags & WPA_STA_SHORT_PREAMBLE)
03616                 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);
03617 
03618         if (total_flags & WPA_STA_MFP)
03619                 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_MFP);
03620 
03621         if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))
03622                 goto nla_put_failure;
03623 
03624         os_memset(&upd, 0, sizeof(upd));
03625         upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
03626         upd.set = sta_flags_nl80211(flags_or);
03627         NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
03628 
03629         nlmsg_free(flags);
03630 
03631         return send_and_recv_msgs(drv, msg, NULL, NULL);
03632  nla_put_failure:
03633         nlmsg_free(flags);
03634         return -ENOBUFS;
03635 }
03636 
03637 
03638 static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
03639                                  struct wpa_driver_associate_params *params)
03640 {
03641         if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode) ||
03642             wpa_driver_nl80211_set_freq(drv, params->freq, 0, 0)) {
03643                 nl80211_remove_monitor_interface(drv);
03644                 return -1;
03645         }
03646 
03647         /* TODO: setup monitor interface (and add code somewhere to remove this
03648          * when AP mode is stopped; associate with mode != 2 or drv_deinit) */
03649 
03650         return 0;
03651 }
03652 
03653 
03654 static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
03655 {
03656         struct nl_msg *msg;
03657         int ret = -1;
03658 
03659         msg = nlmsg_alloc();
03660         if (!msg)
03661                 return -1;
03662 
03663         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
03664                     NL80211_CMD_LEAVE_IBSS, 0);
03665         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
03666         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
03667         msg = NULL;
03668         if (ret) {
03669                 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
03670                            "(%s)", ret, strerror(-ret));
03671                 goto nla_put_failure;
03672         }
03673 
03674         ret = 0;
03675         wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
03676 
03677 nla_put_failure:
03678         nlmsg_free(msg);
03679         return ret;
03680 }
03681 
03682 
03683 static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
03684                                    struct wpa_driver_associate_params *params)
03685 {
03686         struct nl_msg *msg;
03687         int ret = -1;
03688         int count = 0;
03689 
03690         wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
03691 
03692         if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode)) {
03693                 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
03694                            "IBSS mode");
03695                 return -1;
03696         }
03697 
03698 retry:
03699         msg = nlmsg_alloc();
03700         if (!msg)
03701                 return -1;
03702 
03703         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
03704                     NL80211_CMD_JOIN_IBSS, 0);
03705         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
03706 
03707         if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
03708                 goto nla_put_failure;
03709 
03710         wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
03711                           params->ssid, params->ssid_len);
03712         NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
03713                 params->ssid);
03714         os_memcpy(drv->ssid, params->ssid, params->ssid_len);
03715         drv->ssid_len = params->ssid_len;
03716 
03717         wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
03718         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
03719 
03720         ret = nl80211_set_conn_keys(params, msg);
03721         if (ret)
03722                 goto nla_put_failure;
03723 
03724         if (params->wpa_ie) {
03725                 wpa_hexdump(MSG_DEBUG,
03726                             "  * Extra IEs for Beacon/Probe Response frames",
03727                             params->wpa_ie, params->wpa_ie_len);
03728                 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
03729                         params->wpa_ie);
03730         }
03731 
03732         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
03733         msg = NULL;
03734         if (ret) {
03735                 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
03736                            ret, strerror(-ret));
03737                 count++;
03738                 if (ret == -EALREADY && count == 1) {
03739                         wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
03740                                    "forced leave");
03741                         nl80211_leave_ibss(drv);
03742                         nlmsg_free(msg);
03743                         goto retry;
03744                 }
03745 
03746                 goto nla_put_failure;
03747         }
03748         ret = 0;
03749         wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
03750 
03751 nla_put_failure:
03752         nlmsg_free(msg);
03753         return ret;
03754 }
03755 
03756 
03757 static int wpa_driver_nl80211_connect(
03758         struct wpa_driver_nl80211_data *drv,
03759         struct wpa_driver_associate_params *params)
03760 {
03761         struct nl_msg *msg;
03762         enum nl80211_auth_type type;
03763         int ret = 0;
03764 
03765         msg = nlmsg_alloc();
03766         if (!msg)
03767                 return -1;
03768 
03769         wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
03770         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
03771                     NL80211_CMD_CONNECT, 0);
03772 
03773         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
03774         if (params->bssid) {
03775                 wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
03776                            MAC2STR(params->bssid));
03777                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
03778         }
03779         if (params->freq) {
03780                 wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
03781                 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
03782         }
03783         if (params->ssid) {
03784                 wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
03785                                   params->ssid, params->ssid_len);
03786                 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
03787                         params->ssid);
03788                 if (params->ssid_len > sizeof(drv->ssid))
03789                         goto nla_put_failure;
03790                 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
03791                 drv->ssid_len = params->ssid_len;
03792         }
03793         wpa_hexdump(MSG_DEBUG, "  * IEs", params->wpa_ie, params->wpa_ie_len);
03794         if (params->wpa_ie)
03795                 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
03796                         params->wpa_ie);
03797 
03798         if (params->auth_alg & WPA_AUTH_ALG_OPEN)
03799                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
03800         else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
03801                 type = NL80211_AUTHTYPE_SHARED_KEY;
03802         else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
03803                 type = NL80211_AUTHTYPE_NETWORK_EAP;
03804         else if (params->auth_alg & WPA_AUTH_ALG_FT)
03805                 type = NL80211_AUTHTYPE_FT;
03806         else
03807                 goto nla_put_failure;
03808 
03809         wpa_printf(MSG_DEBUG, "  * Auth Type %d", type);
03810         NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
03811 
03812         if (params->wpa_ie && params->wpa_ie_len) {
03813                 enum nl80211_wpa_versions ver;
03814 
03815                 if (params->wpa_ie[0] == WLAN_EID_RSN)
03816                         ver = NL80211_WPA_VERSION_2;
03817                 else
03818                         ver = NL80211_WPA_VERSION_1;
03819 
03820                 wpa_printf(MSG_DEBUG, "  * WPA Version %d", ver);
03821                 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
03822         }
03823 
03824         if (params->pairwise_suite != CIPHER_NONE) {
03825                 int cipher;
03826 
03827                 switch (params->pairwise_suite) {
03828                 case CIPHER_WEP40:
03829                         cipher = WLAN_CIPHER_SUITE_WEP40;
03830                         break;
03831                 case CIPHER_WEP104:
03832                         cipher = WLAN_CIPHER_SUITE_WEP104;
03833                         break;
03834                 case CIPHER_CCMP:
03835                         cipher = WLAN_CIPHER_SUITE_CCMP;
03836                         break;
03837                 case CIPHER_TKIP:
03838                 default:
03839                         cipher = WLAN_CIPHER_SUITE_TKIP;
03840                         break;
03841                 }
03842                 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
03843         }
03844 
03845         if (params->group_suite != CIPHER_NONE) {
03846                 int cipher;
03847 
03848                 switch (params->group_suite) {
03849                 case CIPHER_WEP40:
03850                         cipher = WLAN_CIPHER_SUITE_WEP40;
03851                         break;
03852                 case CIPHER_WEP104:
03853                         cipher = WLAN_CIPHER_SUITE_WEP104;
03854                         break;
03855                 case CIPHER_CCMP:
03856                         cipher = WLAN_CIPHER_SUITE_CCMP;
03857                         break;
03858                 case CIPHER_TKIP:
03859                 default:
03860                         cipher = WLAN_CIPHER_SUITE_TKIP;
03861                         break;
03862                 }
03863                 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
03864         }
03865 
03866         if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
03867             params->key_mgmt_suite == KEY_MGMT_PSK) {
03868                 int mgmt = WLAN_AKM_SUITE_PSK;
03869 
03870                 switch (params->key_mgmt_suite) {
03871                 case KEY_MGMT_802_1X:
03872                         mgmt = WLAN_AKM_SUITE_8021X;
03873                         break;
03874                 case KEY_MGMT_PSK:
03875                 default:
03876                         mgmt = WLAN_AKM_SUITE_PSK;
03877                         break;
03878                 }
03879                 NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
03880         }
03881 
03882         ret = nl80211_set_conn_keys(params, msg);
03883         if (ret)
03884                 goto nla_put_failure;
03885 
03886         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
03887         msg = NULL;
03888         if (ret) {
03889                 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
03890                            "(%s)", ret, strerror(-ret));
03891                 goto nla_put_failure;
03892         }
03893         ret = 0;
03894         wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
03895 
03896 nla_put_failure:
03897         nlmsg_free(msg);
03898         return ret;
03899 
03900 }
03901 
03902 
03903 static int wpa_driver_nl80211_associate(
03904         void *priv, struct wpa_driver_associate_params *params)
03905 {
03906         struct i802_bss *bss = priv;
03907         struct wpa_driver_nl80211_data *drv = bss->drv;
03908         int ret = -1;
03909         struct nl_msg *msg;
03910 
03911         if (params->mode == IEEE80211_MODE_AP)
03912                 return wpa_driver_nl80211_ap(drv, params);
03913 
03914         if (params->mode == IEEE80211_MODE_IBSS)
03915                 return wpa_driver_nl80211_ibss(drv, params);
03916 
03917         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
03918                 if (wpa_driver_nl80211_set_mode(priv, params->mode) < 0)
03919                         return -1;
03920                 return wpa_driver_nl80211_connect(drv, params);
03921         }
03922 
03923         drv->associated = 0;
03924 
03925         msg = nlmsg_alloc();
03926         if (!msg)
03927                 return -1;
03928 
03929         wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
03930                    drv->ifindex);
03931         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
03932                     NL80211_CMD_ASSOCIATE, 0);
03933 
03934         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
03935         if (params->bssid) {
03936                 wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
03937                            MAC2STR(params->bssid));
03938                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
03939         }
03940         if (params->freq) {
03941                 wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
03942                 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
03943                 drv->assoc_freq = params->freq;
03944         } else
03945                 drv->assoc_freq = 0;
03946         if (params->ssid) {
03947                 wpa_hexdump_ascii(MSG_DEBUG, "  * SSID",
03948                                   params->ssid, params->ssid_len);
03949                 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
03950                         params->ssid);
03951                 if (params->ssid_len > sizeof(drv->ssid))
03952                         goto nla_put_failure;
03953                 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
03954                 drv->ssid_len = params->ssid_len;
03955         }
03956         wpa_hexdump(MSG_DEBUG, "  * IEs", params->wpa_ie, params->wpa_ie_len);
03957         if (params->wpa_ie)
03958                 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
03959                         params->wpa_ie);
03960 
03961 #ifdef CONFIG_IEEE80211W
03962         if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
03963                 NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
03964 #endif /* CONFIG_IEEE80211W */
03965 
03966         NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
03967 
03968         if (params->prev_bssid) {
03969                 wpa_printf(MSG_DEBUG, "  * prev_bssid=" MACSTR,
03970                            MAC2STR(params->prev_bssid));
03971                 NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
03972                         params->prev_bssid);
03973         }
03974 
03975         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
03976         msg = NULL;
03977         if (ret) {
03978                 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
03979                            "(%s)", ret, strerror(-ret));
03980                 nl80211_dump_scan(drv);
03981                 goto nla_put_failure;
03982         }
03983         ret = 0;
03984         wpa_printf(MSG_DEBUG, "nl80211: Association request send "
03985                    "successfully");
03986 
03987 nla_put_failure:
03988         nlmsg_free(msg);
03989         return ret;
03990 }
03991 
03992 
03993 static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
03994                             int ifindex, int mode)
03995 {
03996         struct nl_msg *msg;
03997         int ret = -ENOBUFS;
03998 
03999         msg = nlmsg_alloc();
04000         if (!msg)
04001                 return -ENOMEM;
04002 
04003         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04004                     0, NL80211_CMD_SET_INTERFACE, 0);
04005         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
04006         NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
04007 
04008         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
04009         if (!ret)
04010                 return 0;
04011 nla_put_failure:
04012         wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
04013                    " %d (%s)", ifindex, mode, ret, strerror(-ret));
04014         return ret;
04015 }
04016 
04017 
04018 static int wpa_driver_nl80211_set_mode(void *priv, int mode)
04019 {
04020         struct i802_bss *bss = priv;
04021         struct wpa_driver_nl80211_data *drv = bss->drv;
04022         int ret = -1;
04023         int nlmode;
04024 
04025         switch (mode) {
04026         case 0:
04027                 nlmode = NL80211_IFTYPE_STATION;
04028                 break;
04029         case 1:
04030                 nlmode = NL80211_IFTYPE_ADHOC;
04031                 break;
04032         case 2:
04033                 nlmode = NL80211_IFTYPE_AP;
04034                 break;
04035         default:
04036                 return -1;
04037         }
04038 
04039         if (nl80211_set_mode(drv, drv->ifindex, nlmode) == 0) {
04040                 drv->nlmode = nlmode;
04041                 ret = 0;
04042                 goto done;
04043         }
04044 
04045         if (nlmode == drv->nlmode) {
04046                 wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
04047                            "requested mode - ignore error");
04048                 ret = 0;
04049                 goto done; /* Already in the requested mode */
04050         }
04051 
04052         /* mac80211 doesn't allow mode changes while the device is up, so
04053          * take the device down, try to set the mode again, and bring the
04054          * device back up.
04055          */
04056         if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0) == 0) {
04057                 /* Try to set the mode again while the interface is down */
04058                 ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
04059                 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1))
04060                         ret = -1;
04061         }
04062 
04063         if (!ret) {
04064                 wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
04065                            "interface is down");
04066                 drv->nlmode = nlmode;
04067         }
04068 
04069 done:
04070         if (!ret && nlmode == NL80211_IFTYPE_AP) {
04071                 /* Setup additional AP mode functionality if needed */
04072                 if (drv->monitor_ifidx < 0 &&
04073                     nl80211_create_monitor_interface(drv))
04074                         return -1;
04075         } else if (!ret && nlmode != NL80211_IFTYPE_AP) {
04076                 /* Remove additional AP mode functionality */
04077                 nl80211_remove_monitor_interface(drv);
04078                 bss->beacon_set = 0;
04079         }
04080 
04081         if (ret)
04082                 wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
04083                            "from %d failed", nlmode, drv->nlmode);
04084 
04085         return ret;
04086 }
04087 
04088 
04089 static int wpa_driver_nl80211_get_capa(void *priv,
04090                                        struct wpa_driver_capa *capa)
04091 {
04092         struct i802_bss *bss = priv;
04093         struct wpa_driver_nl80211_data *drv = bss->drv;
04094         if (!drv->has_capability)
04095                 return -1;
04096         os_memcpy(capa, &drv->capa, sizeof(*capa));
04097         return 0;
04098 }
04099 
04100 
04101 static int wpa_driver_nl80211_set_operstate(void *priv, int state)
04102 {
04103         struct i802_bss *bss = priv;
04104         struct wpa_driver_nl80211_data *drv = bss->drv;
04105 
04106         wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
04107                    __func__, drv->operstate, state, state ? "UP" : "DORMANT");
04108         drv->operstate = state;
04109         return netlink_send_oper_ifla(drv->netlink, drv->ifindex, -1,
04110                                       state ? IF_OPER_UP : IF_OPER_DORMANT);
04111 }
04112 
04113 
04114 static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
04115 {
04116         struct i802_bss *bss = priv;
04117         struct wpa_driver_nl80211_data *drv = bss->drv;
04118         struct nl_msg *msg;
04119         struct nl80211_sta_flag_update upd;
04120 
04121         msg = nlmsg_alloc();
04122         if (!msg)
04123                 return -ENOMEM;
04124 
04125         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04126                     0, NL80211_CMD_SET_STATION, 0);
04127 
04128         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
04129                     if_nametoindex(bss->ifname));
04130         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
04131 
04132         os_memset(&upd, 0, sizeof(upd));
04133         upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
04134         if (authorized)
04135                 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
04136         NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
04137 
04138         return send_and_recv_msgs(drv, msg, NULL, NULL);
04139  nla_put_failure:
04140         return -ENOBUFS;
04141 }
04142 
04143 
04144 #ifdef HOSTAPD
04145 
04146 static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
04147 {
04148         int i;
04149         int *old;
04150 
04151         wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
04152                    ifidx);
04153         for (i = 0; i < drv->num_if_indices; i++) {
04154                 if (drv->if_indices[i] == 0) {
04155                         drv->if_indices[i] = ifidx;
04156                         return;
04157                 }
04158         }
04159 
04160         if (drv->if_indices != drv->default_if_indices)
04161                 old = drv->if_indices;
04162         else
04163                 old = NULL;
04164 
04165         drv->if_indices = os_realloc(old,
04166                                      sizeof(int) * (drv->num_if_indices + 1));
04167         if (!drv->if_indices) {
04168                 if (!old)
04169                         drv->if_indices = drv->default_if_indices;
04170                 else
04171                         drv->if_indices = old;
04172                 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
04173                            "interfaces");
04174                 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
04175                 return;
04176         } else if (!old)
04177                 os_memcpy(drv->if_indices, drv->default_if_indices,
04178                           sizeof(drv->default_if_indices));
04179         drv->if_indices[drv->num_if_indices] = ifidx;
04180         drv->num_if_indices++;
04181 }
04182 
04183 
04184 static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
04185 {
04186         int i;
04187 
04188         for (i = 0; i < drv->num_if_indices; i++) {
04189                 if (drv->if_indices[i] == ifidx) {
04190                         drv->if_indices[i] = 0;
04191                         break;
04192                 }
04193         }
04194 }
04195 
04196 
04197 static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
04198 {
04199         int i;
04200 
04201         for (i = 0; i < drv->num_if_indices; i++)
04202                 if (drv->if_indices[i] == ifidx)
04203                         return 1;
04204 
04205         return 0;
04206 }
04207 
04208 
04209 static inline int min_int(int a, int b)
04210 {
04211         if (a < b)
04212                 return a;
04213         return b;
04214 }
04215 
04216 
04217 static int get_key_handler(struct nl_msg *msg, void *arg)
04218 {
04219         struct nlattr *tb[NL80211_ATTR_MAX + 1];
04220         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
04221 
04222         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
04223                   genlmsg_attrlen(gnlh, 0), NULL);
04224 
04225         /*
04226          * TODO: validate the key index and mac address!
04227          * Otherwise, there's a race condition as soon as
04228          * the kernel starts sending key notifications.
04229          */
04230 
04231         if (tb[NL80211_ATTR_KEY_SEQ])
04232                 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
04233                        min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
04234         return NL_SKIP;
04235 }
04236 
04237 
04238 static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
04239                            int idx, u8 *seq)
04240 {
04241         struct i802_bss *bss = priv;
04242         struct wpa_driver_nl80211_data *drv = bss->drv;
04243         struct nl_msg *msg;
04244 
04245         msg = nlmsg_alloc();
04246         if (!msg)
04247                 return -ENOMEM;
04248 
04249         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04250                     0, NL80211_CMD_GET_KEY, 0);
04251 
04252         if (addr)
04253                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
04254         NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
04255         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
04256 
04257         memset(seq, 0, 6);
04258 
04259         return send_and_recv_msgs(drv, msg, get_key_handler, seq);
04260  nla_put_failure:
04261         return -ENOBUFS;
04262 }
04263 
04264 
04265 static int i802_set_rate_sets(void *priv, int *supp_rates, int *basic_rates,
04266                               int mode)
04267 {
04268         struct i802_bss *bss = priv;
04269         struct wpa_driver_nl80211_data *drv = bss->drv;
04270         struct nl_msg *msg;
04271         u8 rates[NL80211_MAX_SUPP_RATES];
04272         u8 rates_len = 0;
04273         int i;
04274 
04275         msg = nlmsg_alloc();
04276         if (!msg)
04277                 return -ENOMEM;
04278 
04279         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
04280                     NL80211_CMD_SET_BSS, 0);
04281 
04282         for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0; i++)
04283                 rates[rates_len++] = basic_rates[i] / 5;
04284 
04285         NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
04286 
04287         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
04288 
04289         return send_and_recv_msgs(drv, msg, NULL, NULL);
04290  nla_put_failure:
04291         return -ENOBUFS;
04292 }
04293 
04294 #endif /* HOSTAPD */
04295 
04296 
04297 /* Set kernel driver on given frequency (MHz) */
04298 static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
04299 {
04300         struct i802_bss *bss = priv;
04301         struct wpa_driver_nl80211_data *drv = bss->drv;
04302         return wpa_driver_nl80211_set_freq(drv, freq->freq, freq->ht_enabled,
04303                                            freq->sec_channel_offset);
04304 }
04305 
04306 
04307 #ifdef HOSTAPD
04308 
04309 static int i802_set_rts(void *priv, int rts)
04310 {
04311         struct i802_bss *bss = priv;
04312         struct wpa_driver_nl80211_data *drv = bss->drv;
04313         struct nl_msg *msg;
04314         int ret = -ENOBUFS;
04315         u32 val;
04316 
04317         msg = nlmsg_alloc();
04318         if (!msg)
04319                 return -ENOMEM;
04320 
04321         if (rts >= 2347)
04322                 val = (u32) -1;
04323         else
04324                 val = rts;
04325 
04326         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04327                     0, NL80211_CMD_SET_WIPHY, 0);
04328         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
04329         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
04330 
04331         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
04332         if (!ret)
04333                 return 0;
04334 nla_put_failure:
04335         wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
04336                    "%d (%s)", rts, ret, strerror(-ret));
04337         return ret;
04338 }
04339 
04340 
04341 static int i802_set_frag(void *priv, int frag)
04342 {
04343         struct i802_bss *bss = priv;
04344         struct wpa_driver_nl80211_data *drv = bss->drv;
04345         struct nl_msg *msg;
04346         int ret = -ENOBUFS;
04347         u32 val;
04348 
04349         msg = nlmsg_alloc();
04350         if (!msg)
04351                 return -ENOMEM;
04352 
04353         if (frag >= 2346)
04354                 val = (u32) -1;
04355         else
04356                 val = frag;
04357 
04358         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04359                     0, NL80211_CMD_SET_WIPHY, 0);
04360         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
04361         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
04362 
04363         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
04364         if (!ret)
04365                 return 0;
04366 nla_put_failure:
04367         wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
04368                    "%d: %d (%s)", frag, ret, strerror(-ret));
04369         return ret;
04370 }
04371 
04372 
04373 static int i802_flush(void *priv)
04374 {
04375         struct i802_bss *bss = priv;
04376         struct wpa_driver_nl80211_data *drv = bss->drv;
04377         struct nl_msg *msg;
04378 
04379         msg = nlmsg_alloc();
04380         if (!msg)
04381                 return -1;
04382 
04383         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04384                     0, NL80211_CMD_DEL_STATION, 0);
04385 
04386         /*
04387          * XXX: FIX! this needs to flush all VLANs too
04388          */
04389         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
04390                     if_nametoindex(bss->ifname));
04391 
04392         return send_and_recv_msgs(drv, msg, NULL, NULL);
04393  nla_put_failure:
04394         return -ENOBUFS;
04395 }
04396 
04397 
04398 static int get_sta_handler(struct nl_msg *msg, void *arg)
04399 {
04400         struct nlattr *tb[NL80211_ATTR_MAX + 1];
04401         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
04402         struct hostap_sta_driver_data *data = arg;
04403         struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
04404         static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
04405                 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
04406                 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
04407                 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
04408                 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
04409                 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
04410         };
04411 
04412         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
04413                   genlmsg_attrlen(gnlh, 0), NULL);
04414 
04415         /*
04416          * TODO: validate the interface and mac address!
04417          * Otherwise, there's a race condition as soon as
04418          * the kernel starts sending station notifications.
04419          */
04420 
04421         if (!tb[NL80211_ATTR_STA_INFO]) {
04422                 wpa_printf(MSG_DEBUG, "sta stats missing!");
04423                 return NL_SKIP;
04424         }
04425         if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
04426                              tb[NL80211_ATTR_STA_INFO],
04427                              stats_policy)) {
04428                 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
04429                 return NL_SKIP;
04430         }
04431 
04432         if (stats[NL80211_STA_INFO_INACTIVE_TIME])
04433                 data->inactive_msec =
04434                         nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
04435         if (stats[NL80211_STA_INFO_RX_BYTES])
04436                 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
04437         if (stats[NL80211_STA_INFO_TX_BYTES])
04438                 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
04439         if (stats[NL80211_STA_INFO_RX_PACKETS])
04440                 data->rx_packets =
04441                         nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
04442         if (stats[NL80211_STA_INFO_TX_PACKETS])
04443                 data->tx_packets =
04444                         nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
04445 
04446         return NL_SKIP;
04447 }
04448 
04449 static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
04450                               const u8 *addr)
04451 {
04452         struct i802_bss *bss = priv;
04453         struct wpa_driver_nl80211_data *drv = bss->drv;
04454         struct nl_msg *msg;
04455 
04456         os_memset(data, 0, sizeof(*data));
04457         msg = nlmsg_alloc();
04458         if (!msg)
04459                 return -ENOMEM;
04460 
04461         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04462                     0, NL80211_CMD_GET_STATION, 0);
04463 
04464         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
04465         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
04466 
04467         return send_and_recv_msgs(drv, msg, get_sta_handler, data);
04468  nla_put_failure:
04469         return -ENOBUFS;
04470 }
04471 
04472 
04473 static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
04474                                     int cw_min, int cw_max, int burst_time)
04475 {
04476         struct i802_bss *bss = priv;
04477         struct wpa_driver_nl80211_data *drv = bss->drv;
04478         struct nl_msg *msg;
04479         struct nlattr *txq, *params;
04480 
04481         msg = nlmsg_alloc();
04482         if (!msg)
04483                 return -1;
04484 
04485         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04486                     0, NL80211_CMD_SET_WIPHY, 0);
04487 
04488         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
04489 
04490         txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
04491         if (!txq)
04492                 goto nla_put_failure;
04493 
04494         /* We are only sending parameters for a single TXQ at a time */
04495         params = nla_nest_start(msg, 1);
04496         if (!params)
04497                 goto nla_put_failure;
04498 
04499         NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, queue);
04500         /* Burst time is configured in units of 0.1 msec and TXOP parameter in
04501          * 32 usec, so need to convert the value here. */
04502         NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
04503         NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
04504         NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
04505         NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
04506 
04507         nla_nest_end(msg, params);
04508 
04509         nla_nest_end(msg, txq);
04510 
04511         if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
04512                 return 0;
04513  nla_put_failure:
04514         return -1;
04515 }
04516 
04517 
04518 static int i802_set_bss(void *priv, int cts, int preamble, int slot)
04519 {
04520         struct i802_bss *bss = priv;
04521         struct wpa_driver_nl80211_data *drv = bss->drv;
04522         struct nl_msg *msg;
04523 
04524         msg = nlmsg_alloc();
04525         if (!msg)
04526                 return -ENOMEM;
04527 
04528         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
04529                     NL80211_CMD_SET_BSS, 0);
04530 
04531         if (cts >= 0)
04532                 NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
04533         if (preamble >= 0)
04534                 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
04535         if (slot >= 0)
04536                 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
04537 
04538         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
04539 
04540         return send_and_recv_msgs(drv, msg, NULL, NULL);
04541  nla_put_failure:
04542         return -ENOBUFS;
04543 }
04544 
04545 
04546 static int i802_set_cts_protect(void *priv, int value)
04547 {
04548         return i802_set_bss(priv, value, -1, -1);
04549 }
04550 
04551 
04552 static int i802_set_preamble(void *priv, int value)
04553 {
04554         return i802_set_bss(priv, -1, value, -1);
04555 }
04556 
04557 
04558 static int i802_set_short_slot_time(void *priv, int value)
04559 {
04560         return i802_set_bss(priv, -1, -1, value);
04561 }
04562 
04563 
04564 static int i802_set_sta_vlan(void *priv, const u8 *addr,
04565                              const char *ifname, int vlan_id)
04566 {
04567         struct i802_bss *bss = priv;
04568         struct wpa_driver_nl80211_data *drv = bss->drv;
04569         struct nl_msg *msg;
04570         int ret = -ENOBUFS;
04571 
04572         msg = nlmsg_alloc();
04573         if (!msg)
04574                 return -ENOMEM;
04575 
04576         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
04577                     0, NL80211_CMD_SET_STATION, 0);
04578 
04579         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
04580                     if_nametoindex(bss->ifname));
04581         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
04582         NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
04583                     if_nametoindex(ifname));
04584 
04585         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
04586         if (ret < 0) {
04587                 wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
04588                            MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
04589                            MAC2STR(addr), ifname, vlan_id, ret,
04590                            strerror(-ret));
04591         }
04592  nla_put_failure:
04593         return ret;
04594 }
04595 
04596 
04597 static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val)
04598 {
04599         struct i802_bss *bss = priv;
04600         struct wpa_driver_nl80211_data *drv = bss->drv;
04601         char name[IFNAMSIZ + 1];
04602 
04603         os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
04604         wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
04605                    " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
04606         if (val) {
04607                 if (nl80211_create_iface(drv, name, NL80211_IFTYPE_AP_VLAN,
04608                                          NULL, 1) < 0)
04609                         return -1;
04610                 linux_set_iface_flags(drv->ioctl_sock, name, 1);
04611                 return i802_set_sta_vlan(priv, addr, name, 0);
04612         } else {
04613                 i802_set_sta_vlan(priv, addr, bss->ifname, 0);
04614                 return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN,
04615                                                     name);
04616         }
04617 }
04618 
04619 
04620 static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
04621 {
04622         struct wpa_driver_nl80211_data *drv = eloop_ctx;
04623         struct sockaddr_ll lladdr;
04624         unsigned char buf[3000];
04625         int len;
04626         socklen_t fromlen = sizeof(lladdr);
04627 
04628         len = recvfrom(sock, buf, sizeof(buf), 0,
04629                        (struct sockaddr *)&lladdr, &fromlen);
04630         if (len < 0) {
04631                 perror("recv");
04632                 return;
04633         }
04634 
04635         if (have_ifidx(drv, lladdr.sll_ifindex))
04636                 drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
04637 }
04638 
04639 
04640 static int i802_get_inact_sec(void *priv, const u8 *addr)
04641 {
04642         struct hostap_sta_driver_data data;
04643         int ret;
04644 
04645         data.inactive_msec = (unsigned long) -1;
04646         ret = i802_read_sta_data(priv, &data, addr);
04647         if (ret || data.inactive_msec == (unsigned long) -1)
04648                 return -1;
04649         return data.inactive_msec / 1000;
04650 }
04651 
04652 
04653 static int i802_sta_clear_stats(void *priv, const u8 *addr)
04654 {
04655 #if 0
04656         /* TODO */
04657 #endif
04658         return 0;
04659 }
04660 
04661 
04662 static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
04663                            int reason)
04664 {
04665         struct i802_bss *bss = priv;
04666         struct ieee80211_mgmt mgmt;
04667 
04668         memset(&mgmt, 0, sizeof(mgmt));
04669         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
04670                                           WLAN_FC_STYPE_DEAUTH);
04671         memcpy(mgmt.da, addr, ETH_ALEN);
04672         memcpy(mgmt.sa, own_addr, ETH_ALEN);
04673         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
04674         mgmt.u.deauth.reason_code = host_to_le16(reason);
04675         return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
04676                                             IEEE80211_HDRLEN +
04677                                             sizeof(mgmt.u.deauth));
04678 }
04679 
04680 
04681 static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
04682                              int reason)
04683 {
04684         struct i802_bss *bss = priv;
04685         struct ieee80211_mgmt mgmt;
04686 
04687         memset(&mgmt, 0, sizeof(mgmt));
04688         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
04689                                           WLAN_FC_STYPE_DISASSOC);
04690         memcpy(mgmt.da, addr, ETH_ALEN);
04691         memcpy(mgmt.sa, own_addr, ETH_ALEN);
04692         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
04693         mgmt.u.disassoc.reason_code = host_to_le16(reason);
04694         return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
04695                                             IEEE80211_HDRLEN +
04696                                             sizeof(mgmt.u.disassoc));
04697 }
04698 
04699 
04700 static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
04701                              const char *brname, const char *ifname)
04702 {
04703         int ifindex;
04704         char in_br[IFNAMSIZ];
04705 
04706         os_strlcpy(drv->brname, brname, IFNAMSIZ);
04707         ifindex = if_nametoindex(brname);
04708         if (ifindex == 0) {
04709                 /*
04710                  * Bridge was configured, but the bridge device does
04711                  * not exist. Try to add it now.
04712                  */
04713                 if (linux_br_add(drv->ioctl_sock, brname) < 0) {
04714                         wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
04715                                    "bridge interface %s: %s",
04716                                    brname, strerror(errno));
04717                         return -1;
04718                 }
04719                 drv->added_bridge = 1;
04720                 add_ifidx(drv, if_nametoindex(brname));
04721         }
04722 
04723         if (linux_br_get(in_br, ifname) == 0) {
04724                 if (os_strcmp(in_br, brname) == 0)
04725                         return 0; /* already in the bridge */
04726 
04727                 wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
04728                            "bridge %s", ifname, in_br);
04729                 if (linux_br_del_if(drv->ioctl_sock, in_br, ifname) < 0) {
04730                         wpa_printf(MSG_ERROR, "nl80211: Failed to "
04731                                    "remove interface %s from bridge "
04732                                    "%s: %s",
04733                                    ifname, brname, strerror(errno));
04734                         return -1;
04735                 }
04736         }
04737 
04738         wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
04739                    ifname, brname);
04740         if (linux_br_add_if(drv->ioctl_sock, brname, ifname) < 0) {
04741                 wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
04742                            "into bridge %s: %s",
04743                            ifname, brname, strerror(errno));
04744                 return -1;
04745         }
04746         drv->added_if_into_bridge = 1;
04747 
04748         return 0;
04749 }
04750 
04751 
04752 static void *i802_init(struct hostapd_data *hapd,
04753                        struct wpa_init_params *params)
04754 {
04755         struct wpa_driver_nl80211_data *drv;
04756         struct i802_bss *bss;
04757         size_t i;
04758         char brname[IFNAMSIZ];
04759         int ifindex, br_ifindex;
04760         int br_added = 0;
04761 
04762         bss = wpa_driver_nl80211_init(hapd, params->ifname);
04763         if (bss == NULL)
04764                 return NULL;
04765 
04766         drv = bss->drv;
04767         if (linux_br_get(brname, params->ifname) == 0) {
04768                 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
04769                            params->ifname, brname);
04770                 br_ifindex = if_nametoindex(brname);
04771         } else {
04772                 brname[0] = '\0';
04773                 br_ifindex = 0;
04774         }
04775 
04776         drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
04777         drv->if_indices = drv->default_if_indices;
04778         for (i = 0; i < params->num_bridge; i++) {
04779                 if (params->bridge[i]) {
04780                         ifindex = if_nametoindex(params->bridge[i]);
04781                         if (ifindex)
04782                                 add_ifidx(drv, ifindex);
04783                         if (ifindex == br_ifindex)
04784                                 br_added = 1;
04785                 }
04786         }
04787         if (!br_added && br_ifindex &&
04788             (params->num_bridge == 0 || !params->bridge[0]))
04789                 add_ifidx(drv, br_ifindex);
04790 
04791         /* start listening for EAPOL on the default AP interface */
04792         add_ifidx(drv, drv->ifindex);
04793 
04794         if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0))
04795                 goto failed;
04796 
04797         if (params->bssid) {
04798                 if (linux_set_ifhwaddr(drv->ioctl_sock, bss->ifname,
04799                                        params->bssid))
04800                         goto failed;
04801         }
04802 
04803         if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_AP)) {
04804                 wpa_printf(MSG_ERROR, "nl80211: Failed to set interface %s "
04805                            "into AP mode", bss->ifname);
04806                 goto failed;
04807         }
04808 
04809         if (params->num_bridge && params->bridge[0] &&
04810             i802_check_bridge(drv, params->bridge[0], params->ifname) < 0)
04811                 goto failed;
04812 
04813         if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1))
04814                 goto failed;
04815 
04816         drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
04817         if (drv->eapol_sock < 0) {
04818                 perror("socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE)");
04819                 goto failed;
04820         }
04821 
04822         if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
04823         {
04824                 printf("Could not register read socket for eapol\n");
04825                 goto failed;
04826         }
04827 
04828         if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, params->own_addr))
04829                 goto failed;
04830 
04831         return bss;
04832 
04833 failed:
04834         nl80211_remove_monitor_interface(drv);
04835         if (drv->ioctl_sock >= 0)
04836                 close(drv->ioctl_sock);
04837 
04838         genl_family_put(drv->nl80211);
04839         nl_cache_free(drv->nl_cache);
04840         nl_handle_destroy(drv->nl_handle);
04841         nl_cb_put(drv->nl_cb);
04842 
04843         os_free(drv);
04844         return NULL;
04845 }
04846 
04847 
04848 static void i802_deinit(void *priv)
04849 {
04850         wpa_driver_nl80211_deinit(priv);
04851 }
04852 
04853 #endif /* HOSTAPD */
04854 
04855 
04856 static enum nl80211_iftype wpa_driver_nl80211_if_type(
04857         enum wpa_driver_if_type type)
04858 {
04859         switch (type) {
04860         case WPA_IF_STATION:
04861                 return NL80211_IFTYPE_STATION;
04862         case WPA_IF_AP_VLAN:
04863                 return NL80211_IFTYPE_AP_VLAN;
04864         case WPA_IF_AP_BSS:
04865                 return NL80211_IFTYPE_AP;
04866         }
04867         return -1;
04868 }
04869 
04870 
04871 static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
04872                                      const char *ifname, const u8 *addr,
04873                                      void *bss_ctx, void **drv_priv,
04874                                      char *force_ifname, u8 *if_addr)
04875 {
04876         struct i802_bss *bss = priv;
04877         struct wpa_driver_nl80211_data *drv = bss->drv;
04878         int ifidx;
04879 #ifdef HOSTAPD
04880         struct i802_bss *new_bss = NULL;
04881 
04882         if (type == WPA_IF_AP_BSS) {
04883                 new_bss = os_zalloc(sizeof(*new_bss));
04884                 if (new_bss == NULL)
04885                         return -1;
04886         }
04887 #endif /* HOSTAPD */
04888 
04889         if (addr)
04890                 os_memcpy(if_addr, addr, ETH_ALEN);
04891         ifidx = nl80211_create_iface(drv, ifname,
04892                                      wpa_driver_nl80211_if_type(type), addr,
04893                                      0);
04894         if (ifidx < 0) {
04895 #ifdef HOSTAPD
04896                 os_free(new_bss);
04897 #endif /* HOSTAPD */
04898                 return -1;
04899         }
04900 
04901         if (!addr &&
04902             linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, if_addr) < 0)
04903                 return -1;
04904 
04905 #ifdef HOSTAPD
04906         if (type == WPA_IF_AP_BSS) {
04907                 if (linux_set_iface_flags(drv->ioctl_sock, ifname, 1)) {
04908                         nl80211_remove_iface(drv, ifidx);
04909                         os_free(new_bss);
04910                         return -1;
04911                 }
04912                 os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
04913                 new_bss->ifindex = ifidx;
04914                 new_bss->drv = drv;
04915                 new_bss->next = drv->first_bss.next;
04916                 drv->first_bss.next = new_bss;
04917                 if (drv_priv)
04918                         *drv_priv = new_bss;
04919         }
04920 #endif /* HOSTAPD */
04921 
04922         return 0;
04923 }
04924 
04925 
04926 static int wpa_driver_nl80211_if_remove(void *priv,
04927                                         enum wpa_driver_if_type type,
04928                                         const char *ifname)
04929 {
04930         struct i802_bss *bss = priv;
04931         struct wpa_driver_nl80211_data *drv = bss->drv;
04932         int ifindex = if_nametoindex(ifname);
04933 
04934         wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d",
04935                    __func__, type, ifname, ifindex);
04936         if (ifindex <= 0)
04937                 return -1;
04938         nl80211_remove_iface(drv, ifindex);
04939 
04940 #ifdef HOSTAPD
04941         if (type != WPA_IF_AP_BSS)
04942                 return 0;
04943 
04944         if (bss != &drv->first_bss) {
04945                 struct i802_bss *tbss = &drv->first_bss;
04946 
04947                 while (tbss) {
04948                         if (tbss->next != bss)
04949                                 continue;
04950 
04951                         tbss->next = bss->next;
04952                         os_free(bss);
04953                         break;
04954                 }
04955         }
04956 #endif /* HOSTAPD */
04957 
04958         return 0;
04959 }
04960 
04961 
04962 static int cookie_handler(struct nl_msg *msg, void *arg)
04963 {
04964         struct nlattr *tb[NL80211_ATTR_MAX + 1];
04965         struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
04966         u64 *cookie = arg;
04967         nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
04968                   genlmsg_attrlen(gnlh, 0), NULL);
04969         if (tb[NL80211_ATTR_COOKIE])
04970                 *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
04971         return NL_SKIP;
04972 }
04973 
04974 
04975 static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
04976                                           const u8 *dst, const u8 *src,
04977                                           const u8 *bssid,
04978                                           const u8 *data, size_t data_len)
04979 {
04980         struct i802_bss *bss = priv;
04981         struct wpa_driver_nl80211_data *drv = bss->drv;
04982         int ret = -1;
04983         struct nl_msg *msg;
04984         u8 *buf;
04985         struct ieee80211_hdr *hdr;
04986         u64 cookie;
04987 
04988         wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d)",
04989                    drv->ifindex);
04990 
04991         buf = os_zalloc(24 + data_len);
04992         if (buf == NULL)
04993                 return ret;
04994         os_memcpy(buf + 24, data, data_len);
04995         hdr = (struct ieee80211_hdr *) buf;
04996         hdr->frame_control =
04997                 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
04998         os_memcpy(hdr->addr1, dst, ETH_ALEN);
04999         os_memcpy(hdr->addr2, src, ETH_ALEN);
05000         os_memcpy(hdr->addr3, bssid, ETH_ALEN);
05001 
05002         if (drv->nlmode == NL80211_IFTYPE_AP) {
05003                 ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len);
05004                 os_free(buf);
05005                 return ret;
05006         }
05007 
05008         msg = nlmsg_alloc();
05009         if (!msg) {
05010                 os_free(buf);
05011                 return -1;
05012         }
05013 
05014         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
05015                     NL80211_CMD_ACTION, 0);
05016 
05017         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
05018         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
05019         NLA_PUT(msg, NL80211_ATTR_FRAME, 24 + data_len, buf);
05020         os_free(buf);
05021         buf = NULL;
05022 
05023         cookie = 0;
05024         ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
05025         msg = NULL;
05026         if (ret) {
05027                 wpa_printf(MSG_DEBUG, "nl80211: Action command failed: ret=%d "
05028                            "(%s)", ret, strerror(-ret));
05029                 goto nla_put_failure;
05030         }
05031         wpa_printf(MSG_DEBUG, "nl80211: Action TX command accepted; "
05032                    "cookie 0x%llx", (long long unsigned int) cookie);
05033         drv->send_action_cookie = cookie;
05034         drv->pending_send_action = 1;
05035         ret = 0;
05036 
05037 nla_put_failure:
05038         os_free(buf);
05039         nlmsg_free(msg);
05040         return ret;
05041 }
05042 
05043 
05044 static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
05045                                                 unsigned int duration)
05046 {
05047         struct i802_bss *bss = priv;
05048         struct wpa_driver_nl80211_data *drv = bss->drv;
05049         struct nl_msg *msg;
05050         int ret;
05051         u64 cookie;
05052 
05053         msg = nlmsg_alloc();
05054         if (!msg)
05055                 return -1;
05056 
05057         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
05058                     NL80211_CMD_REMAIN_ON_CHANNEL, 0);
05059 
05060         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
05061         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
05062         NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
05063 
05064         cookie = 0;
05065         ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
05066         if (ret == 0) {
05067                 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
05068                            "0x%llx for freq=%u MHz duration=%u",
05069                            (long long unsigned int) cookie, freq, duration);
05070                 drv->remain_on_chan_cookie = cookie;
05071                 return 0;
05072         }
05073         wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
05074                    "(freq=%d): %d (%s)", freq, ret, strerror(-ret));
05075 nla_put_failure:
05076         return -1;
05077 }
05078 
05079 
05080 static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
05081 {
05082         struct i802_bss *bss = priv;
05083         struct wpa_driver_nl80211_data *drv = bss->drv;
05084         struct nl_msg *msg;
05085         int ret;
05086 
05087         if (!drv->pending_remain_on_chan) {
05088                 wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
05089                            "to cancel");
05090                 return -1;
05091         }
05092 
05093         wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
05094                    "0x%llx",
05095                    (long long unsigned int) drv->remain_on_chan_cookie);
05096 
05097         msg = nlmsg_alloc();
05098         if (!msg)
05099                 return -1;
05100 
05101         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
05102                     NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 0);
05103 
05104         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
05105         NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
05106 
05107         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
05108         if (ret == 0)
05109                 return 0;
05110         wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
05111                    "%d (%s)", ret, strerror(-ret));
05112 nla_put_failure:
05113         return -1;
05114 }
05115 
05116 
05117 static void wpa_driver_nl80211_probe_req_report_timeout(void *eloop_ctx,
05118                                                         void *timeout_ctx)
05119 {
05120         struct wpa_driver_nl80211_data *drv = eloop_ctx;
05121         if (drv->monitor_ifidx < 0)
05122                 return; /* monitor interface already removed */
05123 
05124         if (drv->nlmode != NL80211_IFTYPE_STATION)
05125                 return; /* not in station mode anymore */
05126 
05127         if (drv->probe_req_report)
05128                 return; /* reporting enabled */
05129 
05130         wpa_printf(MSG_DEBUG, "nl80211: Remove monitor interface due to no "
05131                    "Probe Request reporting needed anymore");
05132         nl80211_remove_monitor_interface(drv);
05133 }
05134 
05135 
05136 static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
05137 {
05138         struct i802_bss *bss = priv;
05139         struct wpa_driver_nl80211_data *drv = bss->drv;
05140 
05141         if (drv->nlmode != NL80211_IFTYPE_STATION) {
05142                 wpa_printf(MSG_DEBUG, "nl80211: probe_req_report control only "
05143                            "allowed in station mode (iftype=%d)",
05144                            drv->nlmode);
05145                 return -1;
05146         }
05147         drv->probe_req_report = report;
05148 
05149         if (report) {
05150                 eloop_cancel_timeout(
05151                         wpa_driver_nl80211_probe_req_report_timeout,
05152                         drv, NULL);
05153                 if (drv->monitor_ifidx < 0 &&
05154                     nl80211_create_monitor_interface(drv))
05155                         return -1;
05156         } else {
05157                 /*
05158                  * It takes a while to remove the monitor interface, so try to
05159                  * avoid doing this if it is needed again shortly. Instead,
05160                  * schedule the interface to be removed later if no need for it
05161                  * is seen.
05162                  */
05163                 wpa_printf(MSG_DEBUG, "nl80211: Scheduling monitor interface "
05164                            "to be removed after 10 seconds of no use");
05165                 eloop_register_timeout(
05166                         10, 0, wpa_driver_nl80211_probe_req_report_timeout,
05167                         drv, NULL);
05168         }
05169 
05170         return 0;
05171 }
05172 
05173 
05174 static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
05175                                      int ifindex, int disabled)
05176 {
05177         struct nl_msg *msg;
05178         struct nlattr *bands, *band;
05179         int ret;
05180 
05181         msg = nlmsg_alloc();
05182         if (!msg)
05183                 return -1;
05184 
05185         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
05186                     NL80211_CMD_SET_TX_BITRATE_MASK, 0);
05187         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
05188 
05189         bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
05190         if (!bands)
05191                 goto nla_put_failure;
05192 
05193         /*
05194          * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
05195          * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
05196          * rates. All 5 GHz rates are left enabled.
05197          */
05198         band = nla_nest_start(msg, NL80211_BAND_2GHZ);
05199         if (!band)
05200                 goto nla_put_failure;
05201         NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
05202                 "\x0c\x12\x18\x24\x30\x48\x60\x6c");
05203         nla_nest_end(msg, band);
05204 
05205         nla_nest_end(msg, bands);
05206 
05207         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
05208         msg = NULL;
05209         if (ret) {
05210                 wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
05211                            "(%s)", ret, strerror(-ret));
05212         }
05213 
05214         return ret;
05215 
05216 nla_put_failure:
05217         nlmsg_free(msg);
05218         return -1;
05219 }
05220 
05221 
05222 static int wpa_driver_nl80211_disable_11b_rates(void *priv, int disabled)
05223 {
05224         struct i802_bss *bss = priv;
05225         struct wpa_driver_nl80211_data *drv = bss->drv;
05226         drv->disable_11b_rates = disabled;
05227         return nl80211_disable_11b_rates(drv, drv->ifindex, disabled);
05228 }
05229 
05230 
05231 static int wpa_driver_nl80211_deinit_ap(void *priv)
05232 {
05233         struct i802_bss *bss = priv;
05234         struct wpa_driver_nl80211_data *drv = bss->drv;
05235         if (drv->nlmode != NL80211_IFTYPE_AP)
05236                 return -1;
05237         wpa_driver_nl80211_del_beacon(drv);
05238         return wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
05239 }
05240 
05241 
05242 static void wpa_driver_nl80211_resume(void *priv)
05243 {
05244         struct i802_bss *bss = priv;
05245         struct wpa_driver_nl80211_data *drv = bss->drv;
05246         if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1)) {
05247                 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on "
05248                            "resume event");
05249         }
05250 }
05251 
05252 
05253 static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
05254                                   const u8 *ies, size_t ies_len)
05255 {
05256         struct i802_bss *bss = priv;
05257         struct wpa_driver_nl80211_data *drv = bss->drv;
05258         int ret;
05259         u8 *data, *pos;
05260         size_t data_len;
05261         u8 own_addr[ETH_ALEN];
05262 
05263         if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, own_addr) < 0)
05264                 return -1;
05265 
05266         if (action != 1) {
05267                 wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
05268                            "action %d", action);
05269                 return -1;
05270         }
05271 
05272         /*
05273          * Action frame payload:
05274          * Category[1] = 6 (Fast BSS Transition)
05275          * Action[1] = 1 (Fast BSS Transition Request)
05276          * STA Address
05277          * Target AP Address
05278          * FT IEs
05279          */
05280 
05281         data_len = 2 + 2 * ETH_ALEN + ies_len;
05282         data = os_malloc(data_len);
05283         if (data == NULL)
05284                 return -1;
05285         pos = data;
05286         *pos++ = 0x06; /* FT Action category */
05287         *pos++ = action;
05288         os_memcpy(pos, own_addr, ETH_ALEN);
05289         pos += ETH_ALEN;
05290         os_memcpy(pos, target_ap, ETH_ALEN);
05291         pos += ETH_ALEN;
05292         os_memcpy(pos, ies, ies_len);
05293 
05294         ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, drv->bssid,
05295                                              own_addr, drv->bssid,
05296                                              data, data_len);
05297         os_free(data);
05298 
05299         return ret;
05300 }
05301 
05302 
05303 static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
05304 {
05305         struct i802_bss *bss = priv;
05306         struct wpa_driver_nl80211_data *drv = bss->drv;
05307         struct nl_msg *msg, *cqm = NULL;
05308 
05309         wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
05310                    "hysteresis=%d", threshold, hysteresis);
05311 
05312         msg = nlmsg_alloc();
05313         if (!msg)
05314                 return -1;
05315 
05316         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
05317                     0, NL80211_CMD_SET_CQM, 0);
05318 
05319         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
05320 
05321         cqm = nlmsg_alloc();
05322         if (cqm == NULL)
05323                 return -1;
05324 
05325         NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
05326         NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
05327         nla_put_nested(msg, NL80211_ATTR_CQM, cqm);
05328 
05329         if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
05330                 return 0;
05331         msg = NULL;
05332 
05333 nla_put_failure:
05334         if (cqm)
05335                 nlmsg_free(cqm);
05336         nlmsg_free(msg);
05337         return -1;
05338 }
05339 
05340 
05341 static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
05342                               int encrypt)
05343 {
05344         struct i802_bss *bss = priv;
05345         struct wpa_driver_nl80211_data *drv = bss->drv;
05346         return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt);
05347 }
05348 
05349 
05350 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
05351         .name = "nl80211",
05352         .desc = "Linux nl80211/cfg80211",
05353         .get_bssid = wpa_driver_nl80211_get_bssid,
05354         .get_ssid = wpa_driver_nl80211_get_ssid,
05355         .set_key = wpa_driver_nl80211_set_key,
05356         .scan2 = wpa_driver_nl80211_scan,
05357         .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
05358         .deauthenticate = wpa_driver_nl80211_deauthenticate,
05359         .disassociate = wpa_driver_nl80211_disassociate,
05360         .authenticate = wpa_driver_nl80211_authenticate,
05361         .associate = wpa_driver_nl80211_associate,
05362         .init = wpa_driver_nl80211_init,
05363         .deinit = wpa_driver_nl80211_deinit,
05364         .get_capa = wpa_driver_nl80211_get_capa,
05365         .set_operstate = wpa_driver_nl80211_set_operstate,
05366         .set_supp_port = wpa_driver_nl80211_set_supp_port,
05367         .set_country = wpa_driver_nl80211_set_country,
05368         .set_beacon = wpa_driver_nl80211_set_beacon,
05369         .if_add = wpa_driver_nl80211_if_add,
05370         .if_remove = wpa_driver_nl80211_if_remove,
05371         .send_mlme = wpa_driver_nl80211_send_mlme,
05372         .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
05373         .sta_add = wpa_driver_nl80211_sta_add,
05374         .sta_remove = wpa_driver_nl80211_sta_remove,
05375         .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
05376         .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
05377 #ifdef HOSTAPD
05378         .hapd_init = i802_init,
05379         .hapd_deinit = i802_deinit,
05380         .get_seqnum = i802_get_seqnum,
05381         .flush = i802_flush,
05382         .read_sta_data = i802_read_sta_data,
05383         .sta_deauth = i802_sta_deauth,
05384         .sta_disassoc = i802_sta_disassoc,
05385         .get_inact_sec = i802_get_inact_sec,
05386         .sta_clear_stats = i802_sta_clear_stats,
05387         .set_rts = i802_set_rts,
05388         .set_frag = i802_set_frag,
05389         .set_rate_sets = i802_set_rate_sets,
05390         .set_cts_protect = i802_set_cts_protect,
05391         .set_preamble = i802_set_preamble,
05392         .set_short_slot_time = i802_set_short_slot_time,
05393         .set_tx_queue_params = i802_set_tx_queue_params,
05394         .set_sta_vlan = i802_set_sta_vlan,
05395         .set_wds_sta = i802_set_wds_sta,
05396 #endif /* HOSTAPD */
05397         .set_freq = i802_set_freq,
05398         .send_action = wpa_driver_nl80211_send_action,
05399         .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
05400         .cancel_remain_on_channel =
05401         wpa_driver_nl80211_cancel_remain_on_channel,
05402         .probe_req_report = wpa_driver_nl80211_probe_req_report,
05403         .disable_11b_rates = wpa_driver_nl80211_disable_11b_rates,
05404         .deinit_ap = wpa_driver_nl80211_deinit_ap,
05405         .resume = wpa_driver_nl80211_resume,
05406         .send_ft_action = nl80211_send_ft_action,
05407         .signal_monitor = nl80211_signal_monitor,
05408         .send_frame = nl80211_send_frame,
05409 };


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:33:19