diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/Makefile | 1 | ||||
-rw-r--r-- | net/mac80211/event.c | 42 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/rx.c | 41 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 34 |
5 files changed, 57 insertions, 63 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 122b23e..7937338 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -22,4 +22,5 @@ mac80211-objs := \ tx.o \ key.o \ util.o \ + event.o \ $(mac80211-objs-y) diff --git a/net/mac80211/event.c b/net/mac80211/event.c new file mode 100644 index 0000000..68a526c --- /dev/null +++ b/net/mac80211/event.c @@ -0,0 +1,42 @@ +/* + * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * mac80211 - events + */ + +#include <linux/netdevice.h> +#include <net/iw_handler.h> +#include "ieee80211_i.h" + +/* + * indicate a failed Michael MIC to userspace; the passed packet + * (in the variable hdr) must be long enough to extract the TKIP + * fields like TSC + */ +void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, + struct ieee80211_hdr *hdr) +{ + union iwreq_data wrqu; + char *buf = kmalloc(128, GFP_ATOMIC); + + if (buf) { + /* TODO: needed parameters: count, key type, TSC */ + sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" + "keyid=%d %scast addr=" MAC_FMT ")", + keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", + MAC_ARG(hdr->addr2)); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlen(buf); + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); + kfree(buf); + } + + /* + * TODO: re-add support for sending MIC failure indication + * with all info via nl80211 + */ +} diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c771b7a..9c5fd86 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -823,5 +823,7 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len); int ieee80211_is_eapol(const struct sk_buff *skb); int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, int rate, int erp, int short_preamble); +void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, + struct ieee80211_hdr *hdr); #endif /* IEEE80211_I_H */ diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 08ca066..5a66269 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -13,7 +13,6 @@ #include <linux/skbuff.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> -#include <net/iw_handler.h> #include <net/mac80211.h> #include <net/ieee80211_radiotap.h> @@ -1206,20 +1205,17 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, } if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && - rx->sdata->type == IEEE80211_IF_TYPE_AP) { - keyidx = ieee80211_wep_get_keyidx(rx->skb); + rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) { /* AP with Pairwise keys support should never receive Michael * MIC errors for non-zero keyidx because these are reserved * for group keys and only the AP is sending real multicast * frames in BSS. */ - if (keyidx) { - if (net_ratelimit()) - printk(KERN_DEBUG "%s: ignored Michael MIC " - "error for a frame with non-zero keyidx" - " (%d) (src " MAC_FMT ")\n", dev->name, - keyidx, MAC_ARG(hdr->addr2)); - goto ignore; - } + if (net_ratelimit()) + printk(KERN_DEBUG "%s: ignored Michael MIC error for " + "a frame with non-zero keyidx (%d)" + " (src " MAC_FMT ")\n", dev->name, keyidx, + MAC_ARG(hdr->addr2)); + goto ignore; } if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && @@ -1233,32 +1229,11 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, goto ignore; } - do { - union iwreq_data wrqu; - char *buf = kmalloc(128, GFP_ATOMIC); - if (!buf) - break; - - /* TODO: needed parameters: count, key type, TSC */ - sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" - "keyid=%d %scast addr=" MAC_FMT ")", - keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC_ARG(hdr->addr2)); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf); - kfree(buf); - } while (0); - /* TODO: consider verifying the MIC error report with software * implementation if we get too many spurious reports from the * hardware. */ - if (!rx->local->apdev) - goto ignore; - ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status, - ieee80211_msg_michael_mic_failure); - return; + mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); ignore: dev_kfree_skb(rx->skb); rx->skb = NULL; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f5723ea..742b558 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -11,10 +11,8 @@ #include <linux/slab.h> #include <linux/skbuff.h> #include <linux/compiler.h> -#include <net/iw_handler.h> - #include <net/mac80211.h> -#include "ieee80211_common.h" + #include "ieee80211_i.h" #include "michael.h" #include "tkip.h" @@ -181,33 +179,9 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " MAC_FMT "\n", rx->dev->name, MAC_ARG(sa)); - do { - struct ieee80211_hdr *hdr; - union iwreq_data wrqu; - char *buf = kmalloc(128, GFP_ATOMIC); - if (!buf) - break; - - /* TODO: needed parameters: count, key type, TSC */ - hdr = (struct ieee80211_hdr *) skb->data; - sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" - "keyid=%d %scast addr=" MAC_FMT ")", - rx->key->keyidx, - hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC_ARG(hdr->addr2)); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf); - kfree(buf); - } while (0); - - if (!rx->local->apdev) - return TXRX_DROP; - - ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status, - ieee80211_msg_michael_mic_failure); - - return TXRX_QUEUED; + mac80211_ev_michael_mic_failure(rx->dev, rx->key->keyidx, + (void *) skb->data); + return TXRX_DROP; } remove_mic: |