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