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 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 1094 if (wiphy->bands[band]) 1095 n_channels += wiphy->bands[band]->n_channels; 1096 } 1097 1098 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + 1099 n_channels * sizeof(void *), 1100 GFP_ATOMIC); 1101 if (!creq) { 1102 err = -ENOMEM; 1103 goto out; 1104 } 1105 1106 creq->wiphy = wiphy; 1107 creq->wdev = dev->ieee80211_ptr; 1108 /* SSIDs come after channels */ 1109 creq->ssids = (void *)&creq->channels[n_channels]; 1110 creq->n_channels = n_channels; 1111 creq->n_ssids = 1; 1112 creq->scan_start = jiffies; 1113 1114 /* translate "Scan on frequencies" request */ 1115 i = 0; 1116 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1117 int j; 1118 1119 if (!wiphy->bands[band]) 1120 continue; 1121 1122 for (j = 0; j < wiphy->bands[band]->n_channels; j++) { 1123 /* ignore disabled channels */ 1124 if (wiphy->bands[band]->channels[j].flags & 1125 IEEE80211_CHAN_DISABLED) 1126 continue; 1127 1128 /* If we have a wireless request structure and the 1129 * wireless request specifies frequencies, then search 1130 * for the matching hardware channel. 1131 */ 1132 if (wreq && wreq->num_channels) { 1133 int k; 1134 int wiphy_freq = wiphy->bands[band]->channels[j].center_freq; 1135 for (k = 0; k < wreq->num_channels; k++) { 1136 int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]); 1137 if (wext_freq == wiphy_freq) 1138 goto wext_freq_found; 1139 } 1140 goto wext_freq_not_found; 1141 } 1142 1143 wext_freq_found: 1144 creq->channels[i] = &wiphy->bands[band]->channels[j]; 1145 i++; 1146 wext_freq_not_found: ; 1147 } 1148 } 1149 /* No channels found? */ 1150 if (!i) { 1151 err = -EINVAL; 1152 goto out; 1153 } 1154 1155 /* Set real number of channels specified in creq->channels[] */ 1156 creq->n_channels = i; 1157 1158 /* translate "Scan for SSID" request */ 1159 if (wreq) { 1160 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 1161 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) { 1162 err = -EINVAL; 1163 goto out; 1164 } 1165 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); 1166 creq->ssids[0].ssid_len = wreq->essid_len; 1167 } 1168 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) 1169 creq->n_ssids = 0; 1170 } 1171 1172 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 1173 if (wiphy->bands[i]) 1174 creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; 1175 1176 rdev->scan_req = creq; 1177 err = rdev_scan(rdev, creq); 1178 if (err) { 1179 rdev->scan_req = NULL; 1180 /* creq will be freed below */ 1181 } else { 1182 nl80211_send_scan_start(rdev, dev->ieee80211_ptr); 1183 /* creq now owned by driver */ 1184 creq = NULL; 1185 dev_hold(dev); 1186 } 1187 out: 1188 kfree(creq); 1189 return err; 1190 } 1191 EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); 1192 1193 static void ieee80211_scan_add_ies(struct iw_request_info *info, 1194 const struct cfg80211_bss_ies *ies, 1195 char **current_ev, char *end_buf) 1196 { 1197 const u8 *pos, *end, *next; 1198 struct iw_event iwe; 1199 1200 if (!ies) 1201 return; 1202 1203 /* 1204 * If needed, fragment the IEs buffer (at IE boundaries) into short 1205 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages. 1206 */ 1207 pos = ies->data; 1208 end = pos + ies->len; 1209 1210 while (end - pos > IW_GENERIC_IE_MAX) { 1211 next = pos + 2 + pos[1]; 1212 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX) 1213 next = next + 2 + next[1]; 1214 1215 memset(&iwe, 0, sizeof(iwe)); 1216 iwe.cmd = IWEVGENIE; 1217 iwe.u.data.length = next - pos; 1218 *current_ev = iwe_stream_add_point(info, *current_ev, 1219 end_buf, &iwe, 1220 (void *)pos); 1221 1222 pos = next; 1223 } 1224 1225 if (end > pos) { 1226 memset(&iwe, 0, sizeof(iwe)); 1227 iwe.cmd = IWEVGENIE; 1228 iwe.u.data.length = end - pos; 1229 *current_ev = iwe_stream_add_point(info, *current_ev, 1230 end_buf, &iwe, 1231 (void *)pos); 1232 } 1233 } 1234 1235 static char * 1236 ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, 1237 struct cfg80211_internal_bss *bss, char *current_ev, 1238 char *end_buf) 1239 { 1240 const struct cfg80211_bss_ies *ies; 1241 struct iw_event iwe; 1242 const u8 *ie; 1243 u8 *buf, *cfg, *p; 1244 int rem, i, sig; 1245 bool ismesh = false; 1246 1247 memset(&iwe, 0, sizeof(iwe)); 1248 iwe.cmd = SIOCGIWAP; 1249 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1250 memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN); 1251 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, 1252 IW_EV_ADDR_LEN); 1253 1254 memset(&iwe, 0, sizeof(iwe)); 1255 iwe.cmd = SIOCGIWFREQ; 1256 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq); 1257 iwe.u.freq.e = 0; 1258 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, 1259 IW_EV_FREQ_LEN); 1260 1261 memset(&iwe, 0, sizeof(iwe)); 1262 iwe.cmd = SIOCGIWFREQ; 1263 iwe.u.freq.m = bss->pub.channel->center_freq; 1264 iwe.u.freq.e = 6; 1265 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, 1266 IW_EV_FREQ_LEN); 1267 1268 if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) { 1269 memset(&iwe, 0, sizeof(iwe)); 1270 iwe.cmd = IWEVQUAL; 1271 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED | 1272 IW_QUAL_NOISE_INVALID | 1273 IW_QUAL_QUAL_UPDATED; 1274 switch (wiphy->signal_type) { 1275 case CFG80211_SIGNAL_TYPE_MBM: 1276 sig = bss->pub.signal / 100; 1277 iwe.u.qual.level = sig; 1278 iwe.u.qual.updated |= IW_QUAL_DBM; 1279 if (sig < -110) /* rather bad */ 1280 sig = -110; 1281 else if (sig > -40) /* perfect */ 1282 sig = -40; 1283 /* will give a range of 0 .. 70 */ 1284 iwe.u.qual.qual = sig + 110; 1285 break; 1286 case CFG80211_SIGNAL_TYPE_UNSPEC: 1287 iwe.u.qual.level = bss->pub.signal; 1288 /* will give range 0 .. 100 */ 1289 iwe.u.qual.qual = bss->pub.signal; 1290 break; 1291 default: 1292 /* not reached */ 1293 break; 1294 } 1295 current_ev = iwe_stream_add_event(info, current_ev, end_buf, 1296 &iwe, IW_EV_QUAL_LEN); 1297 } 1298 1299 memset(&iwe, 0, sizeof(iwe)); 1300 iwe.cmd = SIOCGIWENCODE; 1301 if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY) 1302 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 1303 else 1304 iwe.u.data.flags = IW_ENCODE_DISABLED; 1305 iwe.u.data.length = 0; 1306 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1307 &iwe, ""); 1308 1309 rcu_read_lock(); 1310 ies = rcu_dereference(bss->pub.ies); 1311 rem = ies->len; 1312 ie = ies->data; 1313 1314 while (rem >= 2) { 1315 /* invalid data */ 1316 if (ie[1] > rem - 2) 1317 break; 1318 1319 switch (ie[0]) { 1320 case WLAN_EID_SSID: 1321 memset(&iwe, 0, sizeof(iwe)); 1322 iwe.cmd = SIOCGIWESSID; 1323 iwe.u.data.length = ie[1]; 1324 iwe.u.data.flags = 1; 1325 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1326 &iwe, (u8 *)ie + 2); 1327 break; 1328 case WLAN_EID_MESH_ID: 1329 memset(&iwe, 0, sizeof(iwe)); 1330 iwe.cmd = SIOCGIWESSID; 1331 iwe.u.data.length = ie[1]; 1332 iwe.u.data.flags = 1; 1333 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1334 &iwe, (u8 *)ie + 2); 1335 break; 1336 case WLAN_EID_MESH_CONFIG: 1337 ismesh = true; 1338 if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) 1339 break; 1340 buf = kmalloc(50, GFP_ATOMIC); 1341 if (!buf) 1342 break; 1343 cfg = (u8 *)ie + 2; 1344 memset(&iwe, 0, sizeof(iwe)); 1345 iwe.cmd = IWEVCUSTOM; 1346 sprintf(buf, "Mesh Network Path Selection Protocol ID: " 1347 "0x%02X", cfg[0]); 1348 iwe.u.data.length = strlen(buf); 1349 current_ev = iwe_stream_add_point(info, current_ev, 1350 end_buf, 1351 &iwe, buf); 1352 sprintf(buf, "Path Selection Metric ID: 0x%02X", 1353 cfg[1]); 1354 iwe.u.data.length = strlen(buf); 1355 current_ev = iwe_stream_add_point(info, current_ev, 1356 end_buf, 1357 &iwe, buf); 1358 sprintf(buf, "Congestion Control Mode ID: 0x%02X", 1359 cfg[2]); 1360 iwe.u.data.length = strlen(buf); 1361 current_ev = iwe_stream_add_point(info, current_ev, 1362 end_buf, 1363 &iwe, buf); 1364 sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]); 1365 iwe.u.data.length = strlen(buf); 1366 current_ev = iwe_stream_add_point(info, current_ev, 1367 end_buf, 1368 &iwe, buf); 1369 sprintf(buf, "Authentication ID: 0x%02X", cfg[4]); 1370 iwe.u.data.length = strlen(buf); 1371 current_ev = iwe_stream_add_point(info, current_ev, 1372 end_buf, 1373 &iwe, buf); 1374 sprintf(buf, "Formation Info: 0x%02X", cfg[5]); 1375 iwe.u.data.length = strlen(buf); 1376 current_ev = iwe_stream_add_point(info, current_ev, 1377 end_buf, 1378 &iwe, buf); 1379 sprintf(buf, "Capabilities: 0x%02X", cfg[6]); 1380 iwe.u.data.length = strlen(buf); 1381 current_ev = iwe_stream_add_point(info, current_ev, 1382 end_buf, 1383 &iwe, buf); 1384 kfree(buf); 1385 break; 1386 case WLAN_EID_SUPP_RATES: 1387 case WLAN_EID_EXT_SUPP_RATES: 1388 /* display all supported rates in readable format */ 1389 p = current_ev + iwe_stream_lcp_len(info); 1390 1391 memset(&iwe, 0, sizeof(iwe)); 1392 iwe.cmd = SIOCGIWRATE; 1393 /* Those two flags are ignored... */ 1394 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 1395 1396 for (i = 0; i < ie[1]; i++) { 1397 iwe.u.bitrate.value = 1398 ((ie[i + 2] & 0x7f) * 500000); 1399 p = iwe_stream_add_value(info, current_ev, p, 1400 end_buf, &iwe, IW_EV_PARAM_LEN); 1401 } 1402 current_ev = p; 1403 break; 1404 } 1405 rem -= ie[1] + 2; 1406 ie += ie[1] + 2; 1407 } 1408 1409 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) || 1410 ismesh) { 1411 memset(&iwe, 0, sizeof(iwe)); 1412 iwe.cmd = SIOCGIWMODE; 1413 if (ismesh) 1414 iwe.u.mode = IW_MODE_MESH; 1415 else if (bss->pub.capability & WLAN_CAPABILITY_ESS) 1416 iwe.u.mode = IW_MODE_MASTER; 1417 else 1418 iwe.u.mode = IW_MODE_ADHOC; 1419 current_ev = iwe_stream_add_event(info, current_ev, end_buf, 1420 &iwe, IW_EV_UINT_LEN); 1421 } 1422 1423 buf = kmalloc(31, GFP_ATOMIC); 1424 if (buf) { 1425 memset(&iwe, 0, sizeof(iwe)); 1426 iwe.cmd = IWEVCUSTOM; 1427 sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf)); 1428 iwe.u.data.length = strlen(buf); 1429 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1430 &iwe, buf); 1431 memset(&iwe, 0, sizeof(iwe)); 1432 iwe.cmd = IWEVCUSTOM; 1433 sprintf(buf, " Last beacon: %ums ago", 1434 elapsed_jiffies_msecs(bss->ts)); 1435 iwe.u.data.length = strlen(buf); 1436 current_ev = iwe_stream_add_point(info, current_ev, 1437 end_buf, &iwe, buf); 1438 kfree(buf); 1439 } 1440 1441 ieee80211_scan_add_ies(info, ies, ¤t_ev, end_buf); 1442 rcu_read_unlock(); 1443 1444 return current_ev; 1445 } 1446 1447 1448 static int ieee80211_scan_results(struct cfg80211_registered_device *dev, 1449 struct iw_request_info *info, 1450 char *buf, size_t len) 1451 { 1452 char *current_ev = buf; 1453 char *end_buf = buf + len; 1454 struct cfg80211_internal_bss *bss; 1455 1456 spin_lock_bh(&dev->bss_lock); 1457 cfg80211_bss_expire(dev); 1458 1459 list_for_each_entry(bss, &dev->bss_list, list) { 1460 if (buf + len - current_ev <= IW_EV_ADDR_LEN) { 1461 spin_unlock_bh(&dev->bss_lock); 1462 return -E2BIG; 1463 } 1464 current_ev = ieee80211_bss(&dev->wiphy, info, bss, 1465 current_ev, end_buf); 1466 } 1467 spin_unlock_bh(&dev->bss_lock); 1468 return current_ev - buf; 1469 } 1470 1471 1472 int cfg80211_wext_giwscan(struct net_device *dev, 1473 struct iw_request_info *info, 1474 struct iw_point *data, char *extra) 1475 { 1476 struct cfg80211_registered_device *rdev; 1477 int res; 1478 1479 if (!netif_running(dev)) 1480 return -ENETDOWN; 1481 1482 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex); 1483 1484 if (IS_ERR(rdev)) 1485 return PTR_ERR(rdev); 1486 1487 if (rdev->scan_req) 1488 return -EAGAIN; 1489 1490 res = ieee80211_scan_results(rdev, info, extra, data->length); 1491 data->length = 0; 1492 if (res >= 0) { 1493 data->length = res; 1494 res = 0; 1495 } 1496 1497 return res; 1498 } 1499 EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); 1500 #endif 1501