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