aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-03-27 15:59:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:54:28 -0400
commita3b8b0569fbef725597f05278ec58083321f6e9d (patch)
treecb3beb05c841a9564a3fdd44d540570c7b89c9f6 /net
parent53b46b8444f600cc1744521ea096ea0c5d494dd0 (diff)
nl80211: Add Michael MIC failure event
Define a new nl80211 event, NL80211_CMD_MICHAEL_MIC_FAILURE, to be used to notify user space about locally detected Michael MIC failures. This matches with the MLME-MICHAELMICFAILURE.indication() primitive. Since we do not actually have TSC in the skb anymore when mac80211_ev_michael_mic_failure() is called, that function is changed to take in the TSC as an optional parameter instead of as a requirement to include the TSC after the hdr field (which we did not really follow). For now, TSC is not included in the events from mac80211, but it could be added at some point. Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/event.c17
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/wpa.c2
-rw-r--r--net/wireless/mlme.c10
-rw-r--r--net/wireless/nl80211.c40
-rw-r--r--net/wireless/nl80211.h5
7 files changed, 67 insertions, 11 deletions
diff --git a/net/mac80211/event.c b/net/mac80211/event.c
index 0d95561c0ee0..f288d01a6344 100644
--- a/net/mac80211/event.c
+++ b/net/mac80211/event.c
@@ -12,12 +12,12 @@
12#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13 13
14/* 14/*
15 * indicate a failed Michael MIC to userspace; the passed packet 15 * Indicate a failed Michael MIC to userspace. If the caller knows the TSC of
16 * (in the variable hdr) must be long enough to extract the TKIP 16 * the frame that generated the MIC failure (i.e., if it was provided by the
17 * fields like TSC 17 * driver or is still in the frame), it should provide that information.
18 */ 18 */
19void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 19void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
20 struct ieee80211_hdr *hdr) 20 struct ieee80211_hdr *hdr, const u8 *tsc)
21{ 21{
22 union iwreq_data wrqu; 22 union iwreq_data wrqu;
23 char *buf = kmalloc(128, GFP_ATOMIC); 23 char *buf = kmalloc(128, GFP_ATOMIC);
@@ -34,8 +34,9 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
34 kfree(buf); 34 kfree(buf);
35 } 35 }
36 36
37 /* 37 cfg80211_michael_mic_failure(sdata->dev, hdr->addr2,
38 * TODO: re-add support for sending MIC failure indication 38 (hdr->addr1[0] & 0x01) ?
39 * with all info via nl80211 39 NL80211_KEYTYPE_GROUP :
40 */ 40 NL80211_KEYTYPE_PAIRWISE,
41 keyidx, tsc);
41} 42}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6ed78cb16b3..312347d102c8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1060,7 +1060,7 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
1060int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 1060int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
1061 int rate, int erp, int short_preamble); 1061 int rate, int erp, int short_preamble);
1062void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 1062void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
1063 struct ieee80211_hdr *hdr); 1063 struct ieee80211_hdr *hdr, const u8 *tsc);
1064void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); 1064void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
1065void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 1065void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1066 int encrypt); 1066 int encrypt);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5fa7aedd90ed..19c4b4589fee 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1932,7 +1932,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1932 !ieee80211_is_auth(hdr->frame_control)) 1932 !ieee80211_is_auth(hdr->frame_control))
1933 goto ignore; 1933 goto ignore;
1934 1934
1935 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr); 1935 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL);
1936 ignore: 1936 ignore:
1937 dev_kfree_skb(rx->skb); 1937 dev_kfree_skb(rx->skb);
1938 rx->skb = NULL; 1938 rx->skb = NULL;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 4f8bfea278f2..dcfae8884b86 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -122,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
122 return RX_DROP_UNUSABLE; 122 return RX_DROP_UNUSABLE;
123 123
124 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, 124 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
125 (void *) skb->data); 125 (void *) skb->data, NULL);
126 return RX_DROP_UNUSABLE; 126 return RX_DROP_UNUSABLE;
127 } 127 }
128 128
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 33ff7cca496b..1407244a647e 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -43,3 +43,13 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
43 nl80211_send_disassoc(rdev, dev, buf, len); 43 nl80211_send_disassoc(rdev, dev, buf, len);
44} 44}
45EXPORT_SYMBOL(cfg80211_send_disassoc); 45EXPORT_SYMBOL(cfg80211_send_disassoc);
46
47void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
48 enum nl80211_key_type key_type, int key_id,
49 const u8 *tsc)
50{
51 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
52 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
53 nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc);
54}
55EXPORT_SYMBOL(cfg80211_michael_mic_failure);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 195424eee77d..1394115cde95 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3430,6 +3430,46 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
3430 NL80211_CMD_DISASSOCIATE); 3430 NL80211_CMD_DISASSOCIATE);
3431} 3431}
3432 3432
3433void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3434 struct net_device *netdev, const u8 *addr,
3435 enum nl80211_key_type key_type, int key_id,
3436 const u8 *tsc)
3437{
3438 struct sk_buff *msg;
3439 void *hdr;
3440
3441 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3442 if (!msg)
3443 return;
3444
3445 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
3446 if (!hdr) {
3447 nlmsg_free(msg);
3448 return;
3449 }
3450
3451 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3452 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3453 if (addr)
3454 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3455 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
3456 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
3457 if (tsc)
3458 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
3459
3460 if (genlmsg_end(msg, hdr) < 0) {
3461 nlmsg_free(msg);
3462 return;
3463 }
3464
3465 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
3466 return;
3467
3468 nla_put_failure:
3469 genlmsg_cancel(msg, hdr);
3470 nlmsg_free(msg);
3471}
3472
3433/* initialisation/exit functions */ 3473/* initialisation/exit functions */
3434 3474
3435int nl80211_init(void) 3475int nl80211_init(void)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 55686fc264f0..e4b92cccd157 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -23,5 +23,10 @@ extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
23extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 23extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
24 struct net_device *netdev, 24 struct net_device *netdev,
25 const u8 *buf, size_t len); 25 const u8 *buf, size_t len);
26extern void
27nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
28 struct net_device *netdev, const u8 *addr,
29 enum nl80211_key_type key_type,
30 int key_id, const u8 *tsc);
26 31
27#endif /* __NET_WIRELESS_NL80211_H */ 32#endif /* __NET_WIRELESS_NL80211_H */