00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
00044
00045
00046 #ifndef IFF_LOWER_UP
00047 #define IFF_LOWER_UP 0x10000
00048 #endif
00049 #ifndef IFF_DORMANT
00050 #define IFF_DORMANT 0x20000
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;
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;
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
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
00148 static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
00149 {
00150 return 0;
00151 }
00152 #endif
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
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
00416
00417
00418
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
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
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
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
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
00572
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
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;
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
01000
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
01029
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
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
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
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
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
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
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
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
01494
01495
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
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
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
01692
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
01705 drv->ap_scan_as_station = 1;
01706 ret = 0;
01707 } else
01708 goto nla_put_failure;
01709 #else
01710 goto nla_put_failure;
01711 #endif
01712 }
01713
01714
01715
01716 timeout = 10;
01717 if (drv->scan_complete_events) {
01718
01719
01720
01721
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;
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
02141
02142
02143 if (ret || !set_tx || alg == WPA_ALG_NONE)
02144 return ret;
02145 #ifdef HOSTAPD
02146 if (addr)
02147 return ret;
02148 #else
02149 if (drv->nlmode == NL80211_IFTYPE_AP && addr)
02150 return ret;
02151 #endif
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
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
02427
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
02456
02457
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
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
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
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
02663
02664
02665 for (m = 0; m < *num_modes; m++) {
02666 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
02667 return modes;
02668 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
02669 mode11g_idx = m;
02670 }
02671
02672 if (mode11g_idx < 0)
02673 return modes;
02674
02675 nmodes = os_realloc(modes, (*num_modes + 1) * sizeof(*nmodes));
02676 if (nmodes == NULL)
02677 return modes;
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;
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;
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;
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,
02765 0x0e, 0x00,
02766 0x02, 0xc0, 0x00, 0x00,
02767 IEEE80211_RADIOTAP_F_FRAG,
02768 0x00,
02769 0x00, 0x00,
02770 0x00, 0x00,
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
02815
02816
02817
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
02992 del_ifidx(drv, ifidx);
02993 #endif
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
03065 add_ifidx(drv, ifidx);
03066 #endif
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
03087 if (ret == -ENFILE && if_nametoindex(ifname)) {
03088 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
03089
03090
03091 nl80211_remove_iface(drv, if_nametoindex(ifname));
03092
03093
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
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
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
03243
03244
03245 #define PASS 0xFF
03246 #define FAIL 0xFE
03247
03248 static struct sock_filter msock_filter_insns[] = {
03249
03250
03251
03252
03253 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
03254
03255 BPF_STMT(BPF_MISC| BPF_TAX, 0),
03256
03257 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 3),
03258
03259 BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
03260
03261 BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
03262
03263 BPF_STMT(BPF_MISC| BPF_TAX, 0),
03264
03265
03266
03267
03268
03269
03270 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
03271
03272 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
03273
03274 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285 #if 0
03286
03287
03288
03289
03290 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
03291
03292 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0c),
03293
03294 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 8, 0, FAIL),
03295 #endif
03296
03297 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
03298
03299 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x03),
03300
03301 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 3, PASS, 0),
03302
03303
03304
03305
03306
03307 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
03308
03309 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80),
03310
03311 BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 6),
03312
03313 BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 24),
03314
03315 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
03316
03317 BPF_STMT(BPF_MISC | BPF_TAX, 0),
03318
03319
03320
03321
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
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
03335
03336 BPF_STMT(BPF_RET | BPF_K, 0),
03337
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
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
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
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
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
03507 if (qos) {
03508
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
03578
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
03619
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
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;
04021 }
04022
04023
04024
04025
04026
04027 if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0) == 0) {
04028
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
04043 if (drv->monitor_ifidx < 0 &&
04044 nl80211_create_monitor_interface(drv))
04045 return -1;
04046 } else if (!ret && nlmode != NL80211_IFTYPE_AP) {
04047
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
04198
04199
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
04266
04267
04268
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
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
04388
04389
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
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
04472
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
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
04682
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;
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
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
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
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
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
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
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;
05094
05095 if (drv->nlmode != NL80211_IFTYPE_STATION)
05096 return;
05097
05098 if (drv->probe_req_report)
05099 return;
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
05130
05131
05132
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
05166
05167
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
05245
05246
05247
05248
05249
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;
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
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 };