1 /* 2 * cfg80211 scan result handling 3 * 4 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> 5 */ 6 #include <linux/kernel.h> 7 #include <linux/slab.h> 8 #include <linux/module.h> 9 #include <linux/netdevice.h> 10 #include <linux/wireless.h> 11 #include <linux/nl80211.h> 12 #include <linux/etherdevice.h> 13 #include <net/arp.h> 14 #include <net/cfg80211.h> 15 #include <net/cfg80211-wext.h> 16 #include <net/iw_handler.h> 17 #include "core.h" 18 #include "nl80211.h" 19 #include "wext-compat.h" 20 #include "rdev-ops.h" 21 22 #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) 23 24 static void bss_release(struct kref *ref) 25 { 26 struct cfg80211_bss_ies *ies; 27 struct cfg80211_internal_bss *bss; 28 29 bss = container_of(ref, struct cfg80211_internal_bss, ref); 30 31 if (WARN_ON(atomic_read(&bss->hold))) 32 return; 33 34 if (bss->pub.free_priv) 35 bss->pub.free_priv(&bss->pub); 36 37 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies); 38 if (ies) 39 kfree_rcu(ies, rcu_head); 40 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies); 41 if (ies) 42 kfree_rcu(ies, rcu_head); 43 44 kfree(bss); 45 } 46 47 /* must hold dev->bss_lock! */ 48 static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, 49 struct cfg80211_internal_bss *bss) 50 { 51 list_del_init(&bss->list); 52 rb_erase(&bss->rbn, &dev->bss_tree); 53 kref_put(&bss->ref, bss_release); 54 } 55 56 /* must hold dev->bss_lock! */ 57 static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, 58 unsigned long expire_time) 59 { 60 struct cfg80211_internal_bss *bss, *tmp; 61 bool expired = false; 62 63 list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { 64 if (atomic_read(&bss->hold)) 65 continue; 66 if (!time_after(expire_time, bss->ts)) 67 continue; 68 69 __cfg80211_unlink_bss(dev, bss); 70 expired = true; 71 } 72 73 if (expired) 74 dev->bss_generation++; 75 } 76 77 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) 78 { 79 struct cfg80211_scan_request *request; 80 struct wireless_dev *wdev; 81 #ifdef CONFIG_CFG80211_WEXT 82 union iwreq_data wrqu; 83 #endif 84 85 ASSERT_RDEV_LOCK(rdev); 86 87 request = rdev->scan_req; 88 89 if (!request) 90 return; 91 92 wdev = request->wdev; 93 94 /* 95 * This must be before sending the other events! 96 * Otherwise, wpa_supplicant gets completely confused with 97 * wext events. 98 */ 99 if (wdev->netdev) 100 cfg80211_sme_scan_done(wdev->netdev); 101 102 if (request->aborted) { 103 nl80211_send_scan_aborted(rdev, wdev); 104 } else { 105 if (request->flags & NL80211_SCAN_FLAG_FLUSH) { 106 /* flush entries from previous scans */ 107 spin_lock_bh(&rdev->bss_lock); 108 __cfg80211_bss_expire(rdev, request->scan_start); 109 spin_unlock_bh(&rdev->bss_lock); 110 } 111 nl80211_send_scan_done(rdev, wdev); 112 } 113 114 #ifdef CONFIG_CFG80211_WEXT 115 if (wdev->netdev && !request->aborted) { 116 memset(&wrqu, 0, sizeof(wrqu)); 117 118 wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL); 119 } 120 #endif 121 122 if (wdev->netdev) 123 dev_put(wdev->netdev); 124 125 rdev->scan_req = NULL; 126 127 /* 128 * OK. If this is invoked with "leak" then we can't 129 * free this ... but we've cleaned it up anyway. The 130 * driver failed to call the scan_done callback, so 131 * all bets are off, it might still be trying to use 132 * the scan request or not ... if it accesses the dev 133 * in there (it shouldn't anyway) then it may crash. 134 */ 135 if (!leak) 136 kfree(request); 137 } 138 139 void __cfg80211_scan_done(struct work_struct *wk) 140 { 141 struct cfg80211_registered_device *rdev; 142 143 rdev = container_of(wk, struct cfg80211_registered_device, 144 scan_done_wk); 145 146 cfg80211_lock_rdev(rdev); 147 ___cfg80211_scan_done(rdev, false); 148 cfg80211_unlock_rdev(rdev); 149 } 150 151 void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 152 { 153 trace_cfg80211_scan_done(request, aborted); 154 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 155 156 request->aborted = aborted; 157 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk); 158 } 159 EXPORT_SYMBOL(cfg80211_scan_done); 160 161 void __cfg80211_sched_scan_results(struct work_struct *wk) 162 { 163 struct cfg80211_registered_device *rdev; 164 struct cfg80211_sched_scan_request *request; 165 166 rdev = container_of(wk, struct cfg80211_registered_device, 167 sched_scan_results_wk); 168 169 request = rdev->sched_scan_req; 170 171 mutex_lock(&rdev->sched_scan_mtx); 172 173 /* we don't have sched_scan_req anymore if the scan is stopping */ 174 if (request) { 175 if (request->flags & NL80211_SCAN_FLAG_FLUSH) { 176 /* flush entries from previous scans */ 177 spin_lock_bh(&rdev->bss_lock); 178 __cfg80211_bss_expire(rdev, request->scan_start); 179 spin_unlock_bh(&rdev->bss_lock); 180 request->scan_start = 181 jiffies + msecs_to_jiffies(request->interval); 182 } 183 nl80211_send_sched_scan_results(rdev, request->dev); 184 } 185 186 mutex_unlock(&rdev->sched_scan_mtx); 187 } 188 189 void cfg80211_sched_scan_results(struct wiphy *wiphy) 190 { 191 trace_cfg80211_sched_scan_results(wiphy); 192 /* ignore if we're not scanning */ 193 if (wiphy_to_dev(wiphy)->sched_scan_req) 194 queue_work(cfg80211_wq, 195 &wiphy_to_dev(wiphy)->sched_scan_results_wk); 196 } 197 EXPORT_SYMBOL(cfg80211_sched_scan_results); 198 199 void cfg80211_sched_scan_stopped(struct wiphy *wiphy) 200 { 201 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 202 203 trace_cfg80211_sched_scan_stopped(wiphy); 204 205 mutex_lock(&rdev->sched_scan_mtx); 206 __cfg80211_stop_sched_scan(rdev, true); 207 mutex_unlock(&rdev->sched_scan_mtx); 208 } 209 EXPORT_SYMBOL(cfg80211_sched_scan_stopped); 210 211 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 212 bool driver_initiated) 213 { 214 struct net_device *dev; 215 216 lockdep_assert_held(&rdev->sched_scan_mtx); 217 218 if (!rdev->sched_scan_req) 219 return -ENOENT; 220 221 dev = rdev->sched_scan_req->dev; 222 223 if (!driver_initiated) { 224 int err = rdev_sched_scan_stop(rdev, dev); 225 if (err) 226 return err; 227 } 228 229 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED); 230 231 kfree(rdev->sched_scan_req); 232 rdev->sched_scan_req = NULL; 233 234 return 0; 235 } 236 237 /* must hold dev->bss_lock! */ 238 void cfg80211_bss_age(struct cfg80211_registered_device *dev, 239 unsigned long age_secs) 240 { 241 struct cfg80211_internal_bss *bss; 242 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); 243 244 list_for_each_entry(bss, &dev->bss_list, list) 245 bss->ts -= age_jiffies; 246 } 247 248 void cfg80211_bss_expire(struct cfg80211_registered_device *dev) 249 { 250 __cfg80211_bss_expire(dev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE); 251 } 252 253 const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) 254 { 255 while (len > 2 && ies[0] != eid) { 256 len -= ies[1] + 2; 257 ies += ies[1] + 2; 258 } 259 if (len < 2) 260 return NULL; 261 if (len < 2 + ies[1]) 262 return NULL; 263 return ies; 264 } 265 EXPORT_SYMBOL(cfg80211_find_ie); 266 267 const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, 268 const u8 *ies, int len) 269 { 270 struct ieee80211_vendor_ie *ie; 271 const u8 *pos = ies, *end = ies + len; 272 int ie_oui; 273 274 while (pos < end) { 275 pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, 276 end - pos); 277 if (!pos) 278 return NULL; 279 280 if (end - pos < sizeof(*ie)) 281 return NULL; 282 283 ie = (struct ieee80211_vendor_ie *)pos; 284 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; 285 if (ie_oui == oui && ie->oui_type == oui_type) 286 return pos; 287 288 pos += 2 + ie->len; 289 } 290 return NULL; 291 } 292 EXPORT_SYMBOL(cfg80211_find_vendor_ie); 293 294 static int cmp_ies(u8 num, const u8 *ies1, int len1, const u8 *ies2, int len2) 295 { 296 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); 297 const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); 298 299 /* equal if both missing */ 300 if (!ie1 && !ie2) 301 return 0; 302 /* sort missing IE before (left of) present IE */ 303 if (!ie1) 304 return -1; 305 if (!ie2) 306 return 1; 307 308 /* sort by length first, then by contents */ 309 if (ie1[1] != ie2[1]) 310 return ie2[1] - ie1[1]; 311 return memcmp(ie1 + 2, ie2 + 2, ie1[1]); 312 } 313 314 static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, 315 const u8 *ssid, size_t ssid_len) 316 { 317 const struct cfg80211_bss_ies *ies; 318 const u8 *ssidie; 319 320 if (bssid && !ether_addr_equal(a->bssid, bssid)) 321 return false; 322 323 if (!ssid) 324 return true; 325 326 ies = rcu_access_pointer(a->ies); 327 if (!ies) 328 return false; 329 ssidie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len); 330 if (!ssidie) 331 return false; 332 if (ssidie[1] != ssid_len) 333 return false; 334 return memcmp(ssidie + 2, ssid, ssid_len) == 0; 335 } 336 337 static bool is_mesh_bss(struct cfg80211_bss *a) 338 { 339 const struct cfg80211_bss_ies *ies; 340 const u8 *ie; 341 342 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) 343 return false; 344 345 ies = rcu_access_pointer(a->ies); 346 if (!ies) 347 return false; 348 349 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ies->data, ies->len); 350 if (!ie) 351 return false; 352 353 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, ies->data, ies->len); 354 if (!ie) 355 return false; 356 357 return true; 358 } 359 360 static bool is_mesh(struct cfg80211_bss *a, 361 const u8 *meshid, size_t meshidlen, 362 const u8 *meshcfg) 363 { 364 const struct cfg80211_bss_ies *ies; 365 const u8 *ie; 366 367 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) 368 return false; 369 370 ies = rcu_access_pointer(a->ies); 371 if (!ies) 372 return false; 373 374 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ies->data, ies->len); 375 if (!ie) 376 return false; 377 if (ie[1] != meshidlen) 378 return false; 379 if (memcmp(ie + 2, meshid, meshidlen)) 380 return false; 381 382 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, ies->data, ies->len); 383 if (!ie) 384 return false; 385 if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) 386 return false; 387 388 /* 389 * Ignore mesh capability (last two bytes of the IE) when 390 * comparing since that may differ between stations taking 391 * part in the same mesh. 392 */ 393 return memcmp(ie + 2, meshcfg, 394 sizeof(struct ieee80211_meshconf_ie) - 2) == 0; 395 } 396 397 static int cmp_bss_core(struct cfg80211_bss *a, struct cfg80211_bss *b) 398 { 399 const struct cfg80211_bss_ies *a_ies, *b_ies; 400 int r; 401 402 if (a->channel != b->channel) 403 return b->channel->center_freq - a->channel->center_freq; 404 405 if (is_mesh_bss(a) && is_mesh_bss(b)) { 406 a_ies = rcu_access_pointer(a->ies); 407 if (!a_ies) 408 return -1; 409 b_ies = rcu_access_pointer(b->ies); 410 if (!b_ies) 411 return 1; 412 413 r = cmp_ies(WLAN_EID_MESH_ID, 414 a_ies->data, a_ies->len, 415 b_ies->data, b_ies->len); 416 if (r) 417 return r; 418 return cmp_ies(WLAN_EID_MESH_CONFIG, 419 a_ies->data, a_ies->len, 420 b_ies->data, b_ies->len); 421 } 422 423 /* 424 * we can't use compare_ether_addr here since we need a < > operator. 425 * The binary return value of compare_ether_addr isn't enough 426 */ 427 return memcmp(a->bssid, b->bssid, sizeof(a->bssid)); 428 } 429 430 static int cmp_bss(struct cfg80211_bss *a, 431 struct cfg80211_bss *b) 432 { 433 const struct cfg80211_bss_ies *a_ies, *b_ies; 434 int r; 435 436 r = cmp_bss_core(a, b); 437 if (r) 438 return r; 439 440 a_ies = rcu_access_pointer(a->ies); 441 if (!a_ies) 442 return -1; 443 b_ies = rcu_access_pointer(b->ies); 444 if (!b_ies) 445 return 1; 446 447 return cmp_ies(WLAN_EID_SSID, 448 a_ies->data, a_ies->len, 449 b_ies->data, b_ies->len); 450 } 451 452 static int cmp_hidden_bss(struct cfg80211_bss *a, struct cfg80211_bss *b) 453 { 454 const struct cfg80211_bss_ies *a_ies, *b_ies; 455 const u8 *ie1; 456 const u8 *ie2; 457 int i; 458 int r; 459 460 r = cmp_bss_core(a, b); 461 if (r) 462 return r; 463 464 a_ies = rcu_access_pointer(a->ies); 465 if (!a_ies) 466 return -1; 467 b_ies = rcu_access_pointer(b->ies); 468 if (!b_ies) 469 return 1; 470 471 ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len); 472 ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len); 473 474 /* 475 * Key comparator must use same algorithm in any rb-tree 476 * search function (order is important), otherwise ordering 477 * of items in the tree is broken and search gives incorrect 478 * results. This code uses same order as cmp_ies() does. 479 * 480 * Note that due to the differring behaviour with hidden SSIDs 481 * this function only works when "b" is the tree element and 482 * "a" is the key we're looking for. 483 */ 484 485 /* sort missing IE before (left of) present IE */ 486 if (!ie1) 487 return -1; 488 if (!ie2) 489 return 1; 490 491 /* zero-size SSID is used as an indication of the hidden bss */ 492 if (!ie2[1]) 493 return 0; 494 495 /* sort by length first, then by contents */ 496 if (ie1[1] != ie2[1]) 497 return ie2[1] - ie1[1]; 498 499 /* 500 * zeroed SSID ie is another indication of a hidden bss; 501 * if it isn't zeroed just return the regular sort value 502 * to find the next candidate 503 */ 504 for (i = 0; i < ie2[1]; i++) 505 if (ie2[i + 2]) 506 return memcmp(ie1 + 2, ie2 + 2, ie1[1]); 507 508 return 0; 509 } 510 511 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, 512 struct ieee80211_channel *channel, 513 const u8 *bssid, 514 const u8 *ssid, size_t ssid_len, 515 u16 capa_mask, u16 capa_val) 516 { 517 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); 518 struct cfg80211_internal_bss *bss, *res = NULL; 519 unsigned long now = jiffies; 520 521 trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask, 522 capa_val); 523 524 spin_lock_bh(&dev->bss_lock); 525 526 list_for_each_entry(bss, &dev->bss_list, list) { 527 if ((bss->pub.capability & capa_mask) != capa_val) 528 continue; 529 if (channel && bss->pub.channel != channel) 530 continue; 531 /* Don't get expired BSS structs */ 532 if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) && 533 !atomic_read(&bss->hold)) 534 continue; 535 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) { 536 res = bss; 537 kref_get(&res->ref); 538 break; 539 } 540 } 541 542 spin_unlock_bh(&dev->bss_lock); 543 if (!res) 544 return NULL; 545 trace_cfg80211_return_bss(&res->pub); 546 return &res->pub; 547 } 548 EXPORT_SYMBOL(cfg80211_get_bss); 549 550 struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy, 551 struct ieee80211_channel *channel, 552 const u8 *meshid, size_t meshidlen, 553 const u8 *meshcfg) 554 { 555 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); 556 struct cfg80211_internal_bss *bss, *res = NULL; 557 558 spin_lock_bh(&dev->bss_lock); 559 560 list_for_each_entry(bss, &dev->bss_list, list) { 561 if (channel && bss->pub.channel != channel) 562 continue; 563 if (is_mesh(&bss->pub, meshid, meshidlen, meshcfg)) { 564 res = bss; 565 kref_get(&res->ref); 566 break; 567 } 568 } 569 570 spin_unlock_bh(&dev->bss_lock); 571 if (!res) 572 return NULL; 573 return &res->pub; 574 } 575 EXPORT_SYMBOL(cfg80211_get_mesh); 576 577 578 static void rb_insert_bss(struct cfg80211_registered_device *dev, 579 struct cfg80211_internal_bss *bss) 580 { 581 struct rb_node **p = &dev->bss_tree.rb_node; 582 struct rb_node *parent = NULL; 583 struct cfg80211_internal_bss *tbss; 584 int cmp; 585 586 while (*p) { 587 parent = *p; 588 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn); 589 590 cmp = cmp_bss(&bss->pub, &tbss->pub); 591 592 if (WARN_ON(!cmp)) { 593 /* will sort of leak this BSS */ 594 return; 595 } 596 597 if (cmp < 0) 598 p = &(*p)->rb_left; 599 else 600 p = &(*p)->rb_right; 601 } 602 603 rb_link_node(&bss->rbn, parent, p); 604 rb_insert_color(&bss->rbn, &dev->bss_tree); 605 } 606 607 static struct cfg80211_internal_bss * 608 rb_find_bss(struct cfg80211_registered_device *dev, 609 struct cfg80211_internal_bss *res) 610 { 611 struct rb_node *n = dev->bss_tree.rb_node; 612 struct cfg80211_internal_bss *bss; 613 int r; 614 615 while (n) { 616 bss = rb_entry(n, struct cfg80211_internal_bss, rbn); 617 r = cmp_bss(&res->pub, &bss->pub); 618 619 if (r == 0) 620 return bss; 621 else if (r < 0) 622 n = n->rb_left; 623 else 624 n = n->rb_right; 625 } 626 627 return NULL; 628 } 629 630 static struct cfg80211_internal_bss * 631 rb_find_hidden_bss(struct cfg80211_registered_device *dev, 632 struct cfg80211_internal_bss *res) 633 { 634 struct rb_node *n = dev->bss_tree.rb_node; 635 struct cfg80211_internal_bss *bss; 636 int r; 637 638 while (n) { 639 bss = rb_entry(n, struct cfg80211_internal_bss, rbn); 640 r = cmp_hidden_bss(&res->pub, &bss->pub); 641 642 if (r == 0) 643 return bss; 644 else if (r < 0) 645 n = n->rb_left; 646 else 647 n = n->rb_right; 648 } 649 650 return NULL; 651 } 652 653 static void 654 copy_hidden_ies(struct cfg80211_internal_bss *res, 655 struct cfg80211_internal_bss *hidden) 656 { 657 const struct cfg80211_bss_ies *ies; 658 659 if (rcu_access_pointer(res->pub.beacon_ies)) 660 return; 661 662 ies = rcu_access_pointer(hidden->pub.beacon_ies); 663 if (WARN_ON(!ies)) 664 return; 665 666 ies = kmemdup(ies, sizeof(*ies) + ies->len, GFP_ATOMIC); 667 if (unlikely(!ies)) 668 return; 669 rcu_assign_pointer(res->pub.beacon_ies, ies); 670 } 671 672 static struct cfg80211_internal_bss * 673 cfg80211_bss_update(struct cfg80211_registered_device *dev, 674 struct cfg80211_internal_bss *tmp) 675 { 676 struct cfg80211_internal_bss *found = NULL; 677 678 if (WARN_ON(!tmp->pub.channel)) 679 return NULL; 680 681 tmp->ts = jiffies; 682 683 spin_lock_bh(&dev->bss_lock); 684 685 if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) { 686 spin_unlock_bh(&dev->bss_lock); 687 return NULL; 688 } 689 690 found = rb_find_bss(dev, tmp); 691 692 if (found) { 693 found->pub.beacon_interval = tmp->pub.beacon_interval; 694 found->pub.tsf = tmp->pub.tsf; 695 found->pub.signal = tmp->pub.signal; 696 found->pub.capability = tmp->pub.capability; 697 found->ts = tmp->ts; 698 699 /* Update IEs */ 700 if (rcu_access_pointer(tmp->pub.proberesp_ies)) { 701 const struct cfg80211_bss_ies *old; 702 703 old = rcu_access_pointer(found->pub.proberesp_ies); 704 705 rcu_assign_pointer(found->pub.proberesp_ies, 706 tmp->pub.proberesp_ies); 707 /* Override possible earlier Beacon frame IEs */ 708 rcu_assign_pointer(found->pub.ies, 709 tmp->pub.proberesp_ies); 710 if (old) 711 kfree_rcu((struct cfg80211_bss_ies *)old, 712 rcu_head); 713 } else if (rcu_access_pointer(tmp->pub.beacon_ies)) { 714 const struct cfg80211_bss_ies *old, *ies; 715 716 old = rcu_access_pointer(found->pub.beacon_ies); 717 ies = rcu_access_pointer(found->pub.ies); 718 719 rcu_assign_pointer(found->pub.beacon_ies, 720 tmp->pub.beacon_ies); 721 722 /* Override IEs if they were from a beacon before */ 723 if (old == ies) 724 rcu_assign_pointer(found->pub.ies, 725 tmp->pub.beacon_ies); 726 727 if (old) 728 kfree_rcu((struct cfg80211_bss_ies *)old, 729 rcu_head); 730 } 731 } else { 732 struct cfg80211_internal_bss *new; 733 struct cfg80211_internal_bss *hidden; 734 struct cfg80211_bss_ies *ies; 735 736 /* First check if the beacon is a probe response from 737 * a hidden bss. If so, copy beacon ies (with nullified 738 * ssid) into the probe response bss entry (with real ssid). 739 * It is required basically for PSM implementation 740 * (probe responses do not contain tim ie) */ 741 742 /* TODO: The code is not trying to update existing probe 743 * response bss entries when beacon ies are 744 * getting changed. */ 745 hidden = rb_find_hidden_bss(dev, tmp); 746 if (hidden) 747 copy_hidden_ies(tmp, hidden); 748 749 /* 750 * create a copy -- the "res" variable that is passed in 751 * is allocated on the stack since it's not needed in the 752 * more common case of an update 753 */ 754 new = kzalloc(sizeof(*new) + dev->wiphy.bss_priv_size, 755 GFP_ATOMIC); 756 if (!new) { 757 ies = (void *)rcu_dereference(tmp->pub.beacon_ies); 758 if (ies) 759 kfree_rcu(ies, rcu_head); 760 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies); 761 if (ies) 762 kfree_rcu(ies, rcu_head); 763 spin_unlock_bh(&dev->bss_lock); 764 return NULL; 765 } 766 memcpy(new, tmp, sizeof(*new)); 767 kref_init(&new->ref); 768 list_add_tail(&new->list, &dev->bss_list); 769 rb_insert_bss(dev, new); 770 found = new; 771 } 772 773 dev->bss_generation++; 774 spin_unlock_bh(&dev->bss_lock); 775 776 kref_get(&found->ref); 777 return found; 778 } 779 780 static struct ieee80211_channel * 781 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, 782 struct ieee80211_channel *channel) 783 { 784 const u8 *tmp; 785 u32 freq; 786 int channel_number = -1; 787 788 tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen); 789 if (tmp && tmp[1] == 1) { 790 channel_number = tmp[2]; 791 } else { 792 tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen); 793 if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) { 794 struct ieee80211_ht_operation *htop = (void *)(tmp + 2); 795 796 channel_number = htop->primary_chan; 797 } 798 } 799 800 if (channel_number < 0) 801 return channel; 802 803 freq = ieee80211_channel_to_frequency(channel_number, channel->band); 804 channel = ieee80211_get_channel(wiphy, freq); 805 if (!channel) 806 return NULL; 807 if (channel->flags & IEEE80211_CHAN_DISABLED) 808 return NULL; 809 return channel; 810 } 811 812 struct cfg80211_bss* 813 cfg80211_inform_bss(struct wiphy *wiphy, 814 struct ieee80211_channel *channel, 815 const u8 *bssid, u64 tsf, u16 capability, 816 u16 beacon_interval, const u8 *ie, size_t ielen, 817 s32 signal, gfp_t gfp) 818 { 819 struct cfg80211_bss_ies *ies; 820 struct cfg80211_internal_bss tmp = {}, *res; 821 822 if (WARN_ON(!wiphy)) 823 return NULL; 824 825 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && 826 (signal < 0 || signal > 100))) 827 return NULL; 828 829 channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel); 830 if (!channel) 831 return NULL; 832 833 memcpy(tmp.pub.bssid, bssid, ETH_ALEN); 834 tmp.pub.channel = channel; 835 tmp.pub.signal = signal; 836 tmp.pub.tsf = tsf; 837 tmp.pub.beacon_interval = beacon_interval; 838 tmp.pub.capability = capability; 839 /* 840 * Since we do not know here whether the IEs are from a Beacon or Probe 841 * Response frame, we need to pick one of the options and only use it 842 * with the driver that does not provide the full Beacon/Probe Response 843 * frame. Use Beacon frame pointer to avoid indicating that this should 844 * override the iies pointer should we have received an earlier 845 * indication of Probe Response data. 846 * 847 * The initial buffer for the IEs is allocated with the BSS entry and 848 * is located after the private area. 849 */ 850 ies = kmalloc(sizeof(*ies) + ielen, gfp); 851 if (!ies) 852 return NULL; 853 ies->len = ielen; 854 memcpy(ies->data, ie, ielen); 855 856 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 857 rcu_assign_pointer(tmp.pub.ies, ies); 858 859 res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp); 860 if (!res) 861 return NULL; 862 863 if (res->pub.capability & WLAN_CAPABILITY_ESS) 864 regulatory_hint_found_beacon(wiphy, channel, gfp); 865 866 trace_cfg80211_return_bss(&res->pub); 867 /* cfg80211_bss_update gives us a referenced result */ 868 return &res->pub; 869 } 870 EXPORT_SYMBOL(cfg80211_inform_bss); 871 872 struct cfg80211_bss * 873 cfg80211_inform_bss_frame(struct wiphy *wiphy, 874 struct ieee80211_channel *channel, 875 struct ieee80211_mgmt *mgmt, size_t len, 876 s32 signal, gfp_t gfp) 877 { 878 struct cfg80211_internal_bss tmp = {}, *res; 879 struct cfg80211_bss_ies *ies; 880 size_t ielen = len - offsetof(struct ieee80211_mgmt, 881 u.probe_resp.variable); 882 883 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != 884 offsetof(struct ieee80211_mgmt, u.beacon.variable)); 885 886 trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); 887 888 if (WARN_ON(!mgmt)) 889 return NULL; 890 891 if (WARN_ON(!wiphy)) 892 return NULL; 893 894 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && 895 (signal < 0 || signal > 100))) 896 return NULL; 897 898 if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable))) 899 return NULL; 900 901 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable, 902 ielen, channel); 903 if (!channel) 904 return NULL; 905 906 ies = kmalloc(sizeof(*ies) + ielen, gfp); 907 if (!ies) 908 return NULL; 909 ies->len = ielen; 910 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); 911 912 if (ieee80211_is_probe_resp(mgmt->frame_control)) 913 rcu_assign_pointer(tmp.pub.proberesp_ies, ies); 914 else 915 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 916 rcu_assign_pointer(tmp.pub.ies, ies); 917 918 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); 919 tmp.pub.channel = channel; 920 tmp.pub.signal = signal; 921 tmp.pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); 922 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 923 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 924 925 res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp); 926 if (!res) 927 return NULL; 928 929 if (res->pub.capability & WLAN_CAPABILITY_ESS) 930 regulatory_hint_found_beacon(wiphy, channel, gfp); 931 932 trace_cfg80211_return_bss(&res->pub); 933 /* cfg80211_bss_update gives us a referenced result */ 934 return &res->pub; 935 } 936 EXPORT_SYMBOL(cfg80211_inform_bss_frame); 937 938 void cfg80211_ref_bss(struct cfg80211_bss *pub) 939 { 940 struct cfg80211_internal_bss *bss; 941 942 if (!pub) 943 return; 944 945 bss = container_of(pub, struct cfg80211_internal_bss, pub); 946 kref_get(&bss->ref); 947 } 948 EXPORT_SYMBOL(cfg80211_ref_bss); 949 950 void cfg80211_put_bss(struct cfg80211_bss *pub) 951 { 952 struct cfg80211_internal_bss *bss; 953 954 if (!pub) 955 return; 956 957 bss = container_of(pub, struct cfg80211_internal_bss, pub); 958 kref_put(&bss->ref, bss_release); 959 } 960 EXPORT_SYMBOL(cfg80211_put_bss); 961 962 void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) 963 { 964 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); 965 struct cfg80211_internal_bss *bss; 966 967 if (WARN_ON(!pub)) 968 return; 969 970 bss = container_of(pub, struct cfg80211_internal_bss, pub); 971 972 spin_lock_bh(&dev->bss_lock); 973 if (!list_empty(&bss->list)) { 974 __cfg80211_unlink_bss(dev, bss); 975 dev->bss_generation++; 976 } 977 spin_unlock_bh(&dev->bss_lock); 978 } 979 EXPORT_SYMBOL(cfg80211_unlink_bss); 980 981 #ifdef CONFIG_CFG80211_WEXT 982 int cfg80211_wext_siwscan(struct net_device *dev, 983 struct iw_request_info *info, 984 union iwreq_data *wrqu, char *extra) 985 { 986 struct cfg80211_registered_device *rdev; 987 struct wiphy *wiphy; 988 struct iw_scan_req *wreq = NULL; 989 struct cfg80211_scan_request *creq = NULL; 990 int i, err, n_channels = 0; 991 enum ieee80211_band band; 992 993 if (!netif_running(dev)) 994 return -ENETDOWN; 995 996 if (wrqu->data.length == sizeof(struct iw_scan_req)) 997 wreq = (struct iw_scan_req *)extra; 998 999 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex); 1000 1001 if (IS_ERR(rdev)) 1002 return PTR_ERR(rdev); 1003 1004 if (rdev->scan_req) { 1005 err = -EBUSY; 1006 goto out; 1007 } 1008 1009 wiphy = &rdev->wiphy; 1010 1011 /* Determine number of channels, needed to allocate creq */ 1012 if (wreq && wreq->num_channels) 1013 n_channels = wreq->num_channels; 1014 else { 1015 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 1016 if (wiphy->bands[band]) 1017 n_channels += wiphy->bands[band]->n_channels; 1018 } 1019 1020 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + 1021 n_channels * sizeof(void *), 1022 GFP_ATOMIC); 1023 if (!creq) { 1024 err = -ENOMEM; 1025 goto out; 1026 } 1027 1028 creq->wiphy = wiphy; 1029 creq->wdev = dev->ieee80211_ptr; 1030 /* SSIDs come after channels */ 1031 creq->ssids = (void *)&creq->channels[n_channels]; 1032 creq->n_channels = n_channels; 1033 creq->n_ssids = 1; 1034 creq->scan_start = jiffies; 1035 1036 /* translate "Scan on frequencies" request */ 1037 i = 0; 1038 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1039 int j; 1040 1041 if (!wiphy->bands[band]) 1042 continue; 1043 1044 for (j = 0; j < wiphy->bands[band]->n_channels; j++) { 1045 /* ignore disabled channels */ 1046 if (wiphy->bands[band]->channels[j].flags & 1047 IEEE80211_CHAN_DISABLED) 1048 continue; 1049 1050 /* If we have a wireless request structure and the 1051 * wireless request specifies frequencies, then search 1052 * for the matching hardware channel. 1053 */ 1054 if (wreq && wreq->num_channels) { 1055 int k; 1056 int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; 1057 for (k = 0; k < wreq->num_channels; k++) { 1058 int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]); 1059 if (wext_freq == wiphy_freq) 1060 goto wext_freq_found; 1061 } 1062 goto wext_freq_not_found; 1063 } 1064 1065 wext_freq_found: 1066 creq->channels[i] = &wiphy->bands[band]->channels[j]; 1067 i++; 1068 wext_freq_not_found: ; 1069 } 1070 } 1071 /* No channels found? */ 1072 if (!i) { 1073 err = -EINVAL; 1074 goto out; 1075 } 1076 1077 /* Set real number of channels specified in creq->channels[] */ 1078 creq->n_channels = i; 1079 1080 /* translate "Scan for SSID" request */ 1081 if (wreq) { 1082 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 1083 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) { 1084 err = -EINVAL; 1085 goto out; 1086 } 1087 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); 1088 creq->ssids[0].ssid_len = wreq->essid_len; 1089 } 1090 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) 1091 creq->n_ssids = 0; 1092 } 1093 1094 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 1095 if (wiphy->bands[i]) 1096 creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; 1097 1098 rdev->scan_req = creq; 1099 err = rdev_scan(rdev, creq); 1100 if (err) { 1101 rdev->scan_req = NULL; 1102 /* creq will be freed below */ 1103 } else { 1104 nl80211_send_scan_start(rdev, dev->ieee80211_ptr); 1105 /* creq now owned by driver */ 1106 creq = NULL; 1107 dev_hold(dev); 1108 } 1109 out: 1110 kfree(creq); 1111 cfg80211_unlock_rdev(rdev); 1112 return err; 1113 } 1114 EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); 1115 1116 static void ieee80211_scan_add_ies(struct iw_request_info *info, 1117 const struct cfg80211_bss_ies *ies, 1118 char **current_ev, char *end_buf) 1119 { 1120 const u8 *pos, *end, *next; 1121 struct iw_event iwe; 1122 1123 if (!ies) 1124 return; 1125 1126 /* 1127 * If needed, fragment the IEs buffer (at IE boundaries) into short 1128 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages. 1129 */ 1130 pos = ies->data; 1131 end = pos + ies->len; 1132 1133 while (end - pos > IW_GENERIC_IE_MAX) { 1134 next = pos + 2 + pos[1]; 1135 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX) 1136 next = next + 2 + next[1]; 1137 1138 memset(&iwe, 0, sizeof(iwe)); 1139 iwe.cmd = IWEVGENIE; 1140 iwe.u.data.length = next - pos; 1141 *current_ev = iwe_stream_add_point(info, *current_ev, 1142 end_buf, &iwe, 1143 (void *)pos); 1144 1145 pos = next; 1146 } 1147 1148 if (end > pos) { 1149 memset(&iwe, 0, sizeof(iwe)); 1150 iwe.cmd = IWEVGENIE; 1151 iwe.u.data.length = end - pos; 1152 *current_ev = iwe_stream_add_point(info, *current_ev, 1153 end_buf, &iwe, 1154 (void *)pos); 1155 } 1156 } 1157 1158 static inline unsigned int elapsed_jiffies_msecs(unsigned long start) 1159 { 1160 unsigned long end = jiffies; 1161 1162 if (end >= start) 1163 return jiffies_to_msecs(end - start); 1164 1165 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); 1166 } 1167 1168 static char * 1169 ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, 1170 struct cfg80211_internal_bss *bss, char *current_ev, 1171 char *end_buf) 1172 { 1173 const struct cfg80211_bss_ies *ies; 1174 struct iw_event iwe; 1175 const u8 *ie; 1176 u8 *buf, *cfg, *p; 1177 int rem, i, sig; 1178 bool ismesh = false; 1179 1180 memset(&iwe, 0, sizeof(iwe)); 1181 iwe.cmd = SIOCGIWAP; 1182 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1183 memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN); 1184 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, 1185 IW_EV_ADDR_LEN); 1186 1187 memset(&iwe, 0, sizeof(iwe)); 1188 iwe.cmd = SIOCGIWFREQ; 1189 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq); 1190 iwe.u.freq.e = 0; 1191 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, 1192 IW_EV_FREQ_LEN); 1193 1194 memset(&iwe, 0, sizeof(iwe)); 1195 iwe.cmd = SIOCGIWFREQ; 1196 iwe.u.freq.m = bss->pub.channel->center_freq; 1197 iwe.u.freq.e = 6; 1198 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, 1199 IW_EV_FREQ_LEN); 1200 1201 if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) { 1202 memset(&iwe, 0, sizeof(iwe)); 1203 iwe.cmd = IWEVQUAL; 1204 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED | 1205 IW_QUAL_NOISE_INVALID | 1206 IW_QUAL_QUAL_UPDATED; 1207 switch (wiphy->signal_type) { 1208 case CFG80211_SIGNAL_TYPE_MBM: 1209 sig = bss->pub.signal / 100; 1210 iwe.u.qual.level = sig; 1211 iwe.u.qual.updated |= IW_QUAL_DBM; 1212 if (sig < -110) /* rather bad */ 1213 sig = -110; 1214 else if (sig > -40) /* perfect */ 1215 sig = -40; 1216 /* will give a range of 0 .. 70 */ 1217 iwe.u.qual.qual = sig + 110; 1218 break; 1219 case CFG80211_SIGNAL_TYPE_UNSPEC: 1220 iwe.u.qual.level = bss->pub.signal; 1221 /* will give range 0 .. 100 */ 1222 iwe.u.qual.qual = bss->pub.signal; 1223 break; 1224 default: 1225 /* not reached */ 1226 break; 1227 } 1228 current_ev = iwe_stream_add_event(info, current_ev, end_buf, 1229 &iwe, IW_EV_QUAL_LEN); 1230 } 1231 1232 memset(&iwe, 0, sizeof(iwe)); 1233 iwe.cmd = SIOCGIWENCODE; 1234 if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY) 1235 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 1236 else 1237 iwe.u.data.flags = IW_ENCODE_DISABLED; 1238 iwe.u.data.length = 0; 1239 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1240 &iwe, ""); 1241 1242 rcu_read_lock(); 1243 ies = rcu_dereference(bss->pub.ies); 1244 if (ies) { 1245 rem = ies->len; 1246 ie = ies->data; 1247 } else { 1248 rem = 0; 1249 ie = NULL; 1250 } 1251 1252 while (ies && rem >= 2) { 1253 /* invalid data */ 1254 if (ie[1] > rem - 2) 1255 break; 1256 1257 switch (ie[0]) { 1258 case WLAN_EID_SSID: 1259 memset(&iwe, 0, sizeof(iwe)); 1260 iwe.cmd = SIOCGIWESSID; 1261 iwe.u.data.length = ie[1]; 1262 iwe.u.data.flags = 1; 1263 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1264 &iwe, (u8 *)ie + 2); 1265 break; 1266 case WLAN_EID_MESH_ID: 1267 memset(&iwe, 0, sizeof(iwe)); 1268 iwe.cmd = SIOCGIWESSID; 1269 iwe.u.data.length = ie[1]; 1270 iwe.u.data.flags = 1; 1271 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1272 &iwe, (u8 *)ie + 2); 1273 break; 1274 case WLAN_EID_MESH_CONFIG: 1275 ismesh = true; 1276 if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) 1277 break; 1278 buf = kmalloc(50, GFP_ATOMIC); 1279 if (!buf) 1280 break; 1281 cfg = (u8 *)ie + 2; 1282 memset(&iwe, 0, sizeof(iwe)); 1283 iwe.cmd = IWEVCUSTOM; 1284 sprintf(buf, "Mesh Network Path Selection Protocol ID: " 1285 "0x%02X", cfg[0]); 1286 iwe.u.data.length = strlen(buf); 1287 current_ev = iwe_stream_add_point(info, current_ev, 1288 end_buf, 1289 &iwe, buf); 1290 sprintf(buf, "Path Selection Metric ID: 0x%02X", 1291 cfg[1]); 1292 iwe.u.data.length = strlen(buf); 1293 current_ev = iwe_stream_add_point(info, current_ev, 1294 end_buf, 1295 &iwe, buf); 1296 sprintf(buf, "Congestion Control Mode ID: 0x%02X", 1297 cfg[2]); 1298 iwe.u.data.length = strlen(buf); 1299 current_ev = iwe_stream_add_point(info, current_ev, 1300 end_buf, 1301 &iwe, buf); 1302 sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]); 1303 iwe.u.data.length = strlen(buf); 1304 current_ev = iwe_stream_add_point(info, current_ev, 1305 end_buf, 1306 &iwe, buf); 1307 sprintf(buf, "Authentication ID: 0x%02X", cfg[4]); 1308 iwe.u.data.length = strlen(buf); 1309 current_ev = iwe_stream_add_point(info, current_ev, 1310 end_buf, 1311 &iwe, buf); 1312 sprintf(buf, "Formation Info: 0x%02X", cfg[5]); 1313 iwe.u.data.length = strlen(buf); 1314 current_ev = iwe_stream_add_point(info, current_ev, 1315 end_buf, 1316 &iwe, buf); 1317 sprintf(buf, "Capabilities: 0x%02X", cfg[6]); 1318 iwe.u.data.length = strlen(buf); 1319 current_ev = iwe_stream_add_point(info, current_ev, 1320 end_buf, 1321 &iwe, buf); 1322 kfree(buf); 1323 break; 1324 case WLAN_EID_SUPP_RATES: 1325 case WLAN_EID_EXT_SUPP_RATES: 1326 /* display all supported rates in readable format */ 1327 p = current_ev + iwe_stream_lcp_len(info); 1328 1329 memset(&iwe, 0, sizeof(iwe)); 1330 iwe.cmd = SIOCGIWRATE; 1331 /* Those two flags are ignored... */ 1332 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 1333 1334 for (i = 0; i < ie[1]; i++) { 1335 iwe.u.bitrate.value = 1336 ((ie[i + 2] & 0x7f) * 500000); 1337 p = iwe_stream_add_value(info, current_ev, p, 1338 end_buf, &iwe, IW_EV_PARAM_LEN); 1339 } 1340 current_ev = p; 1341 break; 1342 } 1343 rem -= ie[1] + 2; 1344 ie += ie[1] + 2; 1345 } 1346 1347 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) || 1348 ismesh) { 1349 memset(&iwe, 0, sizeof(iwe)); 1350 iwe.cmd = SIOCGIWMODE; 1351 if (ismesh) 1352 iwe.u.mode = IW_MODE_MESH; 1353 else if (bss->pub.capability & WLAN_CAPABILITY_ESS) 1354 iwe.u.mode = IW_MODE_MASTER; 1355 else 1356 iwe.u.mode = IW_MODE_ADHOC; 1357 current_ev = iwe_stream_add_event(info, current_ev, end_buf, 1358 &iwe, IW_EV_UINT_LEN); 1359 } 1360 1361 buf = kmalloc(30, GFP_ATOMIC); 1362 if (buf) { 1363 memset(&iwe, 0, sizeof(iwe)); 1364 iwe.cmd = IWEVCUSTOM; 1365 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf)); 1366 iwe.u.data.length = strlen(buf); 1367 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1368 &iwe, buf); 1369 memset(&iwe, 0, sizeof(iwe)); 1370 iwe.cmd = IWEVCUSTOM; 1371 sprintf(buf, " Last beacon: %ums ago", 1372 elapsed_jiffies_msecs(bss->ts)); 1373 iwe.u.data.length = strlen(buf); 1374 current_ev = iwe_stream_add_point(info, current_ev, 1375 end_buf, &iwe, buf); 1376 kfree(buf); 1377 } 1378 1379 ieee80211_scan_add_ies(info, ies, ¤t_ev, end_buf); 1380 rcu_read_unlock(); 1381 1382 return current_ev; 1383 } 1384 1385 1386 static int ieee80211_scan_results(struct cfg80211_registered_device *dev, 1387 struct iw_request_info *info, 1388 char *buf, size_t len) 1389 { 1390 char *current_ev = buf; 1391 char *end_buf = buf + len; 1392 struct cfg80211_internal_bss *bss; 1393 1394 spin_lock_bh(&dev->bss_lock); 1395 cfg80211_bss_expire(dev); 1396 1397 list_for_each_entry(bss, &dev->bss_list, list) { 1398 if (buf + len - current_ev <= IW_EV_ADDR_LEN) { 1399 spin_unlock_bh(&dev->bss_lock); 1400 return -E2BIG; 1401 } 1402 current_ev = ieee80211_bss(&dev->wiphy, info, bss, 1403 current_ev, end_buf); 1404 } 1405 spin_unlock_bh(&dev->bss_lock); 1406 return current_ev - buf; 1407 } 1408 1409 1410 int cfg80211_wext_giwscan(struct net_device *dev, 1411 struct iw_request_info *info, 1412 struct iw_point *data, char *extra) 1413 { 1414 struct cfg80211_registered_device *rdev; 1415 int res; 1416 1417 if (!netif_running(dev)) 1418 return -ENETDOWN; 1419 1420 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex); 1421 1422 if (IS_ERR(rdev)) 1423 return PTR_ERR(rdev); 1424 1425 if (rdev->scan_req) { 1426 res = -EAGAIN; 1427 goto out; 1428 } 1429 1430 res = ieee80211_scan_results(rdev, info, extra, data->length); 1431 data->length = 0; 1432 if (res >= 0) { 1433 data->length = res; 1434 res = 0; 1435 } 1436 1437 out: 1438 cfg80211_unlock_rdev(rdev); 1439 return res; 1440 } 1441 EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); 1442 #endif 1443