1 /* 2 * Some IBSS support code for cfg80211. 3 * 4 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 5 */ 6 7 #include <linux/etherdevice.h> 8 #include <linux/if_arp.h> 9 #include <linux/slab.h> 10 #include <linux/export.h> 11 #include <net/cfg80211.h> 12 #include "wext-compat.h" 13 #include "nl80211.h" 14 #include "rdev-ops.h" 15 16 17 void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, 18 struct ieee80211_channel *channel) 19 { 20 struct wireless_dev *wdev = dev->ieee80211_ptr; 21 struct cfg80211_bss *bss; 22 #ifdef CONFIG_CFG80211_WEXT 23 union iwreq_data wrqu; 24 #endif 25 26 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 27 return; 28 29 if (!wdev->ssid_len) 30 return; 31 32 bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, 33 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); 34 35 if (WARN_ON(!bss)) 36 return; 37 38 if (wdev->current_bss) { 39 cfg80211_unhold_bss(wdev->current_bss); 40 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); 41 } 42 43 cfg80211_hold_bss(bss_from_pub(bss)); 44 wdev->current_bss = bss_from_pub(bss); 45 46 cfg80211_upload_connect_keys(wdev); 47 48 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, 49 GFP_KERNEL); 50 #ifdef CONFIG_CFG80211_WEXT 51 memset(&wrqu, 0, sizeof(wrqu)); 52 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); 53 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 54 #endif 55 } 56 57 void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, 58 struct ieee80211_channel *channel, gfp_t gfp) 59 { 60 struct wireless_dev *wdev = dev->ieee80211_ptr; 61 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 62 struct cfg80211_event *ev; 63 unsigned long flags; 64 65 trace_cfg80211_ibss_joined(dev, bssid, channel); 66 67 if (WARN_ON(!channel)) 68 return; 69 70 ev = kzalloc(sizeof(*ev), gfp); 71 if (!ev) 72 return; 73 74 ev->type = EVENT_IBSS_JOINED; 75 memcpy(ev->ij.bssid, bssid, ETH_ALEN); 76 ev->ij.channel = channel; 77 78 spin_lock_irqsave(&wdev->event_lock, flags); 79 list_add_tail(&ev->list, &wdev->event_list); 80 spin_unlock_irqrestore(&wdev->event_lock, flags); 81 queue_work(cfg80211_wq, &rdev->event_work); 82 } 83 EXPORT_SYMBOL(cfg80211_ibss_joined); 84 85 static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 86 struct net_device *dev, 87 struct cfg80211_ibss_params *params, 88 struct cfg80211_cached_keys *connkeys) 89 { 90 struct wireless_dev *wdev = dev->ieee80211_ptr; 91 struct ieee80211_channel *check_chan; 92 u8 radar_detect_width = 0; 93 int err; 94 95 ASSERT_WDEV_LOCK(wdev); 96 97 if (wdev->ssid_len) 98 return -EALREADY; 99 100 if (!params->basic_rates) { 101 /* 102 * If no rates were explicitly configured, 103 * use the mandatory rate set for 11b or 104 * 11a for maximum compatibility. 105 */ 106 struct ieee80211_supported_band *sband = 107 rdev->wiphy.bands[params->chandef.chan->band]; 108 int j; 109 u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ? 110 IEEE80211_RATE_MANDATORY_A : 111 IEEE80211_RATE_MANDATORY_B; 112 113 for (j = 0; j < sband->n_bitrates; j++) { 114 if (sband->bitrates[j].flags & flag) 115 params->basic_rates |= BIT(j); 116 } 117 } 118 119 if (WARN_ON(wdev->connect_keys)) 120 kfree(wdev->connect_keys); 121 wdev->connect_keys = connkeys; 122 123 wdev->ibss_fixed = params->channel_fixed; 124 wdev->ibss_dfs_possible = params->userspace_handles_dfs; 125 wdev->chandef = params->chandef; 126 #ifdef CONFIG_CFG80211_WEXT 127 wdev->wext.ibss.chandef = params->chandef; 128 #endif 129 check_chan = params->chandef.chan; 130 if (params->userspace_handles_dfs) { 131 /* Check for radar even if the current channel is not 132 * a radar channel - it might decide to change to DFS 133 * channel later. 134 */ 135 radar_detect_width = BIT(params->chandef.width); 136 } 137 138 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 139 check_chan, 140 (params->channel_fixed && 141 !radar_detect_width) 142 ? CHAN_MODE_SHARED 143 : CHAN_MODE_EXCLUSIVE, 144 radar_detect_width); 145 146 if (err) { 147 wdev->connect_keys = NULL; 148 return err; 149 } 150 151 err = rdev_join_ibss(rdev, dev, params); 152 if (err) { 153 wdev->connect_keys = NULL; 154 return err; 155 } 156 157 memcpy(wdev->ssid, params->ssid, params->ssid_len); 158 wdev->ssid_len = params->ssid_len; 159 160 return 0; 161 } 162 163 int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 164 struct net_device *dev, 165 struct cfg80211_ibss_params *params, 166 struct cfg80211_cached_keys *connkeys) 167 { 168 struct wireless_dev *wdev = dev->ieee80211_ptr; 169 int err; 170 171 ASSERT_RTNL(); 172 173 wdev_lock(wdev); 174 err = __cfg80211_join_ibss(rdev, dev, params, connkeys); 175 wdev_unlock(wdev); 176 177 return err; 178 } 179 180 static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) 181 { 182 struct wireless_dev *wdev = dev->ieee80211_ptr; 183 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 184 int i; 185 186 ASSERT_WDEV_LOCK(wdev); 187 188 kfree(wdev->connect_keys); 189 wdev->connect_keys = NULL; 190 191 rdev_set_qos_map(rdev, dev, NULL); 192 193 /* 194 * Delete all the keys ... pairwise keys can't really 195 * exist any more anyway, but default keys might. 196 */ 197 if (rdev->ops->del_key) 198 for (i = 0; i < 6; i++) 199 rdev_del_key(rdev, dev, i, false, NULL); 200 201 if (wdev->current_bss) { 202 cfg80211_unhold_bss(wdev->current_bss); 203 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); 204 } 205 206 wdev->current_bss = NULL; 207 wdev->ssid_len = 0; 208 memset(&wdev->chandef, 0, sizeof(wdev->chandef)); 209 #ifdef CONFIG_CFG80211_WEXT 210 if (!nowext) 211 wdev->wext.ibss.ssid_len = 0; 212 #endif 213 } 214 215 void cfg80211_clear_ibss(struct net_device *dev, bool nowext) 216 { 217 struct wireless_dev *wdev = dev->ieee80211_ptr; 218 219 wdev_lock(wdev); 220 __cfg80211_clear_ibss(dev, nowext); 221 wdev_unlock(wdev); 222 } 223 224 int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 225 struct net_device *dev, bool nowext) 226 { 227 struct wireless_dev *wdev = dev->ieee80211_ptr; 228 int err; 229 230 ASSERT_WDEV_LOCK(wdev); 231 232 if (!wdev->ssid_len) 233 return -ENOLINK; 234 235 err = rdev_leave_ibss(rdev, dev); 236 237 if (err) 238 return err; 239 240 __cfg80211_clear_ibss(dev, nowext); 241 242 return 0; 243 } 244 245 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 246 struct net_device *dev, bool nowext) 247 { 248 struct wireless_dev *wdev = dev->ieee80211_ptr; 249 int err; 250 251 wdev_lock(wdev); 252 err = __cfg80211_leave_ibss(rdev, dev, nowext); 253 wdev_unlock(wdev); 254 255 return err; 256 } 257 258 #ifdef CONFIG_CFG80211_WEXT 259 int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, 260 struct wireless_dev *wdev) 261 { 262 struct cfg80211_cached_keys *ck = NULL; 263 enum ieee80211_band band; 264 int i, err; 265 266 ASSERT_WDEV_LOCK(wdev); 267 268 if (!wdev->wext.ibss.beacon_interval) 269 wdev->wext.ibss.beacon_interval = 100; 270 271 /* try to find an IBSS channel if none requested ... */ 272 if (!wdev->wext.ibss.chandef.chan) { 273 struct ieee80211_channel *new_chan = NULL; 274 275 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 276 struct ieee80211_supported_band *sband; 277 struct ieee80211_channel *chan; 278 279 sband = rdev->wiphy.bands[band]; 280 if (!sband) 281 continue; 282 283 for (i = 0; i < sband->n_channels; i++) { 284 chan = &sband->channels[i]; 285 if (chan->flags & IEEE80211_CHAN_NO_IR) 286 continue; 287 if (chan->flags & IEEE80211_CHAN_DISABLED) 288 continue; 289 new_chan = chan; 290 break; 291 } 292 293 if (new_chan) 294 break; 295 } 296 297 if (!new_chan) 298 return -EINVAL; 299 300 cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan, 301 NL80211_CHAN_NO_HT); 302 } 303 304 /* don't join -- SSID is not there */ 305 if (!wdev->wext.ibss.ssid_len) 306 return 0; 307 308 if (!netif_running(wdev->netdev)) 309 return 0; 310 311 if (wdev->wext.keys) { 312 wdev->wext.keys->def = wdev->wext.default_key; 313 wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; 314 } 315 316 wdev->wext.ibss.privacy = wdev->wext.default_key != -1; 317 318 if (wdev->wext.keys) { 319 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); 320 if (!ck) 321 return -ENOMEM; 322 for (i = 0; i < 6; i++) 323 ck->params[i].key = ck->data[i]; 324 } 325 err = __cfg80211_join_ibss(rdev, wdev->netdev, 326 &wdev->wext.ibss, ck); 327 if (err) 328 kfree(ck); 329 330 return err; 331 } 332 333 int cfg80211_ibss_wext_siwfreq(struct net_device *dev, 334 struct iw_request_info *info, 335 struct iw_freq *wextfreq, char *extra) 336 { 337 struct wireless_dev *wdev = dev->ieee80211_ptr; 338 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 339 struct ieee80211_channel *chan = NULL; 340 int err, freq; 341 342 /* call only for ibss! */ 343 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 344 return -EINVAL; 345 346 if (!rdev->ops->join_ibss) 347 return -EOPNOTSUPP; 348 349 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); 350 if (freq < 0) 351 return freq; 352 353 if (freq) { 354 chan = ieee80211_get_channel(wdev->wiphy, freq); 355 if (!chan) 356 return -EINVAL; 357 if (chan->flags & IEEE80211_CHAN_NO_IR || 358 chan->flags & IEEE80211_CHAN_DISABLED) 359 return -EINVAL; 360 } 361 362 if (wdev->wext.ibss.chandef.chan == chan) 363 return 0; 364 365 wdev_lock(wdev); 366 err = 0; 367 if (wdev->ssid_len) 368 err = __cfg80211_leave_ibss(rdev, dev, true); 369 wdev_unlock(wdev); 370 371 if (err) 372 return err; 373 374 if (chan) { 375 cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan, 376 NL80211_CHAN_NO_HT); 377 wdev->wext.ibss.channel_fixed = true; 378 } else { 379 /* cfg80211_ibss_wext_join will pick one if needed */ 380 wdev->wext.ibss.channel_fixed = false; 381 } 382 383 wdev_lock(wdev); 384 err = cfg80211_ibss_wext_join(rdev, wdev); 385 wdev_unlock(wdev); 386 387 return err; 388 } 389 390 int cfg80211_ibss_wext_giwfreq(struct net_device *dev, 391 struct iw_request_info *info, 392 struct iw_freq *freq, char *extra) 393 { 394 struct wireless_dev *wdev = dev->ieee80211_ptr; 395 struct ieee80211_channel *chan = NULL; 396 397 /* call only for ibss! */ 398 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 399 return -EINVAL; 400 401 wdev_lock(wdev); 402 if (wdev->current_bss) 403 chan = wdev->current_bss->pub.channel; 404 else if (wdev->wext.ibss.chandef.chan) 405 chan = wdev->wext.ibss.chandef.chan; 406 wdev_unlock(wdev); 407 408 if (chan) { 409 freq->m = chan->center_freq; 410 freq->e = 6; 411 return 0; 412 } 413 414 /* no channel if not joining */ 415 return -EINVAL; 416 } 417 418 int cfg80211_ibss_wext_siwessid(struct net_device *dev, 419 struct iw_request_info *info, 420 struct iw_point *data, char *ssid) 421 { 422 struct wireless_dev *wdev = dev->ieee80211_ptr; 423 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 424 size_t len = data->length; 425 int err; 426 427 /* call only for ibss! */ 428 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 429 return -EINVAL; 430 431 if (!rdev->ops->join_ibss) 432 return -EOPNOTSUPP; 433 434 wdev_lock(wdev); 435 err = 0; 436 if (wdev->ssid_len) 437 err = __cfg80211_leave_ibss(rdev, dev, true); 438 wdev_unlock(wdev); 439 440 if (err) 441 return err; 442 443 /* iwconfig uses nul termination in SSID.. */ 444 if (len > 0 && ssid[len - 1] == '\0') 445 len--; 446 447 wdev->wext.ibss.ssid = wdev->ssid; 448 memcpy(wdev->wext.ibss.ssid, ssid, len); 449 wdev->wext.ibss.ssid_len = len; 450 451 wdev_lock(wdev); 452 err = cfg80211_ibss_wext_join(rdev, wdev); 453 wdev_unlock(wdev); 454 455 return err; 456 } 457 458 int cfg80211_ibss_wext_giwessid(struct net_device *dev, 459 struct iw_request_info *info, 460 struct iw_point *data, char *ssid) 461 { 462 struct wireless_dev *wdev = dev->ieee80211_ptr; 463 464 /* call only for ibss! */ 465 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 466 return -EINVAL; 467 468 data->flags = 0; 469 470 wdev_lock(wdev); 471 if (wdev->ssid_len) { 472 data->flags = 1; 473 data->length = wdev->ssid_len; 474 memcpy(ssid, wdev->ssid, data->length); 475 } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) { 476 data->flags = 1; 477 data->length = wdev->wext.ibss.ssid_len; 478 memcpy(ssid, wdev->wext.ibss.ssid, data->length); 479 } 480 wdev_unlock(wdev); 481 482 return 0; 483 } 484 485 int cfg80211_ibss_wext_siwap(struct net_device *dev, 486 struct iw_request_info *info, 487 struct sockaddr *ap_addr, char *extra) 488 { 489 struct wireless_dev *wdev = dev->ieee80211_ptr; 490 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 491 u8 *bssid = ap_addr->sa_data; 492 int err; 493 494 /* call only for ibss! */ 495 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 496 return -EINVAL; 497 498 if (!rdev->ops->join_ibss) 499 return -EOPNOTSUPP; 500 501 if (ap_addr->sa_family != ARPHRD_ETHER) 502 return -EINVAL; 503 504 /* automatic mode */ 505 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) 506 bssid = NULL; 507 508 /* both automatic */ 509 if (!bssid && !wdev->wext.ibss.bssid) 510 return 0; 511 512 /* fixed already - and no change */ 513 if (wdev->wext.ibss.bssid && bssid && 514 ether_addr_equal(bssid, wdev->wext.ibss.bssid)) 515 return 0; 516 517 wdev_lock(wdev); 518 err = 0; 519 if (wdev->ssid_len) 520 err = __cfg80211_leave_ibss(rdev, dev, true); 521 wdev_unlock(wdev); 522 523 if (err) 524 return err; 525 526 if (bssid) { 527 memcpy(wdev->wext.bssid, bssid, ETH_ALEN); 528 wdev->wext.ibss.bssid = wdev->wext.bssid; 529 } else 530 wdev->wext.ibss.bssid = NULL; 531 532 wdev_lock(wdev); 533 err = cfg80211_ibss_wext_join(rdev, wdev); 534 wdev_unlock(wdev); 535 536 return err; 537 } 538 539 int cfg80211_ibss_wext_giwap(struct net_device *dev, 540 struct iw_request_info *info, 541 struct sockaddr *ap_addr, char *extra) 542 { 543 struct wireless_dev *wdev = dev->ieee80211_ptr; 544 545 /* call only for ibss! */ 546 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 547 return -EINVAL; 548 549 ap_addr->sa_family = ARPHRD_ETHER; 550 551 wdev_lock(wdev); 552 if (wdev->current_bss) 553 memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); 554 else if (wdev->wext.ibss.bssid) 555 memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN); 556 else 557 memset(ap_addr->sa_data, 0, ETH_ALEN); 558 559 wdev_unlock(wdev); 560 561 return 0; 562 } 563 #endif 564