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