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