diff options
-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 122b23eb15d1..793733835628 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -22,4 +22,5 @@ mac80211-objs := \ | |||
22 | tx.o \ | 22 | tx.o \ |
23 | key.o \ | 23 | key.o \ |
24 | util.o \ | 24 | util.o \ |
25 | event.o \ | ||
25 | $(mac80211-objs-y) | 26 | $(mac80211-objs-y) |
diff --git a/net/mac80211/event.c b/net/mac80211/event.c new file mode 100644 index 000000000000..68a526cb7623 --- /dev/null +++ b/net/mac80211/event.c | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * mac80211 - events | ||
9 | */ | ||
10 | |||
11 | #include <linux/netdevice.h> | ||
12 | #include <net/iw_handler.h> | ||
13 | #include "ieee80211_i.h" | ||
14 | |||
15 | /* | ||
16 | * indicate a failed Michael MIC to userspace; the passed packet | ||
17 | * (in the variable hdr) must be long enough to extract the TKIP | ||
18 | * fields like TSC | ||
19 | */ | ||
20 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, | ||
21 | struct ieee80211_hdr *hdr) | ||
22 | { | ||
23 | union iwreq_data wrqu; | ||
24 | char *buf = kmalloc(128, GFP_ATOMIC); | ||
25 | |||
26 | if (buf) { | ||
27 | /* TODO: needed parameters: count, key type, TSC */ | ||
28 | sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" | ||
29 | "keyid=%d %scast addr=" MAC_FMT ")", | ||
30 | keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", | ||
31 | MAC_ARG(hdr->addr2)); | ||
32 | memset(&wrqu, 0, sizeof(wrqu)); | ||
33 | wrqu.data.length = strlen(buf); | ||
34 | wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); | ||
35 | kfree(buf); | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * TODO: re-add support for sending MIC failure indication | ||
40 | * with all info via nl80211 | ||
41 | */ | ||
42 | } | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c771b7a76959..9c5fd861eb72 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); | |||
823 | int ieee80211_is_eapol(const struct sk_buff *skb); | 823 | int ieee80211_is_eapol(const struct sk_buff *skb); |
824 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | 824 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, |
825 | int rate, int erp, int short_preamble); | 825 | int rate, int erp, int short_preamble); |
826 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, | ||
827 | struct ieee80211_hdr *hdr); | ||
826 | 828 | ||
827 | #endif /* IEEE80211_I_H */ | 829 | #endif /* IEEE80211_I_H */ |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 08ca066246b9..5a66269d9435 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/skbuff.h> | 13 | #include <linux/skbuff.h> |
14 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
15 | #include <linux/etherdevice.h> | 15 | #include <linux/etherdevice.h> |
16 | #include <net/iw_handler.h> | ||
17 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
18 | #include <net/ieee80211_radiotap.h> | 17 | #include <net/ieee80211_radiotap.h> |
19 | 18 | ||
@@ -1206,20 +1205,17 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1206 | } | 1205 | } |
1207 | 1206 | ||
1208 | if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && | 1207 | if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && |
1209 | rx->sdata->type == IEEE80211_IF_TYPE_AP) { | 1208 | rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) { |
1210 | keyidx = ieee80211_wep_get_keyidx(rx->skb); | ||
1211 | /* AP with Pairwise keys support should never receive Michael | 1209 | /* AP with Pairwise keys support should never receive Michael |
1212 | * MIC errors for non-zero keyidx because these are reserved | 1210 | * MIC errors for non-zero keyidx because these are reserved |
1213 | * for group keys and only the AP is sending real multicast | 1211 | * for group keys and only the AP is sending real multicast |
1214 | * frames in BSS. */ | 1212 | * frames in BSS. */ |
1215 | if (keyidx) { | 1213 | if (net_ratelimit()) |
1216 | if (net_ratelimit()) | 1214 | printk(KERN_DEBUG "%s: ignored Michael MIC error for " |
1217 | printk(KERN_DEBUG "%s: ignored Michael MIC " | 1215 | "a frame with non-zero keyidx (%d)" |
1218 | "error for a frame with non-zero keyidx" | 1216 | " (src " MAC_FMT ")\n", dev->name, keyidx, |
1219 | " (%d) (src " MAC_FMT ")\n", dev->name, | 1217 | MAC_ARG(hdr->addr2)); |
1220 | keyidx, MAC_ARG(hdr->addr2)); | 1218 | goto ignore; |
1221 | goto ignore; | ||
1222 | } | ||
1223 | } | 1219 | } |
1224 | 1220 | ||
1225 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 1221 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && |
@@ -1233,32 +1229,11 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1233 | goto ignore; | 1229 | goto ignore; |
1234 | } | 1230 | } |
1235 | 1231 | ||
1236 | do { | ||
1237 | union iwreq_data wrqu; | ||
1238 | char *buf = kmalloc(128, GFP_ATOMIC); | ||
1239 | if (!buf) | ||
1240 | break; | ||
1241 | |||
1242 | /* TODO: needed parameters: count, key type, TSC */ | ||
1243 | sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" | ||
1244 | "keyid=%d %scast addr=" MAC_FMT ")", | ||
1245 | keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", | ||
1246 | MAC_ARG(hdr->addr2)); | ||
1247 | memset(&wrqu, 0, sizeof(wrqu)); | ||
1248 | wrqu.data.length = strlen(buf); | ||
1249 | wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf); | ||
1250 | kfree(buf); | ||
1251 | } while (0); | ||
1252 | |||
1253 | /* TODO: consider verifying the MIC error report with software | 1232 | /* TODO: consider verifying the MIC error report with software |
1254 | * implementation if we get too many spurious reports from the | 1233 | * implementation if we get too many spurious reports from the |
1255 | * hardware. */ | 1234 | * hardware. */ |
1256 | if (!rx->local->apdev) | ||
1257 | goto ignore; | ||
1258 | ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status, | ||
1259 | ieee80211_msg_michael_mic_failure); | ||
1260 | return; | ||
1261 | 1235 | ||
1236 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); | ||
1262 | ignore: | 1237 | ignore: |
1263 | dev_kfree_skb(rx->skb); | 1238 | dev_kfree_skb(rx->skb); |
1264 | rx->skb = NULL; | 1239 | rx->skb = NULL; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f5723ea15aae..742b5585d1b7 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -11,10 +11,8 @@ | |||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
13 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
14 | #include <net/iw_handler.h> | ||
15 | |||
16 | #include <net/mac80211.h> | 14 | #include <net/mac80211.h> |
17 | #include "ieee80211_common.h" | 15 | |
18 | #include "ieee80211_i.h" | 16 | #include "ieee80211_i.h" |
19 | #include "michael.h" | 17 | #include "michael.h" |
20 | #include "tkip.h" | 18 | #include "tkip.h" |
@@ -181,33 +179,9 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
181 | printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " | 179 | printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " |
182 | MAC_FMT "\n", rx->dev->name, MAC_ARG(sa)); | 180 | MAC_FMT "\n", rx->dev->name, MAC_ARG(sa)); |
183 | 181 | ||
184 | do { | 182 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->keyidx, |
185 | struct ieee80211_hdr *hdr; | 183 | (void *) skb->data); |
186 | union iwreq_data wrqu; | 184 | return TXRX_DROP; |
187 | char *buf = kmalloc(128, GFP_ATOMIC); | ||
188 | if (!buf) | ||
189 | break; | ||
190 | |||
191 | /* TODO: needed parameters: count, key type, TSC */ | ||
192 | hdr = (struct ieee80211_hdr *) skb->data; | ||
193 | sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" | ||
194 | "keyid=%d %scast addr=" MAC_FMT ")", | ||
195 | rx->key->keyidx, | ||
196 | hdr->addr1[0] & 0x01 ? "broad" : "uni", | ||
197 | MAC_ARG(hdr->addr2)); | ||
198 | memset(&wrqu, 0, sizeof(wrqu)); | ||
199 | wrqu.data.length = strlen(buf); | ||
200 | wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf); | ||
201 | kfree(buf); | ||
202 | } while (0); | ||
203 | |||
204 | if (!rx->local->apdev) | ||
205 | return TXRX_DROP; | ||
206 | |||
207 | ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status, | ||
208 | ieee80211_msg_michael_mic_failure); | ||
209 | |||
210 | return TXRX_QUEUED; | ||
211 | } | 185 | } |
212 | 186 | ||
213 | remove_mic: | 187 | remove_mic: |