0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/etherdevice.h>
0010 #include <linux/if_arp.h>
0011 #include <linux/slab.h>
0012 #include <linux/export.h>
0013 #include <net/cfg80211.h>
0014 #include "wext-compat.h"
0015 #include "nl80211.h"
0016 #include "rdev-ops.h"
0017
0018
0019 void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
0020 struct ieee80211_channel *channel)
0021 {
0022 struct wireless_dev *wdev = dev->ieee80211_ptr;
0023 struct cfg80211_bss *bss;
0024 #ifdef CONFIG_CFG80211_WEXT
0025 union iwreq_data wrqu;
0026 #endif
0027
0028 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0029 return;
0030
0031 if (!wdev->u.ibss.ssid_len)
0032 return;
0033
0034 bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
0035 IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY);
0036
0037 if (WARN_ON(!bss))
0038 return;
0039
0040 if (wdev->u.ibss.current_bss) {
0041 cfg80211_unhold_bss(wdev->u.ibss.current_bss);
0042 cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub);
0043 }
0044
0045 cfg80211_hold_bss(bss_from_pub(bss));
0046 wdev->u.ibss.current_bss = bss_from_pub(bss);
0047
0048 if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))
0049 cfg80211_upload_connect_keys(wdev);
0050
0051 nl80211_send_ibss_bssid(wiphy_to_rdev(wdev->wiphy), dev, bssid,
0052 GFP_KERNEL);
0053 #ifdef CONFIG_CFG80211_WEXT
0054 memset(&wrqu, 0, sizeof(wrqu));
0055 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
0056 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
0057 #endif
0058 }
0059
0060 void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
0061 struct ieee80211_channel *channel, gfp_t gfp)
0062 {
0063 struct wireless_dev *wdev = dev->ieee80211_ptr;
0064 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0065 struct cfg80211_event *ev;
0066 unsigned long flags;
0067
0068 trace_cfg80211_ibss_joined(dev, bssid, channel);
0069
0070 if (WARN_ON(!channel))
0071 return;
0072
0073 ev = kzalloc(sizeof(*ev), gfp);
0074 if (!ev)
0075 return;
0076
0077 ev->type = EVENT_IBSS_JOINED;
0078 memcpy(ev->ij.bssid, bssid, ETH_ALEN);
0079 ev->ij.channel = channel;
0080
0081 spin_lock_irqsave(&wdev->event_lock, flags);
0082 list_add_tail(&ev->list, &wdev->event_list);
0083 spin_unlock_irqrestore(&wdev->event_lock, flags);
0084 queue_work(cfg80211_wq, &rdev->event_work);
0085 }
0086 EXPORT_SYMBOL(cfg80211_ibss_joined);
0087
0088 int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
0089 struct net_device *dev,
0090 struct cfg80211_ibss_params *params,
0091 struct cfg80211_cached_keys *connkeys)
0092 {
0093 struct wireless_dev *wdev = dev->ieee80211_ptr;
0094 int err;
0095
0096 lockdep_assert_held(&rdev->wiphy.mtx);
0097 ASSERT_WDEV_LOCK(wdev);
0098
0099 if (wdev->u.ibss.ssid_len)
0100 return -EALREADY;
0101
0102 if (!params->basic_rates) {
0103
0104
0105
0106
0107
0108 struct ieee80211_supported_band *sband;
0109 enum nl80211_band band;
0110 u32 flag;
0111 int j;
0112
0113 band = params->chandef.chan->band;
0114 if (band == NL80211_BAND_5GHZ ||
0115 band == NL80211_BAND_6GHZ)
0116 flag = IEEE80211_RATE_MANDATORY_A;
0117 else
0118 flag = IEEE80211_RATE_MANDATORY_B;
0119
0120 sband = rdev->wiphy.bands[band];
0121 for (j = 0; j < sband->n_bitrates; j++) {
0122 if (sband->bitrates[j].flags & flag)
0123 params->basic_rates |= BIT(j);
0124 }
0125 }
0126
0127 if (WARN_ON(connkeys && connkeys->def < 0))
0128 return -EINVAL;
0129
0130 if (WARN_ON(wdev->connect_keys))
0131 kfree_sensitive(wdev->connect_keys);
0132 wdev->connect_keys = connkeys;
0133
0134 wdev->u.ibss.chandef = params->chandef;
0135 if (connkeys) {
0136 params->wep_keys = connkeys->params;
0137 params->wep_tx_key = connkeys->def;
0138 }
0139
0140 #ifdef CONFIG_CFG80211_WEXT
0141 wdev->wext.ibss.chandef = params->chandef;
0142 #endif
0143 err = rdev_join_ibss(rdev, dev, params);
0144 if (err) {
0145 wdev->connect_keys = NULL;
0146 return err;
0147 }
0148
0149 memcpy(wdev->u.ibss.ssid, params->ssid, params->ssid_len);
0150 wdev->u.ibss.ssid_len = params->ssid_len;
0151
0152 return 0;
0153 }
0154
0155 static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
0156 {
0157 struct wireless_dev *wdev = dev->ieee80211_ptr;
0158 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0159 int i;
0160
0161 ASSERT_WDEV_LOCK(wdev);
0162
0163 kfree_sensitive(wdev->connect_keys);
0164 wdev->connect_keys = NULL;
0165
0166 rdev_set_qos_map(rdev, dev, NULL);
0167
0168
0169
0170
0171
0172 if (rdev->ops->del_key)
0173 for (i = 0; i < 6; i++)
0174 rdev_del_key(rdev, dev, i, false, NULL);
0175
0176 if (wdev->u.ibss.current_bss) {
0177 cfg80211_unhold_bss(wdev->u.ibss.current_bss);
0178 cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub);
0179 }
0180
0181 wdev->u.ibss.current_bss = NULL;
0182 wdev->u.ibss.ssid_len = 0;
0183 memset(&wdev->u.ibss.chandef, 0, sizeof(wdev->u.ibss.chandef));
0184 #ifdef CONFIG_CFG80211_WEXT
0185 if (!nowext)
0186 wdev->wext.ibss.ssid_len = 0;
0187 #endif
0188 cfg80211_sched_dfs_chan_update(rdev);
0189 }
0190
0191 void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
0192 {
0193 struct wireless_dev *wdev = dev->ieee80211_ptr;
0194
0195 wdev_lock(wdev);
0196 __cfg80211_clear_ibss(dev, nowext);
0197 wdev_unlock(wdev);
0198 }
0199
0200 int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
0201 struct net_device *dev, bool nowext)
0202 {
0203 struct wireless_dev *wdev = dev->ieee80211_ptr;
0204 int err;
0205
0206 ASSERT_WDEV_LOCK(wdev);
0207
0208 if (!wdev->u.ibss.ssid_len)
0209 return -ENOLINK;
0210
0211 err = rdev_leave_ibss(rdev, dev);
0212
0213 if (err)
0214 return err;
0215
0216 wdev->conn_owner_nlportid = 0;
0217 __cfg80211_clear_ibss(dev, nowext);
0218
0219 return 0;
0220 }
0221
0222 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
0223 struct net_device *dev, bool nowext)
0224 {
0225 struct wireless_dev *wdev = dev->ieee80211_ptr;
0226 int err;
0227
0228 wdev_lock(wdev);
0229 err = __cfg80211_leave_ibss(rdev, dev, nowext);
0230 wdev_unlock(wdev);
0231
0232 return err;
0233 }
0234
0235 #ifdef CONFIG_CFG80211_WEXT
0236 int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
0237 struct wireless_dev *wdev)
0238 {
0239 struct cfg80211_cached_keys *ck = NULL;
0240 enum nl80211_band band;
0241 int i, err;
0242
0243 ASSERT_WDEV_LOCK(wdev);
0244
0245 if (!wdev->wext.ibss.beacon_interval)
0246 wdev->wext.ibss.beacon_interval = 100;
0247
0248
0249 if (!wdev->wext.ibss.chandef.chan) {
0250 struct ieee80211_channel *new_chan = NULL;
0251
0252 for (band = 0; band < NUM_NL80211_BANDS; band++) {
0253 struct ieee80211_supported_band *sband;
0254 struct ieee80211_channel *chan;
0255
0256 sband = rdev->wiphy.bands[band];
0257 if (!sband)
0258 continue;
0259
0260 for (i = 0; i < sband->n_channels; i++) {
0261 chan = &sband->channels[i];
0262 if (chan->flags & IEEE80211_CHAN_NO_IR)
0263 continue;
0264 if (chan->flags & IEEE80211_CHAN_DISABLED)
0265 continue;
0266 new_chan = chan;
0267 break;
0268 }
0269
0270 if (new_chan)
0271 break;
0272 }
0273
0274 if (!new_chan)
0275 return -EINVAL;
0276
0277 cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan,
0278 NL80211_CHAN_NO_HT);
0279 }
0280
0281
0282 if (!wdev->wext.ibss.ssid_len)
0283 return 0;
0284
0285 if (!netif_running(wdev->netdev))
0286 return 0;
0287
0288 if (wdev->wext.keys)
0289 wdev->wext.keys->def = wdev->wext.default_key;
0290
0291 wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
0292
0293 if (wdev->wext.keys && wdev->wext.keys->def != -1) {
0294 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
0295 if (!ck)
0296 return -ENOMEM;
0297 for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
0298 ck->params[i].key = ck->data[i];
0299 }
0300 err = __cfg80211_join_ibss(rdev, wdev->netdev,
0301 &wdev->wext.ibss, ck);
0302 if (err)
0303 kfree(ck);
0304
0305 return err;
0306 }
0307
0308 int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
0309 struct iw_request_info *info,
0310 struct iw_freq *wextfreq, char *extra)
0311 {
0312 struct wireless_dev *wdev = dev->ieee80211_ptr;
0313 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0314 struct ieee80211_channel *chan = NULL;
0315 int err, freq;
0316
0317
0318 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0319 return -EINVAL;
0320
0321 if (!rdev->ops->join_ibss)
0322 return -EOPNOTSUPP;
0323
0324 freq = cfg80211_wext_freq(wextfreq);
0325 if (freq < 0)
0326 return freq;
0327
0328 if (freq) {
0329 chan = ieee80211_get_channel(wdev->wiphy, freq);
0330 if (!chan)
0331 return -EINVAL;
0332 if (chan->flags & IEEE80211_CHAN_NO_IR ||
0333 chan->flags & IEEE80211_CHAN_DISABLED)
0334 return -EINVAL;
0335 }
0336
0337 if (wdev->wext.ibss.chandef.chan == chan)
0338 return 0;
0339
0340 wdev_lock(wdev);
0341 err = 0;
0342 if (wdev->u.ibss.ssid_len)
0343 err = __cfg80211_leave_ibss(rdev, dev, true);
0344 wdev_unlock(wdev);
0345
0346 if (err)
0347 return err;
0348
0349 if (chan) {
0350 cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan,
0351 NL80211_CHAN_NO_HT);
0352 wdev->wext.ibss.channel_fixed = true;
0353 } else {
0354
0355 wdev->wext.ibss.channel_fixed = false;
0356 }
0357
0358 wdev_lock(wdev);
0359 err = cfg80211_ibss_wext_join(rdev, wdev);
0360 wdev_unlock(wdev);
0361
0362 return err;
0363 }
0364
0365 int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
0366 struct iw_request_info *info,
0367 struct iw_freq *freq, char *extra)
0368 {
0369 struct wireless_dev *wdev = dev->ieee80211_ptr;
0370 struct ieee80211_channel *chan = NULL;
0371
0372
0373 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0374 return -EINVAL;
0375
0376 wdev_lock(wdev);
0377 if (wdev->u.ibss.current_bss)
0378 chan = wdev->u.ibss.current_bss->pub.channel;
0379 else if (wdev->wext.ibss.chandef.chan)
0380 chan = wdev->wext.ibss.chandef.chan;
0381 wdev_unlock(wdev);
0382
0383 if (chan) {
0384 freq->m = chan->center_freq;
0385 freq->e = 6;
0386 return 0;
0387 }
0388
0389
0390 return -EINVAL;
0391 }
0392
0393 int cfg80211_ibss_wext_siwessid(struct net_device *dev,
0394 struct iw_request_info *info,
0395 struct iw_point *data, char *ssid)
0396 {
0397 struct wireless_dev *wdev = dev->ieee80211_ptr;
0398 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0399 size_t len = data->length;
0400 int err;
0401
0402
0403 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0404 return -EINVAL;
0405
0406 if (!rdev->ops->join_ibss)
0407 return -EOPNOTSUPP;
0408
0409 wdev_lock(wdev);
0410 err = 0;
0411 if (wdev->u.ibss.ssid_len)
0412 err = __cfg80211_leave_ibss(rdev, dev, true);
0413 wdev_unlock(wdev);
0414
0415 if (err)
0416 return err;
0417
0418
0419 if (len > 0 && ssid[len - 1] == '\0')
0420 len--;
0421
0422 memcpy(wdev->u.ibss.ssid, ssid, len);
0423 wdev->wext.ibss.ssid = wdev->u.ibss.ssid;
0424 wdev->wext.ibss.ssid_len = len;
0425
0426 wdev_lock(wdev);
0427 err = cfg80211_ibss_wext_join(rdev, wdev);
0428 wdev_unlock(wdev);
0429
0430 return err;
0431 }
0432
0433 int cfg80211_ibss_wext_giwessid(struct net_device *dev,
0434 struct iw_request_info *info,
0435 struct iw_point *data, char *ssid)
0436 {
0437 struct wireless_dev *wdev = dev->ieee80211_ptr;
0438
0439
0440 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0441 return -EINVAL;
0442
0443 data->flags = 0;
0444
0445 wdev_lock(wdev);
0446 if (wdev->u.ibss.ssid_len) {
0447 data->flags = 1;
0448 data->length = wdev->u.ibss.ssid_len;
0449 memcpy(ssid, wdev->u.ibss.ssid, data->length);
0450 } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) {
0451 data->flags = 1;
0452 data->length = wdev->wext.ibss.ssid_len;
0453 memcpy(ssid, wdev->wext.ibss.ssid, data->length);
0454 }
0455 wdev_unlock(wdev);
0456
0457 return 0;
0458 }
0459
0460 int cfg80211_ibss_wext_siwap(struct net_device *dev,
0461 struct iw_request_info *info,
0462 struct sockaddr *ap_addr, char *extra)
0463 {
0464 struct wireless_dev *wdev = dev->ieee80211_ptr;
0465 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0466 u8 *bssid = ap_addr->sa_data;
0467 int err;
0468
0469
0470 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0471 return -EINVAL;
0472
0473 if (!rdev->ops->join_ibss)
0474 return -EOPNOTSUPP;
0475
0476 if (ap_addr->sa_family != ARPHRD_ETHER)
0477 return -EINVAL;
0478
0479
0480 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
0481 bssid = NULL;
0482
0483 if (bssid && !is_valid_ether_addr(bssid))
0484 return -EINVAL;
0485
0486
0487 if (!bssid && !wdev->wext.ibss.bssid)
0488 return 0;
0489
0490
0491 if (wdev->wext.ibss.bssid && bssid &&
0492 ether_addr_equal(bssid, wdev->wext.ibss.bssid))
0493 return 0;
0494
0495 wdev_lock(wdev);
0496 err = 0;
0497 if (wdev->u.ibss.ssid_len)
0498 err = __cfg80211_leave_ibss(rdev, dev, true);
0499 wdev_unlock(wdev);
0500
0501 if (err)
0502 return err;
0503
0504 if (bssid) {
0505 memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
0506 wdev->wext.ibss.bssid = wdev->wext.bssid;
0507 } else
0508 wdev->wext.ibss.bssid = NULL;
0509
0510 wdev_lock(wdev);
0511 err = cfg80211_ibss_wext_join(rdev, wdev);
0512 wdev_unlock(wdev);
0513
0514 return err;
0515 }
0516
0517 int cfg80211_ibss_wext_giwap(struct net_device *dev,
0518 struct iw_request_info *info,
0519 struct sockaddr *ap_addr, char *extra)
0520 {
0521 struct wireless_dev *wdev = dev->ieee80211_ptr;
0522
0523
0524 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
0525 return -EINVAL;
0526
0527 ap_addr->sa_family = ARPHRD_ETHER;
0528
0529 wdev_lock(wdev);
0530 if (wdev->u.ibss.current_bss)
0531 memcpy(ap_addr->sa_data, wdev->u.ibss.current_bss->pub.bssid,
0532 ETH_ALEN);
0533 else if (wdev->wext.ibss.bssid)
0534 memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
0535 else
0536 eth_zero_addr(ap_addr->sa_data);
0537
0538 wdev_unlock(wdev);
0539
0540 return 0;
0541 }
0542 #endif