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


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:36