diff options
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r-- | net/mac80211/ibss.c | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index a497c03c03d7..d38baa41cf6c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -36,31 +36,6 @@ | |||
36 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 | 36 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 |
37 | 37 | ||
38 | 38 | ||
39 | static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | ||
40 | struct ieee80211_mgmt *mgmt, | ||
41 | size_t len) | ||
42 | { | ||
43 | u16 auth_alg, auth_transaction; | ||
44 | |||
45 | lockdep_assert_held(&sdata->u.ibss.mtx); | ||
46 | |||
47 | if (len < 24 + 6) | ||
48 | return; | ||
49 | |||
50 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | ||
51 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | ||
52 | |||
53 | /* | ||
54 | * IEEE 802.11 standard does not require authentication in IBSS | ||
55 | * networks and most implementations do not seem to use it. | ||
56 | * However, try to reply to authentication attempts if someone | ||
57 | * has actually implemented this. | ||
58 | */ | ||
59 | if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) | ||
60 | ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, mgmt->sa, | ||
61 | sdata->u.ibss.bssid, NULL, 0, 0); | ||
62 | } | ||
63 | |||
64 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | 39 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, |
65 | const u8 *bssid, const int beacon_int, | 40 | const u8 *bssid, const int beacon_int, |
66 | struct ieee80211_channel *chan, | 41 | struct ieee80211_channel *chan, |
@@ -275,7 +250,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
275 | cbss->tsf); | 250 | cbss->tsf); |
276 | } | 251 | } |
277 | 252 | ||
278 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta) | 253 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, |
254 | bool auth) | ||
279 | __acquires(RCU) | 255 | __acquires(RCU) |
280 | { | 256 | { |
281 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 257 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
@@ -298,20 +274,22 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta) | |||
298 | /* If it fails, maybe we raced another insertion? */ | 274 | /* If it fails, maybe we raced another insertion? */ |
299 | if (sta_info_insert_rcu(sta)) | 275 | if (sta_info_insert_rcu(sta)) |
300 | return sta_info_get(sdata, addr); | 276 | return sta_info_get(sdata, addr); |
277 | if (auth) { | ||
301 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 278 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
302 | printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM" | 279 | printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM" |
303 | "(auth_transaction=1)\n", sdata->vif.addr, | 280 | "(auth_transaction=1)\n", sdata->vif.addr, |
304 | sdata->u.ibss.bssid, addr); | 281 | sdata->u.ibss.bssid, addr); |
305 | #endif | 282 | #endif |
306 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, | 283 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, |
307 | addr, sdata->u.ibss.bssid, NULL, 0, 0); | 284 | addr, sdata->u.ibss.bssid, NULL, 0, 0); |
285 | } | ||
308 | return sta; | 286 | return sta; |
309 | } | 287 | } |
310 | 288 | ||
311 | static struct sta_info * | 289 | static struct sta_info * |
312 | ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 290 | ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, |
313 | const u8 *bssid, const u8 *addr, | 291 | const u8 *bssid, const u8 *addr, |
314 | u32 supp_rates) | 292 | u32 supp_rates, bool auth) |
315 | __acquires(RCU) | 293 | __acquires(RCU) |
316 | { | 294 | { |
317 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 295 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
@@ -353,7 +331,42 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
353 | sta->sta.supp_rates[band] = supp_rates | | 331 | sta->sta.supp_rates[band] = supp_rates | |
354 | ieee80211_mandatory_rates(local, band); | 332 | ieee80211_mandatory_rates(local, band); |
355 | 333 | ||
356 | return ieee80211_ibss_finish_sta(sta); | 334 | return ieee80211_ibss_finish_sta(sta, auth); |
335 | } | ||
336 | |||
337 | static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | ||
338 | struct ieee80211_mgmt *mgmt, | ||
339 | size_t len) | ||
340 | { | ||
341 | u16 auth_alg, auth_transaction; | ||
342 | |||
343 | lockdep_assert_held(&sdata->u.ibss.mtx); | ||
344 | |||
345 | if (len < 24 + 6) | ||
346 | return; | ||
347 | |||
348 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | ||
349 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | ||
350 | |||
351 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) | ||
352 | return; | ||
353 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
354 | printk(KERN_DEBUG "%s: RX Auth SA=%pM DA=%pM BSSID=%pM." | ||
355 | "(auth_transaction=%d)\n", | ||
356 | sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); | ||
357 | #endif | ||
358 | sta_info_destroy_addr(sdata, mgmt->sa); | ||
359 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); | ||
360 | rcu_read_unlock(); | ||
361 | |||
362 | /* | ||
363 | * IEEE 802.11 standard does not require authentication in IBSS | ||
364 | * networks and most implementations do not seem to use it. | ||
365 | * However, try to reply to authentication attempts if someone | ||
366 | * has actually implemented this. | ||
367 | */ | ||
368 | ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, | ||
369 | mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0); | ||
357 | } | 370 | } |
358 | 371 | ||
359 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 372 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, |
@@ -418,7 +431,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
418 | } else { | 431 | } else { |
419 | rcu_read_unlock(); | 432 | rcu_read_unlock(); |
420 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, | 433 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, |
421 | mgmt->sa, supp_rates); | 434 | mgmt->sa, supp_rates, true); |
422 | } | 435 | } |
423 | } | 436 | } |
424 | 437 | ||
@@ -546,7 +559,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
546 | ieee80211_sta_join_ibss(sdata, bss); | 559 | ieee80211_sta_join_ibss(sdata, bss); |
547 | supp_rates = ieee80211_sta_get_rates(local, elems, band); | 560 | supp_rates = ieee80211_sta_get_rates(local, elems, band); |
548 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, | 561 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, |
549 | supp_rates); | 562 | supp_rates, true); |
550 | rcu_read_unlock(); | 563 | rcu_read_unlock(); |
551 | } | 564 | } |
552 | 565 | ||
@@ -947,7 +960,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) | |||
947 | list_del(&sta->list); | 960 | list_del(&sta->list); |
948 | spin_unlock_bh(&ifibss->incomplete_lock); | 961 | spin_unlock_bh(&ifibss->incomplete_lock); |
949 | 962 | ||
950 | ieee80211_ibss_finish_sta(sta); | 963 | ieee80211_ibss_finish_sta(sta, true); |
951 | rcu_read_unlock(); | 964 | rcu_read_unlock(); |
952 | spin_lock_bh(&ifibss->incomplete_lock); | 965 | spin_lock_bh(&ifibss->incomplete_lock); |
953 | } | 966 | } |