aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-02-15 06:44:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:51:42 -0500
commit469002983fc90c2ff0959e2b03335c0fe2e4d5a9 (patch)
treefdcf78dcdaeadba897abd86d39d0275e236803b3 /net/mac80211/ibss.c
parent96f5e66e8a79810e2982cdcfa28e554f3d97da21 (diff)
mac80211: split IBSS/managed code
This patch splits out the ibss code and data from managed (station) mode. The reason to do this is to better separate the state machines, and have the code be contained better so it gets easier to determine what exactly a given change will affect, that in turn makes it easier to understand. This is quite some churn, especially because I split sdata->u.sta into sdata->u.mgd and sdata->u.ibss, but I think it's easier to maintain that way. I've also shuffled around some code -- null function sending is only applicable to managed interfaces so put that into that file, some other functions are needed from various places so put them into util, and also rearranged the prototypes in ieee80211_i.h accordingly. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c888
1 files changed, 888 insertions, 0 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
new file mode 100644
index 000000000000..1bbfc7029879
--- /dev/null
+++ b/net/mac80211/ibss.c
@@ -0,0 +1,888 @@
1/*
2 * IBSS mode implementation
3 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
4 * Copyright 2004, Instant802 Networks, Inc.
5 * Copyright 2005, Devicescape Software, Inc.
6 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
7 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
8 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/delay.h>
16#include <linux/if_ether.h>
17#include <linux/skbuff.h>
18#include <linux/if_arp.h>
19#include <linux/etherdevice.h>
20#include <linux/rtnetlink.h>
21#include <net/mac80211.h>
22#include <asm/unaligned.h>
23
24#include "ieee80211_i.h"
25#include "rate.h"
26
27#define IEEE80211_SCAN_INTERVAL (2 * HZ)
28#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ)
29#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ)
30
31#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ)
32#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ)
33
34#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
35
36
37static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
38 struct ieee80211_mgmt *mgmt,
39 size_t len)
40{
41 u16 auth_alg, auth_transaction, status_code;
42
43 if (len < 24 + 6)
44 return;
45
46 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
47 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
48 status_code = le16_to_cpu(mgmt->u.auth.status_code);
49
50 /*
51 * IEEE 802.11 standard does not require authentication in IBSS
52 * networks and most implementations do not seem to use it.
53 * However, try to reply to authentication attempts if someone
54 * has actually implemented this.
55 */
56 if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
57 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
58 sdata->u.ibss.bssid, 0);
59}
60
61static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
62 const u8 *bssid, const int beacon_int,
63 const int freq,
64 const size_t supp_rates_len,
65 const u8 *supp_rates,
66 const u16 capability)
67{
68 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
69 struct ieee80211_local *local = sdata->local;
70 int res = 0, rates, i, j;
71 struct sk_buff *skb;
72 struct ieee80211_mgmt *mgmt;
73 u8 *pos;
74 struct ieee80211_supported_band *sband;
75 union iwreq_data wrqu;
76
77 if (local->ops->reset_tsf) {
78 /* Reset own TSF to allow time synchronization work. */
79 local->ops->reset_tsf(local_to_hw(local));
80 }
81
82 if ((ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) &&
83 memcmp(ifibss->bssid, bssid, ETH_ALEN) == 0)
84 return res;
85
86 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
87 if (!skb) {
88 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
89 "response\n", sdata->dev->name);
90 return -ENOMEM;
91 }
92
93 if (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) {
94 /* Remove possible STA entries from other IBSS networks. */
95 sta_info_flush_delayed(sdata);
96 }
97
98 memcpy(ifibss->bssid, bssid, ETH_ALEN);
99 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
100 if (res)
101 return res;
102
103 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
104
105 sdata->drop_unencrypted = capability &
106 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
107
108 res = ieee80211_set_freq(sdata, freq);
109
110 if (res)
111 return res;
112
113 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
114
115 /* Build IBSS probe response */
116
117 skb_reserve(skb, local->hw.extra_tx_headroom);
118
119 mgmt = (struct ieee80211_mgmt *)
120 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
121 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
122 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
123 IEEE80211_STYPE_PROBE_RESP);
124 memset(mgmt->da, 0xff, ETH_ALEN);
125 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
126 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
127 mgmt->u.beacon.beacon_int =
128 cpu_to_le16(local->hw.conf.beacon_int);
129 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
130
131 pos = skb_put(skb, 2 + ifibss->ssid_len);
132 *pos++ = WLAN_EID_SSID;
133 *pos++ = ifibss->ssid_len;
134 memcpy(pos, ifibss->ssid, ifibss->ssid_len);
135
136 rates = supp_rates_len;
137 if (rates > 8)
138 rates = 8;
139 pos = skb_put(skb, 2 + rates);
140 *pos++ = WLAN_EID_SUPP_RATES;
141 *pos++ = rates;
142 memcpy(pos, supp_rates, rates);
143
144 if (sband->band == IEEE80211_BAND_2GHZ) {
145 pos = skb_put(skb, 2 + 1);
146 *pos++ = WLAN_EID_DS_PARAMS;
147 *pos++ = 1;
148 *pos++ = ieee80211_frequency_to_channel(freq);
149 }
150
151 pos = skb_put(skb, 2 + 2);
152 *pos++ = WLAN_EID_IBSS_PARAMS;
153 *pos++ = 2;
154 /* FIX: set ATIM window based on scan results */
155 *pos++ = 0;
156 *pos++ = 0;
157
158 if (supp_rates_len > 8) {
159 rates = supp_rates_len - 8;
160 pos = skb_put(skb, 2 + rates);
161 *pos++ = WLAN_EID_EXT_SUPP_RATES;
162 *pos++ = rates;
163 memcpy(pos, &supp_rates[8], rates);
164 }
165
166 ifibss->probe_resp = skb;
167
168 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
169 IEEE80211_IFCC_BEACON_ENABLED);
170
171
172 rates = 0;
173 for (i = 0; i < supp_rates_len; i++) {
174 int bitrate = (supp_rates[i] & 0x7f) * 5;
175 for (j = 0; j < sband->n_bitrates; j++)
176 if (sband->bitrates[j].bitrate == bitrate)
177 rates |= BIT(j);
178 }
179
180 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
181
182 ifibss->flags |= IEEE80211_IBSS_PREV_BSSID_SET;
183 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
184 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
185
186 memset(&wrqu, 0, sizeof(wrqu));
187 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
188 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
189
190 return res;
191}
192
193static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
194 struct ieee80211_bss *bss)
195{
196 return __ieee80211_sta_join_ibss(sdata,
197 bss->cbss.bssid,
198 bss->cbss.beacon_interval,
199 bss->cbss.channel->center_freq,
200 bss->supp_rates_len, bss->supp_rates,
201 bss->cbss.capability);
202}
203
204static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
205 struct ieee80211_mgmt *mgmt,
206 size_t len,
207 struct ieee80211_rx_status *rx_status,
208 struct ieee802_11_elems *elems,
209 bool beacon)
210{
211 struct ieee80211_local *local = sdata->local;
212 int freq;
213 struct ieee80211_bss *bss;
214 struct sta_info *sta;
215 struct ieee80211_channel *channel;
216 u64 beacon_timestamp, rx_timestamp;
217 u32 supp_rates = 0;
218 enum ieee80211_band band = rx_status->band;
219
220 if (elems->ds_params && elems->ds_params_len == 1)
221 freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
222 else
223 freq = rx_status->freq;
224
225 channel = ieee80211_get_channel(local->hw.wiphy, freq);
226
227 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
228 return;
229
230 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates &&
231 memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) {
232 supp_rates = ieee80211_sta_get_rates(local, elems, band);
233
234 rcu_read_lock();
235
236 sta = sta_info_get(local, mgmt->sa);
237 if (sta) {
238 u32 prev_rates;
239
240 prev_rates = sta->sta.supp_rates[band];
241 /* make sure mandatory rates are always added */
242 sta->sta.supp_rates[band] = supp_rates |
243 ieee80211_mandatory_rates(local, band);
244
245#ifdef CONFIG_MAC80211_IBSS_DEBUG
246 if (sta->sta.supp_rates[band] != prev_rates)
247 printk(KERN_DEBUG "%s: updated supp_rates set "
248 "for %pM based on beacon info (0x%llx | "
249 "0x%llx -> 0x%llx)\n",
250 sdata->dev->name,
251 sta->sta.addr,
252 (unsigned long long) prev_rates,
253 (unsigned long long) supp_rates,
254 (unsigned long long) sta->sta.supp_rates[band]);
255#endif
256 } else
257 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
258
259 rcu_read_unlock();
260 }
261
262 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
263 channel, beacon);
264 if (!bss)
265 return;
266
267 /* was just updated in ieee80211_bss_info_update */
268 beacon_timestamp = bss->cbss.tsf;
269
270 /* check if we need to merge IBSS */
271
272 /* merge only on beacons (???) */
273 if (!beacon)
274 goto put_bss;
275
276 /* we use a fixed BSSID */
277 if (sdata->u.ibss.flags & IEEE80211_IBSS_BSSID_SET)
278 goto put_bss;
279
280 /* not an IBSS */
281 if (!(bss->cbss.capability & WLAN_CAPABILITY_IBSS))
282 goto put_bss;
283
284 /* different channel */
285 if (bss->cbss.channel != local->oper_channel)
286 goto put_bss;
287
288 /* different SSID */
289 if (elems->ssid_len != sdata->u.ibss.ssid_len ||
290 memcmp(elems->ssid, sdata->u.ibss.ssid,
291 sdata->u.ibss.ssid_len))
292 goto put_bss;
293
294 if (rx_status->flag & RX_FLAG_TSFT) {
295 /*
296 * For correct IBSS merging we need mactime; since mactime is
297 * defined as the time the first data symbol of the frame hits
298 * the PHY, and the timestamp of the beacon is defined as "the
299 * time that the data symbol containing the first bit of the
300 * timestamp is transmitted to the PHY plus the transmitting
301 * STA's delays through its local PHY from the MAC-PHY
302 * interface to its interface with the WM" (802.11 11.1.2)
303 * - equals the time this bit arrives at the receiver - we have
304 * to take into account the offset between the two.
305 *
306 * E.g. at 1 MBit that means mactime is 192 usec earlier
307 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
308 */
309 int rate;
310
311 if (rx_status->flag & RX_FLAG_HT)
312 rate = 65; /* TODO: HT rates */
313 else
314 rate = local->hw.wiphy->bands[band]->
315 bitrates[rx_status->rate_idx].bitrate;
316
317 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
318 } else if (local && local->ops && local->ops->get_tsf)
319 /* second best option: get current TSF */
320 rx_timestamp = local->ops->get_tsf(local_to_hw(local));
321 else
322 /* can't merge without knowing the TSF */
323 rx_timestamp = -1LLU;
324
325#ifdef CONFIG_MAC80211_IBSS_DEBUG
326 printk(KERN_DEBUG "RX beacon SA=%pM BSSID="
327 "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
328 mgmt->sa, mgmt->bssid,
329 (unsigned long long)rx_timestamp,
330 (unsigned long long)beacon_timestamp,
331 (unsigned long long)(rx_timestamp - beacon_timestamp),
332 jiffies);
333#endif
334
335 if (beacon_timestamp > rx_timestamp) {
336#ifdef CONFIG_MAC80211_IBSS_DEBUG
337 printk(KERN_DEBUG "%s: beacon TSF higher than "
338 "local TSF - IBSS merge with BSSID %pM\n",
339 sdata->dev->name, mgmt->bssid);
340#endif
341 ieee80211_sta_join_ibss(sdata, bss);
342 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
343 }
344
345 put_bss:
346 ieee80211_rx_bss_put(local, bss);
347}
348
349/*
350 * Add a new IBSS station, will also be called by the RX code when,
351 * in IBSS mode, receiving a frame from a yet-unknown station, hence
352 * must be callable in atomic context.
353 */
354struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
355 u8 *bssid,u8 *addr, u32 supp_rates)
356{
357 struct ieee80211_local *local = sdata->local;
358 struct sta_info *sta;
359 int band = local->hw.conf.channel->band;
360
361 /* TODO: Could consider removing the least recently used entry and
362 * allow new one to be added. */
363 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
364 if (net_ratelimit()) {
365 printk(KERN_DEBUG "%s: No room for a new IBSS STA "
366 "entry %pM\n", sdata->dev->name, addr);
367 }
368 return NULL;
369 }
370
371 if (compare_ether_addr(bssid, sdata->u.ibss.bssid))
372 return NULL;
373
374#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
375 printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n",
376 wiphy_name(local->hw.wiphy), addr, sdata->dev->name);
377#endif
378
379 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
380 if (!sta)
381 return NULL;
382
383 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
384
385 /* make sure mandatory rates are always added */
386 sta->sta.supp_rates[band] = supp_rates |
387 ieee80211_mandatory_rates(local, band);
388
389 rate_control_rate_init(sta);
390
391 if (sta_info_insert(sta))
392 return NULL;
393
394 return sta;
395}
396
397static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
398{
399 struct ieee80211_local *local = sdata->local;
400 int active = 0;
401 struct sta_info *sta;
402
403 rcu_read_lock();
404
405 list_for_each_entry_rcu(sta, &local->sta_list, list) {
406 if (sta->sdata == sdata &&
407 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
408 jiffies)) {
409 active++;
410 break;
411 }
412 }
413
414 rcu_read_unlock();
415
416 return active;
417}
418
419
420static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
421{
422 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
423
424 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
425
426 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
427 if (ieee80211_sta_active_ibss(sdata))
428 return;
429
430 if ((ifibss->flags & IEEE80211_IBSS_BSSID_SET) &&
431 (!(ifibss->flags & IEEE80211_IBSS_AUTO_CHANNEL_SEL)))
432 return;
433
434 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
435 "IBSS networks with same SSID (merge)\n", sdata->dev->name);
436
437 /* XXX maybe racy? */
438 if (sdata->local->scan_req)
439 return;
440
441 memcpy(sdata->local->int_scan_req.ssids[0].ssid,
442 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
443 sdata->local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
444 ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
445}
446
447static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
448{
449 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
450 struct ieee80211_local *local = sdata->local;
451 struct ieee80211_supported_band *sband;
452 u8 *pos;
453 u8 bssid[ETH_ALEN];
454 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
455 u16 capability;
456 int i;
457
458 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) {
459 memcpy(bssid, ifibss->bssid, ETH_ALEN);
460 } else {
461 /* Generate random, not broadcast, locally administered BSSID. Mix in
462 * own MAC address to make sure that devices that do not have proper
463 * random number generator get different BSSID. */
464 get_random_bytes(bssid, ETH_ALEN);
465 for (i = 0; i < ETH_ALEN; i++)
466 bssid[i] ^= sdata->dev->dev_addr[i];
467 bssid[0] &= ~0x01;
468 bssid[0] |= 0x02;
469 }
470
471 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
472 sdata->dev->name, bssid);
473
474 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
475
476 if (local->hw.conf.beacon_int == 0)
477 local->hw.conf.beacon_int = 100;
478
479 capability = WLAN_CAPABILITY_IBSS;
480
481 if (sdata->default_key)
482 capability |= WLAN_CAPABILITY_PRIVACY;
483 else
484 sdata->drop_unencrypted = 0;
485
486 pos = supp_rates;
487 for (i = 0; i < sband->n_bitrates; i++) {
488 int rate = sband->bitrates[i].bitrate;
489 *pos++ = (u8) (rate / 5);
490 }
491
492 return __ieee80211_sta_join_ibss(sdata,
493 bssid, local->hw.conf.beacon_int,
494 local->hw.conf.channel->center_freq,
495 sband->n_bitrates, supp_rates,
496 capability);
497}
498
499static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
500{
501 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
502 struct ieee80211_local *local = sdata->local;
503 struct ieee80211_bss *bss;
504 const u8 *bssid = NULL;
505 int active_ibss;
506
507 if (ifibss->ssid_len == 0)
508 return -EINVAL;
509
510 active_ibss = ieee80211_sta_active_ibss(sdata);
511#ifdef CONFIG_MAC80211_IBSS_DEBUG
512 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
513 sdata->dev->name, active_ibss);
514#endif /* CONFIG_MAC80211_IBSS_DEBUG */
515
516 if (active_ibss)
517 return 0;
518
519 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET)
520 bssid = ifibss->bssid;
521 bss = (void *)cfg80211_get_bss(local->hw.wiphy, NULL, bssid,
522 ifibss->ssid, ifibss->ssid_len,
523 WLAN_CAPABILITY_IBSS,
524 WLAN_CAPABILITY_IBSS);
525
526#ifdef CONFIG_MAC80211_IBSS_DEBUG
527 if (bss)
528 printk(KERN_DEBUG " sta_find_ibss: selected %pM current "
529 "%pM\n", bss->cbss.bssid, ifibss->bssid);
530#endif /* CONFIG_MAC80211_IBSS_DEBUG */
531
532 if (bss &&
533 (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) ||
534 memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN))) {
535 int ret;
536
537 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
538 " based on configured SSID\n",
539 sdata->dev->name, bss->cbss.bssid);
540
541 ret = ieee80211_sta_join_ibss(sdata, bss);
542 ieee80211_rx_bss_put(local, bss);
543 return ret;
544 } else if (bss)
545 ieee80211_rx_bss_put(local, bss);
546
547#ifdef CONFIG_MAC80211_IBSS_DEBUG
548 printk(KERN_DEBUG " did not try to join ibss\n");
549#endif /* CONFIG_MAC80211_IBSS_DEBUG */
550
551 /* Selected IBSS not found in current scan results - try to scan */
552 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
553 !ieee80211_sta_active_ibss(sdata)) {
554 mod_timer(&ifibss->timer, jiffies +
555 IEEE80211_IBSS_MERGE_INTERVAL);
556 } else if (time_after(jiffies, local->last_scan_completed +
557 IEEE80211_SCAN_INTERVAL)) {
558 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
559 "join\n", sdata->dev->name);
560
561 /* XXX maybe racy? */
562 if (local->scan_req)
563 return -EBUSY;
564
565 memcpy(local->int_scan_req.ssids[0].ssid,
566 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
567 local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
568 return ieee80211_request_scan(sdata, &local->int_scan_req);
569 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
570 int interval = IEEE80211_SCAN_INTERVAL;
571
572 if (time_after(jiffies, ifibss->ibss_join_req +
573 IEEE80211_IBSS_JOIN_TIMEOUT)) {
574 if (!(local->oper_channel->flags &
575 IEEE80211_CHAN_NO_IBSS))
576 return ieee80211_sta_create_ibss(sdata);
577 printk(KERN_DEBUG "%s: IBSS not allowed on"
578 " %d MHz\n", sdata->dev->name,
579 local->hw.conf.channel->center_freq);
580
581 /* No IBSS found - decrease scan interval and continue
582 * scanning. */
583 interval = IEEE80211_SCAN_INTERVAL_SLOW;
584 }
585
586 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
587 mod_timer(&ifibss->timer, jiffies + interval);
588 return 0;
589 }
590
591 return 0;
592}
593
594static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
595 struct ieee80211_mgmt *mgmt,
596 size_t len)
597{
598 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
599 struct ieee80211_local *local = sdata->local;
600 int tx_last_beacon;
601 struct sk_buff *skb;
602 struct ieee80211_mgmt *resp;
603 u8 *pos, *end;
604
605 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
606 len < 24 + 2 || !ifibss->probe_resp)
607 return;
608
609 if (local->ops->tx_last_beacon)
610 tx_last_beacon = local->ops->tx_last_beacon(local_to_hw(local));
611 else
612 tx_last_beacon = 1;
613
614#ifdef CONFIG_MAC80211_IBSS_DEBUG
615 printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
616 " (tx_last_beacon=%d)\n",
617 sdata->dev->name, mgmt->sa, mgmt->da,
618 mgmt->bssid, tx_last_beacon);
619#endif /* CONFIG_MAC80211_IBSS_DEBUG */
620
621 if (!tx_last_beacon)
622 return;
623
624 if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
625 memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
626 return;
627
628 end = ((u8 *) mgmt) + len;
629 pos = mgmt->u.probe_req.variable;
630 if (pos[0] != WLAN_EID_SSID ||
631 pos + 2 + pos[1] > end) {
632#ifdef CONFIG_MAC80211_IBSS_DEBUG
633 printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
634 "from %pM\n",
635 sdata->dev->name, mgmt->sa);
636#endif
637 return;
638 }
639 if (pos[1] != 0 &&
640 (pos[1] != ifibss->ssid_len ||
641 memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len) != 0)) {
642 /* Ignore ProbeReq for foreign SSID */
643 return;
644 }
645
646 /* Reply with ProbeResp */
647 skb = skb_copy(ifibss->probe_resp, GFP_KERNEL);
648 if (!skb)
649 return;
650
651 resp = (struct ieee80211_mgmt *) skb->data;
652 memcpy(resp->da, mgmt->sa, ETH_ALEN);
653#ifdef CONFIG_MAC80211_IBSS_DEBUG
654 printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n",
655 sdata->dev->name, resp->da);
656#endif /* CONFIG_MAC80211_IBSS_DEBUG */
657 ieee80211_tx_skb(sdata, skb, 0);
658}
659
660static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
661 struct ieee80211_mgmt *mgmt,
662 size_t len,
663 struct ieee80211_rx_status *rx_status)
664{
665 size_t baselen;
666 struct ieee802_11_elems elems;
667
668 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
669 return; /* ignore ProbeResp to foreign address */
670
671 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
672 if (baselen > len)
673 return;
674
675 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
676 &elems);
677
678 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
679}
680
681static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
682 struct ieee80211_mgmt *mgmt,
683 size_t len,
684 struct ieee80211_rx_status *rx_status)
685{
686 size_t baselen;
687 struct ieee802_11_elems elems;
688
689 /* Process beacon from the current BSS */
690 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
691 if (baselen > len)
692 return;
693
694 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
695
696 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
697}
698
699static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
700 struct sk_buff *skb)
701{
702 struct ieee80211_rx_status *rx_status;
703 struct ieee80211_mgmt *mgmt;
704 u16 fc;
705
706 rx_status = (struct ieee80211_rx_status *) skb->cb;
707 mgmt = (struct ieee80211_mgmt *) skb->data;
708 fc = le16_to_cpu(mgmt->frame_control);
709
710 switch (fc & IEEE80211_FCTL_STYPE) {
711 case IEEE80211_STYPE_PROBE_REQ:
712 ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len);
713 break;
714 case IEEE80211_STYPE_PROBE_RESP:
715 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len,
716 rx_status);
717 break;
718 case IEEE80211_STYPE_BEACON:
719 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
720 rx_status);
721 break;
722 case IEEE80211_STYPE_AUTH:
723 ieee80211_rx_mgmt_auth_ibss(sdata, mgmt, skb->len);
724 break;
725 }
726
727 kfree_skb(skb);
728}
729
730static void ieee80211_ibss_work(struct work_struct *work)
731{
732 struct ieee80211_sub_if_data *sdata =
733 container_of(work, struct ieee80211_sub_if_data, u.ibss.work);
734 struct ieee80211_local *local = sdata->local;
735 struct ieee80211_if_ibss *ifibss;
736 struct sk_buff *skb;
737
738 if (!netif_running(sdata->dev))
739 return;
740
741 if (local->sw_scanning || local->hw_scanning)
742 return;
743
744 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC))
745 return;
746 ifibss = &sdata->u.ibss;
747
748 while ((skb = skb_dequeue(&ifibss->skb_queue)))
749 ieee80211_ibss_rx_queued_mgmt(sdata, skb);
750
751 if (!test_and_clear_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request))
752 return;
753
754 switch (ifibss->state) {
755 case IEEE80211_IBSS_MLME_SEARCH:
756 ieee80211_sta_find_ibss(sdata);
757 break;
758 case IEEE80211_IBSS_MLME_JOINED:
759 ieee80211_sta_merge_ibss(sdata);
760 break;
761 default:
762 WARN_ON(1);
763 break;
764 }
765}
766
767static void ieee80211_ibss_timer(unsigned long data)
768{
769 struct ieee80211_sub_if_data *sdata =
770 (struct ieee80211_sub_if_data *) data;
771 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
772 struct ieee80211_local *local = sdata->local;
773
774 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
775 queue_work(local->hw.workqueue, &ifibss->work);
776}
777
778void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
779{
780 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
781
782 INIT_WORK(&ifibss->work, ieee80211_ibss_work);
783 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
784 (unsigned long) sdata);
785 skb_queue_head_init(&ifibss->skb_queue);
786
787 ifibss->flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
788 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
789}
790
791int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
792{
793 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
794
795 if (len > IEEE80211_MAX_SSID_LEN)
796 return -EINVAL;
797
798 if (ifibss->ssid_len != len || memcmp(ifibss->ssid, ssid, len) != 0) {
799 memset(ifibss->ssid, 0, sizeof(ifibss->ssid));
800 memcpy(ifibss->ssid, ssid, len);
801 ifibss->ssid_len = len;
802 }
803
804 ifibss->flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
805
806 if (len)
807 ifibss->flags |= IEEE80211_IBSS_SSID_SET;
808 else
809 ifibss->flags &= ~IEEE80211_IBSS_SSID_SET;
810
811 ifibss->ibss_join_req = jiffies;
812 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
813 return ieee80211_sta_find_ibss(sdata);
814}
815
816int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
817{
818 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
819
820 memcpy(ssid, ifibss->ssid, ifibss->ssid_len);
821 *len = ifibss->ssid_len;
822
823 return 0;
824}
825
826int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
827{
828 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
829
830 if (is_valid_ether_addr(bssid)) {
831 memcpy(ifibss->bssid, bssid, ETH_ALEN);
832 ifibss->flags |= IEEE80211_IBSS_BSSID_SET;
833 } else {
834 memset(ifibss->bssid, 0, ETH_ALEN);
835 ifibss->flags &= ~IEEE80211_IBSS_BSSID_SET;
836 }
837
838 if (netif_running(sdata->dev)) {
839 if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
840 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
841 "the low-level driver\n", sdata->dev->name);
842 }
843 }
844
845 return ieee80211_ibss_set_ssid(sdata, ifibss->ssid, ifibss->ssid_len);
846}
847
848/* scan finished notification */
849void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
850{
851 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
852 struct ieee80211_if_ibss *ifibss;
853
854 if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) {
855 ifibss = &sdata->u.ibss;
856 if ((!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) ||
857 !ieee80211_sta_active_ibss(sdata))
858 ieee80211_sta_find_ibss(sdata);
859 }
860}
861
862ieee80211_rx_result
863ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
864 struct ieee80211_rx_status *rx_status)
865{
866 struct ieee80211_local *local = sdata->local;
867 struct ieee80211_mgmt *mgmt;
868 u16 fc;
869
870 if (skb->len < 24)
871 return RX_DROP_MONITOR;
872
873 mgmt = (struct ieee80211_mgmt *) skb->data;
874 fc = le16_to_cpu(mgmt->frame_control);
875
876 switch (fc & IEEE80211_FCTL_STYPE) {
877 case IEEE80211_STYPE_PROBE_RESP:
878 case IEEE80211_STYPE_BEACON:
879 memcpy(skb->cb, rx_status, sizeof(*rx_status));
880 case IEEE80211_STYPE_PROBE_REQ:
881 case IEEE80211_STYPE_AUTH:
882 skb_queue_tail(&sdata->u.ibss.skb_queue, skb);
883 queue_work(local->hw.workqueue, &sdata->u.ibss.work);
884 return RX_QUEUED;
885 }
886
887 return RX_DROP_MONITOR;
888}