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