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