diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-03-16 13:45:25 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-16 13:45:25 -0400 |
commit | 01a282980937f9ca55a3cb06b9c6ff1cc49ea396 (patch) | |
tree | 07a043edc861e245a7a9764751af0898a1f1199a /net/mac80211/wep.c | |
parent | d5ddb4a59ed43b4c569b4efa8b508d50ef140cc6 (diff) | |
parent | 377526578f2c343ea281a918b18ece1fca65005c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
drivers/net/wireless/ath/ath9k/hw.c
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r-- | net/mac80211/wep.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 68ad351479df..7aa31bbfaa3b 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -263,16 +263,14 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, | |||
263 | } | 263 | } |
264 | 264 | ||
265 | 265 | ||
266 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 266 | static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, |
267 | struct ieee80211_key *key) | ||
267 | { | 268 | { |
268 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 269 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
269 | unsigned int hdrlen; | 270 | unsigned int hdrlen; |
270 | u8 *ivpos; | 271 | u8 *ivpos; |
271 | u32 iv; | 272 | u32 iv; |
272 | 273 | ||
273 | if (!ieee80211_has_protected(hdr->frame_control)) | ||
274 | return false; | ||
275 | |||
276 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 274 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
277 | ivpos = skb->data + hdrlen; | 275 | ivpos = skb->data + hdrlen; |
278 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; | 276 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; |
@@ -286,18 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
286 | struct sk_buff *skb = rx->skb; | 284 | struct sk_buff *skb = rx->skb; |
287 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 285 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
288 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 286 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
287 | __le16 fc = hdr->frame_control; | ||
289 | 288 | ||
290 | if (!ieee80211_is_data(hdr->frame_control) && | 289 | if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc)) |
291 | !ieee80211_is_auth(hdr->frame_control)) | ||
292 | return RX_CONTINUE; | 290 | return RX_CONTINUE; |
293 | 291 | ||
294 | if (!(status->flag & RX_FLAG_DECRYPTED)) { | 292 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
293 | if (skb_linearize(rx->skb)) | ||
294 | return RX_DROP_UNUSABLE; | ||
295 | if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
296 | rx->sta->wep_weak_iv_count++; | ||
295 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) | 297 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
296 | return RX_DROP_UNUSABLE; | 298 | return RX_DROP_UNUSABLE; |
297 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { | 299 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { |
300 | if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN)) | ||
301 | return RX_DROP_UNUSABLE; | ||
302 | if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
303 | rx->sta->wep_weak_iv_count++; | ||
298 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 304 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
299 | /* remove ICV */ | 305 | /* remove ICV */ |
300 | skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); | 306 | if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN)) |
307 | return RX_DROP_UNUSABLE; | ||
301 | } | 308 | } |
302 | 309 | ||
303 | return RX_CONTINUE; | 310 | return RX_CONTINUE; |