Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=62da92fb75c346b503bca765fd1337e08771c9fe
Commit:     62da92fb75c346b503bca765fd1337e08771c9fe
Parent:     e8cbb4cbeb7642d179b01c35adf036ddb65f3dd0
Author:     Johannes Berg <[EMAIL PROTECTED]>
AuthorDate: Wed Dec 19 02:03:31 2007 +0100
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 14:59:50 2008 -0800

    mac80211: support getting key sequence counters via cfg80211
    
    This implements cfg80211's get_key() to allow retrieving the sequence
    counter for a TKIP or CCMP key from userspace. It also cleans up and
    documents the associated low-level driver interface.
    
    Signed-off-by: Johannes Berg <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 include/net/mac80211.h |   14 +++-----
 net/mac80211/cfg.c     |   85 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5b9e7a2..a762a75 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -647,9 +647,6 @@ struct ieee80211_key_conf {
        u8 key[0];
 };
 
-#define IEEE80211_SEQ_COUNTER_RX       0
-#define IEEE80211_SEQ_COUNTER_TX       1
-
 /**
  * enum set_key_cmd - key command
  *
@@ -996,9 +993,9 @@ enum ieee80211_erp_change_flags {
  *
  * @get_stats: return low-level statistics
  *
- * @get_sequence_counter: For devices that have internal sequence counters this
- *     callback allows mac80211 to access the current value of a counter.
- *     This callback seems not well-defined, tell us if you need it.
+ * @get_tkip_seq: If your device implements TKIP encryption in hardware this
+ *     callback should be provided to read the TKIP transmit IVs (both IV32
+ *     and IV16) for the given key from hardware.
  *
  * @set_rts_threshold: Configuration of RTS threshold (if device needs it)
  *
@@ -1073,9 +1070,8 @@ struct ieee80211_ops {
        int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
        int (*get_stats)(struct ieee80211_hw *hw,
                         struct ieee80211_low_level_stats *stats);
-       int (*get_sequence_counter)(struct ieee80211_hw *hw,
-                                   u8* addr, u8 keyidx, u8 txrx,
-                                   u32* iv32, u16* iv16);
+       void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
+                            u32 *iv32, u16 *iv16);
        int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
        int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
        int (*set_retry_limit)(struct ieee80211_hw *hw,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d49f7b5..4c1ce35 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1,7 +1,7 @@
 /*
  * mac80211 configuration hooks for cfg80211
  *
- * Copyright 2006      Johannes Berg <[EMAIL PROTECTED]>
+ * Copyright 2006, 2007        Johannes Berg <[EMAIL PROTECTED]>
  *
  * This file is GPLv2 as found in COPYING.
  */
@@ -175,6 +175,88 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct 
net_device *dev,
        return 0;
 }
 
+static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+                            u8 key_idx, u8 *mac_addr, void *cookie,
+                            void (*callback)(void *cookie,
+                                             struct key_params *params))
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct sta_info *sta = NULL;
+       u8 seq[6] = {0};
+       struct key_params params;
+       struct ieee80211_key *key;
+       u32 iv32;
+       u16 iv16;
+       int err = -ENOENT;
+
+       if (mac_addr) {
+               sta = sta_info_get(sdata->local, mac_addr);
+               if (!sta)
+                       goto out;
+
+               key = sta->key;
+       } else
+               key = sdata->keys[key_idx];
+
+       if (!key)
+               goto out;
+
+       memset(&params, 0, sizeof(params));
+
+       switch (key->conf.alg) {
+       case ALG_TKIP:
+               params.cipher = WLAN_CIPHER_SUITE_TKIP;
+
+               iv32 = key->u.tkip.iv32;
+               iv16 = key->u.tkip.iv16;
+
+               if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
+                   sdata->local->ops->get_tkip_seq)
+                       sdata->local->ops->get_tkip_seq(
+                               local_to_hw(sdata->local),
+                               key->conf.hw_key_idx,
+                               &iv32, &iv16);
+
+               seq[0] = iv16 & 0xff;
+               seq[1] = (iv16 >> 8) & 0xff;
+               seq[2] = iv32 & 0xff;
+               seq[3] = (iv32 >> 8) & 0xff;
+               seq[4] = (iv32 >> 16) & 0xff;
+               seq[5] = (iv32 >> 24) & 0xff;
+               params.seq = seq;
+               params.seq_len = 6;
+               break;
+       case ALG_CCMP:
+               params.cipher = WLAN_CIPHER_SUITE_CCMP;
+               seq[0] = key->u.ccmp.tx_pn[5];
+               seq[1] = key->u.ccmp.tx_pn[4];
+               seq[2] = key->u.ccmp.tx_pn[3];
+               seq[3] = key->u.ccmp.tx_pn[2];
+               seq[4] = key->u.ccmp.tx_pn[1];
+               seq[5] = key->u.ccmp.tx_pn[0];
+               params.seq = seq;
+               params.seq_len = 6;
+               break;
+       case ALG_WEP:
+               if (key->conf.keylen == 5)
+                       params.cipher = WLAN_CIPHER_SUITE_WEP40;
+               else
+                       params.cipher = WLAN_CIPHER_SUITE_WEP104;
+               break;
+       }
+
+       params.key = key->conf.key;
+       params.key_len = key->conf.keylen;
+
+       callback(cookie, &params);
+       err = 0;
+
+ out:
+       if (sta)
+               sta_info_put(sta);
+       return err;
+}
+
 static int ieee80211_config_default_key(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        u8 key_idx)
@@ -193,5 +275,6 @@ struct cfg80211_ops mac80211_config_ops = {
        .change_virtual_intf = ieee80211_change_iface,
        .add_key = ieee80211_add_key,
        .del_key = ieee80211_del_key,
+       .get_key = ieee80211_get_key,
        .set_default_key = ieee80211_config_default_key,
 };
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to