From ff1d2767d5a43c85f944e86a45284b721f66196c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 12 May 2005 22:54:16 -0400 Subject: Add HostAP wireless driver. Includes minor cleanups from Adrian Bunk . --- drivers/net/wireless/hostap/hostap_ap.h | 272 ++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 drivers/net/wireless/hostap/hostap_ap.h (limited to 'drivers/net/wireless/hostap/hostap_ap.h') diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h new file mode 100644 index 000000000000..10137f44436d --- /dev/null +++ b/drivers/net/wireless/hostap/hostap_ap.h @@ -0,0 +1,272 @@ +#ifndef HOSTAP_AP_H +#define HOSTAP_AP_H + +/* AP data structures for STAs */ + +/* maximum number of frames to buffer per STA */ +#define STA_MAX_TX_BUFFER 32 + +/* Flags used in skb->cb[6] to control how the packet is handled in TX path. + * skb->cb[0..5] must contain magic value 'hostap' to indicate that cb[6] is + * used. */ +#define AP_SKB_CB_MAGIC "hostap" +#define AP_SKB_CB_MAGIC_LEN 6 +#define AP_SKB_CB_BUFFERED_FRAME BIT(0) +#define AP_SKB_CB_ADD_MOREDATA BIT(1) + + +/* STA flags */ +#define WLAN_STA_AUTH BIT(0) +#define WLAN_STA_ASSOC BIT(1) +#define WLAN_STA_PS BIT(2) +#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */ +#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */ +#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is + * controlling whether STA is authorized to + * send and receive non-IEEE 802.1X frames + */ +#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ + +#define WLAN_RATE_1M BIT(0) +#define WLAN_RATE_2M BIT(1) +#define WLAN_RATE_5M5 BIT(2) +#define WLAN_RATE_11M BIT(3) +#define WLAN_RATE_COUNT 4 + +/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8, + * but some pre-standard IEEE 802.11g products use longer elements. */ +#define WLAN_SUPP_RATES_MAX 32 + +/* Try to increase TX rate after # successfully sent consecutive packets */ +#define WLAN_RATE_UPDATE_COUNT 50 + +/* Decrease TX rate after # consecutive dropped packets */ +#define WLAN_RATE_DECREASE_THRESHOLD 2 + +struct sta_info { + struct list_head list; + struct sta_info *hnext; /* next entry in hash table list */ + atomic_t users; /* number of users (do not remove if > 0) */ + struct proc_dir_entry *proc; + + u8 addr[6]; + u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */ + u32 flags; + u16 capability; + u16 listen_interval; /* or beacon_int for APs */ + u8 supported_rates[WLAN_SUPP_RATES_MAX]; + + unsigned long last_auth; + unsigned long last_assoc; + unsigned long last_rx; + unsigned long last_tx; + unsigned long rx_packets, tx_packets; + unsigned long rx_bytes, tx_bytes; + struct sk_buff_head tx_buf; + /* FIX: timeout buffers with an expiry time somehow derived from + * listen_interval */ + + s8 last_rx_silence; /* Noise in dBm */ + s8 last_rx_signal; /* Signal strength in dBm */ + u8 last_rx_rate; /* TX rate in 0.1 Mbps */ + u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */ + + u8 tx_supp_rates; /* bit field of supported TX rates */ + u8 tx_rate; /* current TX rate (in 0.1 Mbps) */ + u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */ + u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */ + u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */ + u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate) + */ + u32 tx_since_last_failure; + u32 tx_consecutive_exc; + + struct prism2_crypt_data *crypt; + + int ap; /* whether this station is an AP */ + + local_info_t *local; + +#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT + union { + struct { + char *challenge; /* shared key authentication + * challenge */ + } sta; + struct { + int ssid_len; + unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */ + int channel; + unsigned long last_beacon; /* last RX beacon time */ + } ap; + } u; + + struct timer_list timer; + enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next; +#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ +}; + + +#define MAX_STA_COUNT 1024 + +/* Maximum number of AIDs to use for STAs; must be 2007 or lower + * (8802.11 limitation) */ +#define MAX_AID_TABLE_SIZE 128 + +#define STA_HASH_SIZE 256 +#define STA_HASH(sta) (sta[5]) + + +/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY_SEC + * has passed since last received frame from the station, a nullfunc data + * frame is sent to the station. If this frame is not acknowledged and no other + * frames have been received, the station will be disassociated after + * AP_DISASSOC_DELAY. Similarily, a the station will be deauthenticated after + * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with + * max inactivity timer. */ +#define AP_MAX_INACTIVITY_SEC (5 * 60) +#define AP_DISASSOC_DELAY (HZ) +#define AP_DEAUTH_DELAY (HZ) + +/* ap_policy: whether to accept frames to/from other APs/IBSS */ +typedef enum { + AP_OTHER_AP_SKIP_ALL = 0, + AP_OTHER_AP_SAME_SSID = 1, + AP_OTHER_AP_ALL = 2, + AP_OTHER_AP_EVEN_IBSS = 3 +} ap_policy_enum; + +#define PRISM2_AUTH_OPEN BIT(0) +#define PRISM2_AUTH_SHARED_KEY BIT(1) + + +/* MAC address-based restrictions */ +struct mac_entry { + struct list_head list; + u8 addr[6]; +}; + +struct mac_restrictions { + enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy; + unsigned int entries; + struct list_head mac_list; + spinlock_t lock; +}; + + +struct add_sta_proc_data { + u8 addr[ETH_ALEN]; + struct add_sta_proc_data *next; +}; + + +typedef enum { WDS_ADD, WDS_DEL } wds_oper_type; +struct wds_oper_data { + wds_oper_type type; + u8 addr[ETH_ALEN]; + struct wds_oper_data *next; +}; + + +struct ap_data { + int initialized; /* whether ap_data has been initialized */ + local_info_t *local; + int bridge_packets; /* send packet to associated STAs directly to the + * wireless media instead of higher layers in the + * kernel */ + unsigned int bridged_unicast; /* number of unicast frames bridged on + * wireless media */ + unsigned int bridged_multicast; /* number of non-unicast frames + * bridged on wireless media */ + unsigned int tx_drop_nonassoc; /* number of unicast TX packets dropped + * because they were to an address that + * was not associated */ + int nullfunc_ack; /* use workaround for nullfunc frame ACKs */ + + spinlock_t sta_table_lock; + int num_sta; /* number of entries in sta_list */ + struct list_head sta_list; /* STA info list head */ + struct sta_info *sta_hash[STA_HASH_SIZE]; + + struct proc_dir_entry *proc; + + ap_policy_enum ap_policy; + unsigned int max_inactivity; + int autom_ap_wds; + + struct mac_restrictions mac_restrictions; /* MAC-based auth */ + int last_tx_rate; + + struct work_struct add_sta_proc_queue; + struct add_sta_proc_data *add_sta_proc_entries; + + struct work_struct wds_oper_queue; + struct wds_oper_data *wds_oper_entries; + + u16 tx_callback_idx; + +#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT + /* pointers to STA info; based on allocated AID or NULL if AID free + * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1 + * and so on + */ + struct sta_info *sta_aid[MAX_AID_TABLE_SIZE]; + + u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll; + + /* WEP operations for generating challenges to be used with shared key + * authentication */ + struct hostap_crypto_ops *crypt; + void *crypt_priv; +#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ +}; + + +void hostap_rx(struct net_device *dev, struct sk_buff *skb, + struct hostap_80211_rx_status *rx_stats); +void hostap_init_data(local_info_t *local); +void hostap_init_ap_proc(local_info_t *local); +void hostap_free_data(struct ap_data *ap); +void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver); + +typedef enum { + AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED, + AP_TX_CONTINUE_NOT_AUTHORIZED +} ap_tx_ret; +struct hostap_tx_data { + struct sk_buff *skb; + int host_encrypt; + struct prism2_crypt_data *crypt; + void *sta_ptr; +}; +ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); +void hostap_handle_sta_release(void *ptr); +void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb); +int hostap_update_sta_ps(local_info_t *local, + struct hostap_ieee80211_hdr *hdr); +typedef enum { + AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED +} ap_rx_ret; +ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, + struct sk_buff *skb, + struct hostap_80211_rx_status *rx_stats, + int wds); +int hostap_handle_sta_crypto(local_info_t *local, + struct hostap_ieee80211_hdr *hdr, + struct prism2_crypt_data **crypt, void **sta_ptr); +int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); +int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); +int hostap_add_sta(struct ap_data *ap, u8 *sta_addr); +int hostap_update_rx_stats(struct ap_data *ap, + struct hostap_ieee80211_hdr *hdr, + struct hostap_80211_rx_status *rx_stats); +void hostap_update_rates(local_info_t *local); +void hostap_add_wds_links(local_info_t *local); +void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type); + +#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT +void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap, + int resend); +#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ + +#endif /* HOSTAP_AP_H */ -- cgit v1.2.3 From 62fe7e378109537ff80971c5208e12d40bf88bee Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 30 Jul 2005 20:43:20 -0700 Subject: [PATCH] hostap: Replace crypto code with net/ieee80211 version Replace Host AP version of WEP, TKIP, CCMP implementation with net/ieee80211 that has more or less identical implementation (since it is based on the Host AP implementation). Remove Host AP specific implementation and modules from drivers/net/wireless/hostap. Signed-off-by: Jouni Malinen Signed-off-by: Jeff Garzik --- drivers/net/wireless/hostap/Kconfig | 33 -- drivers/net/wireless/hostap/Makefile | 3 - drivers/net/wireless/hostap/hostap.c | 12 +- drivers/net/wireless/hostap/hostap_80211.h | 2 +- drivers/net/wireless/hostap/hostap_80211_rx.c | 6 +- drivers/net/wireless/hostap/hostap_80211_tx.c | 2 +- drivers/net/wireless/hostap/hostap_ap.c | 13 +- drivers/net/wireless/hostap/hostap_ap.h | 9 +- drivers/net/wireless/hostap/hostap_crypt.c | 167 ------ drivers/net/wireless/hostap/hostap_crypt.h | 50 -- drivers/net/wireless/hostap/hostap_crypt_ccmp.c | 487 ----------------- drivers/net/wireless/hostap/hostap_crypt_tkip.c | 697 ------------------------ drivers/net/wireless/hostap/hostap_crypt_wep.c | 283 ---------- drivers/net/wireless/hostap/hostap_hw.c | 8 +- drivers/net/wireless/hostap/hostap_ioctl.c | 77 +-- drivers/net/wireless/hostap/hostap_wlan.h | 10 +- 16 files changed, 64 insertions(+), 1795 deletions(-) delete mode 100644 drivers/net/wireless/hostap/hostap_crypt.c delete mode 100644 drivers/net/wireless/hostap/hostap_crypt.h delete mode 100644 drivers/net/wireless/hostap/hostap_crypt_ccmp.c delete mode 100644 drivers/net/wireless/hostap/hostap_crypt_tkip.c delete mode 100644 drivers/net/wireless/hostap/hostap_crypt_wep.c (limited to 'drivers/net/wireless/hostap/hostap_ap.h') diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig index 2871e879b518..1445f3f2600f 100644 --- a/drivers/net/wireless/hostap/Kconfig +++ b/drivers/net/wireless/hostap/Kconfig @@ -7,9 +7,6 @@ config HOSTAP Host AP mode that allows the card to act as an IEEE 802.11 access point. - In addition, this includes generic IEEE 802.11 code, e.g., for - WEP/TKIP/CCMP encryption that can be shared with other drivers. - See for more information about the Host AP driver configuration and tools. This site includes information and tools (hostapd and wpa_supplicant) for WPA/WPA2 @@ -22,36 +19,6 @@ config HOSTAP The driver can be compiled as a module and it will be called "hostap.ko". -config HOSTAP_WEP - tristate "IEEE 802.11 WEP encryption" - depends on HOSTAP - select CRYPTO - ---help--- - Software implementation of IEEE 802.11 WEP encryption. - - This can be compiled as a modules and it will be called - "hostap_crypt_wep.ko". - -config HOSTAP_TKIP - tristate "IEEE 802.11 TKIP encryption" - depends on HOSTAP - select CRYPTO - ---help--- - Software implementation of IEEE 802.11 TKIP encryption. - - This can be compiled as a modules and it will be called - "hostap_crypt_tkip.ko". - -config HOSTAP_CCMP - tristate "IEEE 802.11 CCMP encryption" - depends on HOSTAP - select CRYPTO - ---help--- - Software implementation of IEEE 802.11 CCMP encryption. - - This can be compiled as a modules and it will be called - "hostap_crypt_ccmp.ko". - config HOSTAP_FIRMWARE bool "Support downloading firmware images with Host AP driver" depends on HOSTAP diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile index 087554075038..fc62235bfc24 100644 --- a/drivers/net/wireless/hostap/Makefile +++ b/drivers/net/wireless/hostap/Makefile @@ -1,7 +1,4 @@ obj-$(CONFIG_HOSTAP) += hostap.o -obj-$(CONFIG_HOSTAP_WEP) += hostap_crypt_wep.o -obj-$(CONFIG_HOSTAP_TKIP) += hostap_crypt_tkip.o -obj-$(CONFIG_HOSTAP_CCMP) += hostap_crypt_ccmp.o obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c index 75c75103f678..0858eba4575f 100644 --- a/drivers/net/wireless/hostap/hostap.c +++ b/drivers/net/wireless/hostap/hostap.c @@ -4,7 +4,7 @@ * * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen * - * Copyright (c) 2002-2004, Jouni Malinen + * Copyright (c) 2002-2005, Jouni Malinen * * 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 @@ -34,16 +34,12 @@ #include "hostap_80211.h" #include "hostap_ap.h" #include "hostap.h" -#include "hostap_crypt.h" MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("Host AP common routines"); MODULE_LICENSE("GPL"); MODULE_VERSION(PRISM2_VERSION); -/* Old hostap_crypt module is now part of hostap module. */ -#include "hostap_crypt.c" - #define TX_TIMEOUT (2 * HZ) #define PRISM2_MAX_FRAME_SIZE 2304 @@ -66,7 +62,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer); static int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct prism2_crypt_data ***crypt); + struct ieee80211_crypt_data ***crypt); static void ap_control_kickall(struct ap_data *ap); #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, @@ -1156,8 +1152,6 @@ struct proc_dir_entry *hostap_proc; static int __init hostap_init(void) { - hostap_crypto_init(); - if (proc_net != NULL) { hostap_proc = proc_mkdir("hostap", proc_net); if (!hostap_proc) @@ -1176,8 +1170,6 @@ static void __exit hostap_exit(void) hostap_proc = NULL; remove_proc_entry("hostap", proc_net); } - - hostap_crypto_deinit(); } diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h index 878151f40657..f3ad3445c72e 100644 --- a/drivers/net/wireless/hostap/hostap_80211.h +++ b/drivers/net/wireless/hostap/hostap_80211.h @@ -101,7 +101,7 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb); int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct prism2_crypt_data *crypt); + struct ieee80211_crypt_data *crypt); int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); #endif /* HOSTAP_80211_H */ diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index a0da9b9c890c..f4ca1e88f314 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -613,7 +613,7 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb) /* Called only as a tasklet (software IRQ) */ static inline int hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, - struct prism2_crypt_data *crypt) + struct ieee80211_crypt_data *crypt) { struct hostap_ieee80211_hdr *hdr; int res, hdrlen; @@ -652,7 +652,7 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, /* Called only as a tasklet (software IRQ) */ static inline int hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, - int keyidx, struct prism2_crypt_data *crypt) + int keyidx, struct ieee80211_crypt_data *crypt) { struct hostap_ieee80211_hdr *hdr; int res, hdrlen; @@ -698,7 +698,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, int from_assoc_ap = 0; u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; - struct prism2_crypt_data *crypt = NULL; + struct ieee80211_crypt_data *crypt = NULL; void *sta = NULL; int keyidx = 0; diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c index 52e81cd406fb..8f39871d6908 100644 --- a/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -284,7 +284,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Called only from software IRQ */ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct prism2_crypt_data *crypt) + struct ieee80211_crypt_data *crypt) { struct hostap_interface *iface; local_info_t *local; diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index f59912a0fb4c..6e109dfb43e7 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -2,7 +2,7 @@ * Intersil Prism2 driver with Host AP (software access point) support * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen * - * Copyright (c) 2002-2003, Jouni Malinen + * Copyright (c) 2002-2005, Jouni Malinen * * This file is to be included into hostap.c when S/W AP functionality is * compiled. @@ -1206,7 +1206,7 @@ static void prism2_check_tx_rates(struct sta_info *sta) static void ap_crypt_init(struct ap_data *ap) { - ap->crypt = hostap_get_crypto_ops("WEP"); + ap->crypt = ieee80211_get_crypto_ops("WEP"); if (ap->crypt) { if (ap->crypt->init) { @@ -1224,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap) if (ap->crypt == NULL) { printk(KERN_WARNING "AP could not initialize WEP: load module " - "hostap_crypt_wep.o\n"); + "ieee80211_crypt_wep.ko\n"); } } @@ -1293,7 +1293,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, u16 auth_alg, auth_transaction, status_code, *pos; u16 resp = WLAN_STATUS_SUCCESS, fc; struct sta_info *sta = NULL; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; char *txt = ""; len = skb->len - IEEE80211_MGMT_HDR_LEN; @@ -3058,7 +3058,8 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, /* Called only as a tasklet (software IRQ) */ int hostap_handle_sta_crypto(local_info_t *local, struct hostap_ieee80211_hdr *hdr, - struct prism2_crypt_data **crypt, void **sta_ptr) + struct ieee80211_crypt_data **crypt, + void **sta_ptr) { struct sta_info *sta; @@ -3206,7 +3207,7 @@ void hostap_update_rates(local_info_t *local) static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct prism2_crypt_data ***crypt) + struct ieee80211_crypt_data ***crypt) { struct sta_info *sta; diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h index 10137f44436d..137f78e4532b 100644 --- a/drivers/net/wireless/hostap/hostap_ap.h +++ b/drivers/net/wireless/hostap/hostap_ap.h @@ -81,7 +81,7 @@ struct sta_info { u32 tx_since_last_failure; u32 tx_consecutive_exc; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; int ap; /* whether this station is an AP */ @@ -216,7 +216,7 @@ struct ap_data { /* WEP operations for generating challenges to be used with shared key * authentication */ - struct hostap_crypto_ops *crypt; + struct ieee80211_crypto_ops *crypt; void *crypt_priv; #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ }; @@ -236,7 +236,7 @@ typedef enum { struct hostap_tx_data { struct sk_buff *skb; int host_encrypt; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; void *sta_ptr; }; ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); @@ -253,7 +253,8 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, int wds); int hostap_handle_sta_crypto(local_info_t *local, struct hostap_ieee80211_hdr *hdr, - struct prism2_crypt_data **crypt, void **sta_ptr); + struct ieee80211_crypt_data **crypt, + void **sta_ptr); int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); int hostap_add_sta(struct ap_data *ap, u8 *sta_addr); diff --git a/drivers/net/wireless/hostap/hostap_crypt.c b/drivers/net/wireless/hostap/hostap_crypt.c deleted file mode 100644 index de5390d502f1..000000000000 --- a/drivers/net/wireless/hostap/hostap_crypt.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Host AP crypto routines - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * 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. See README and COPYING for - * more details. - */ - -struct hostap_crypto_alg { - struct list_head list; - struct hostap_crypto_ops *ops; -}; - - -struct hostap_crypto { - struct list_head algs; - spinlock_t lock; -}; - -static struct hostap_crypto *hcrypt; - - -int hostap_register_crypto_ops(struct hostap_crypto_ops *ops) -{ - unsigned long flags; - struct hostap_crypto_alg *alg; - - if (hcrypt == NULL) - return -1; - - alg = (struct hostap_crypto_alg *) kmalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) - return -ENOMEM; - - memset(alg, 0, sizeof(*alg)); - alg->ops = ops; - - spin_lock_irqsave(&hcrypt->lock, flags); - list_add(&alg->list, &hcrypt->algs); - spin_unlock_irqrestore(&hcrypt->lock, flags); - - printk(KERN_DEBUG "hostap_crypt: registered algorithm '%s'\n", - ops->name); - - return 0; -} - - -int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops) -{ - unsigned long flags; - struct list_head *ptr; - struct hostap_crypto_alg *del_alg = NULL; - - if (hcrypt == NULL) - return -1; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct hostap_crypto_alg *alg = - (struct hostap_crypto_alg *) ptr; - if (alg->ops == ops) { - list_del(&alg->list); - del_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (del_alg) { - printk(KERN_DEBUG "hostap_crypt: unregistered algorithm " - "'%s'\n", ops->name); - kfree(del_alg); - } - - return del_alg ? 0 : -1; -} - - -struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name) -{ - unsigned long flags; - struct list_head *ptr; - struct hostap_crypto_alg *found_alg = NULL; - - if (hcrypt == NULL) - return NULL; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct hostap_crypto_alg *alg = - (struct hostap_crypto_alg *) ptr; - if (strcmp(alg->ops->name, name) == 0) { - found_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (found_alg) - return found_alg->ops; - else - return NULL; -} - - -static void * hostap_crypt_null_init(int keyidx) { return (void *) 1; } -static void hostap_crypt_null_deinit(void *priv) {} - -static struct hostap_crypto_ops hostap_crypt_null = { - .name = "NULL", - .init = hostap_crypt_null_init, - .deinit = hostap_crypt_null_deinit, - .encrypt_mpdu = NULL, - .decrypt_mpdu = NULL, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = NULL, - .get_key = NULL, - .extra_prefix_len = 0, - .extra_postfix_len = 0 -}; - - -static int __init hostap_crypto_init(void) -{ - hcrypt = (struct hostap_crypto *) kmalloc(sizeof(*hcrypt), GFP_KERNEL); - if (hcrypt == NULL) - return -ENOMEM; - - memset(hcrypt, 0, sizeof(*hcrypt)); - INIT_LIST_HEAD(&hcrypt->algs); - spin_lock_init(&hcrypt->lock); - - (void) hostap_register_crypto_ops(&hostap_crypt_null); - - return 0; -} - - -static void __exit hostap_crypto_deinit(void) -{ - struct list_head *ptr, *n; - - if (hcrypt == NULL) - return; - - for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; - ptr = n, n = ptr->next) { - struct hostap_crypto_alg *alg = - (struct hostap_crypto_alg *) ptr; - list_del(ptr); - printk(KERN_DEBUG "hostap_crypt: unregistered algorithm " - "'%s' (deinit)\n", alg->ops->name); - kfree(alg); - } - - kfree(hcrypt); -} - - -EXPORT_SYMBOL(hostap_register_crypto_ops); -EXPORT_SYMBOL(hostap_unregister_crypto_ops); -EXPORT_SYMBOL(hostap_get_crypto_ops); diff --git a/drivers/net/wireless/hostap/hostap_crypt.h b/drivers/net/wireless/hostap/hostap_crypt.h deleted file mode 100644 index 45d66d0323b0..000000000000 --- a/drivers/net/wireless/hostap/hostap_crypt.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef PRISM2_CRYPT_H -#define PRISM2_CRYPT_H - -struct hostap_crypto_ops { - char *name; - - /* init new crypto context (e.g., allocate private data space, - * select IV, etc.); returns NULL on failure or pointer to allocated - * private data on success */ - void * (*init)(int keyidx); - - /* deinitialize crypto context and free allocated private data */ - void (*deinit)(void *priv); - - /* encrypt/decrypt return < 0 on error or >= 0 on success. The return - * value from decrypt_mpdu is passed as the keyidx value for - * decrypt_msdu. skb must have enough head and tail room for the - * encryption; if not, error will be returned; these functions are - * called for all MPDUs (i.e., fragments). - */ - int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - - /* These functions are called for full MSDUs, i.e. full frames. - * These can be NULL if full MSDU operations are not needed. */ - int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, - void *priv); - - int (*set_key)(void *key, int len, u8 *seq, void *priv); - int (*get_key)(void *key, int len, u8 *seq, void *priv); - - /* procfs handler for printing out key information and possible - * statistics */ - char * (*print_stats)(char *p, void *priv); - - /* maximum number of bytes added by encryption; encrypt buf is - * allocated with extra_prefix_len bytes, copy of in_buf, and - * extra_postfix_len; encrypt need not use all this space, but - * the result must start at the beginning of the buffer and correct - * length must be returned */ - int extra_prefix_len, extra_postfix_len; -}; - - -int hostap_register_crypto_ops(struct hostap_crypto_ops *ops); -int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops); -struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name); - -#endif /* PRISM2_CRYPT_H */ diff --git a/drivers/net/wireless/hostap/hostap_crypt_ccmp.c b/drivers/net/wireless/hostap/hostap_crypt_ccmp.c deleted file mode 100644 index 9e18340f7a38..000000000000 --- a/drivers/net/wireless/hostap/hostap_crypt_ccmp.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Host AP crypt: host-based CCMP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - * - * 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. See README and COPYING for - * more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hostap_crypt.h" -#include "hostap_wlan.h" -#include "hostap_80211.h" - -#ifndef CONFIG_CRYPTO -#error CONFIG_CRYPTO is required to build this module. -#endif -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: CCMP"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -#define AES_BLOCK_LEN 16 -#define CCMP_HDR_LEN 8 -#define CCMP_MIC_LEN 8 -#define CCMP_TK_LEN 16 -#define CCMP_PN_LEN 6 - - -struct hostap_ccmp_data { - u8 key[CCMP_TK_LEN]; - int key_set; - - u8 tx_pn[CCMP_PN_LEN]; - u8 rx_pn[CCMP_PN_LEN]; - - u32 dot11RSNAStatsCCMPFormatErrors; - u32 dot11RSNAStatsCCMPReplays; - u32 dot11RSNAStatsCCMPDecryptErrors; - - int key_idx; - - struct crypto_tfm *tfm; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], - tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; - u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; -}; - - -void hostap_ccmp_aes_encrypt(struct crypto_tfm *tfm, - const u8 pt[16], u8 ct[16]) -{ - struct scatterlist src, dst; - - src.page = virt_to_page(pt); - src.offset = offset_in_page(pt); - src.length = AES_BLOCK_LEN; - - dst.page = virt_to_page(ct); - dst.offset = offset_in_page(ct); - dst.length = AES_BLOCK_LEN; - - crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN); -} - - -static void * hostap_ccmp_init(int key_idx) -{ - struct hostap_ccmp_data *priv; - - if (!try_module_get(THIS_MODULE)) - return NULL; - - priv = (struct hostap_ccmp_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) { - goto fail; - } - memset(priv, 0, sizeof(*priv)); - priv->key_idx = key_idx; - - priv->tfm = crypto_alloc_tfm("aes", 0); - if (priv->tfm == NULL) { - printk(KERN_DEBUG "hostap_crypt_ccmp: could not allocate " - "crypto API aes\n"); - goto fail; - } - - return priv; - -fail: - if (priv) { - if (priv->tfm) - crypto_free_tfm(priv->tfm); - kfree(priv); - } - module_put(THIS_MODULE); - return NULL; -} - - -static void hostap_ccmp_deinit(void *priv) -{ - struct hostap_ccmp_data *_priv = priv; - if (_priv && _priv->tfm) - crypto_free_tfm(_priv->tfm); - kfree(priv); - module_put(THIS_MODULE); -} - - -static inline void xor_block(u8 *b, u8 *a, size_t len) -{ - int i; - for (i = 0; i < len; i++) - b[i] ^= a[i]; -} - - -static void ccmp_init_blocks(struct crypto_tfm *tfm, - struct hostap_ieee80211_hdr *hdr, - u8 *pn, size_t dlen, u8 *b0, u8 *auth, - u8 *s0) -{ - u8 *pos, qc = 0; - size_t aad_len; - u16 fc; - int a4_included, qc_included; - u8 aad[2 * AES_BLOCK_LEN]; - - fc = le16_to_cpu(hdr->frame_control); - a4_included = ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS)); - qc_included = ((HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) && - (HOSTAP_FC_GET_STYPE(fc) & 0x08)); - aad_len = 22; - if (a4_included) - aad_len += 6; - if (qc_included) { - pos = (u8 *) &hdr->addr4; - if (a4_included) - pos += 6; - qc = *pos & 0x0f; - aad_len += 2; - } - - /* CCM Initial Block: - * Flag (Include authentication header, M=3 (8-octet MIC), - * L=1 (2-octet Dlen)) - * Nonce: 0x00 | A2 | PN - * Dlen */ - b0[0] = 0x59; - b0[1] = qc; - memcpy(b0 + 2, hdr->addr2, ETH_ALEN); - memcpy(b0 + 8, pn, CCMP_PN_LEN); - b0[14] = (dlen >> 8) & 0xff; - b0[15] = dlen & 0xff; - - /* AAD: - * FC with bits 4..6 and 11..13 masked to zero; 14 is always one - * A1 | A2 | A3 - * SC with bits 4..15 (seq#) masked to zero - * A4 (if present) - * QC (if present) - */ - pos = (u8 *) hdr; - aad[0] = 0; /* aad_len >> 8 */ - aad[1] = aad_len & 0xff; - aad[2] = pos[0] & 0x8f; - aad[3] = pos[1] & 0xc7; - memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); - pos = (u8 *) &hdr->seq_ctrl; - aad[22] = pos[0] & 0x0f; - aad[23] = 0; /* all bits masked */ - memset(aad + 24, 0, 8); - if (a4_included) - memcpy(aad + 24, hdr->addr4, ETH_ALEN); - if (qc_included) { - aad[a4_included ? 30 : 24] = qc; - /* rest of QC masked */ - } - - /* Start with the first block and AAD */ - hostap_ccmp_aes_encrypt(tfm, b0, auth); - xor_block(auth, aad, AES_BLOCK_LEN); - hostap_ccmp_aes_encrypt(tfm, auth, auth); - xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - hostap_ccmp_aes_encrypt(tfm, auth, auth); - b0[0] &= 0x07; - b0[14] = b0[15] = 0; - hostap_ccmp_aes_encrypt(tfm, b0, s0); -} - - -static int hostap_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_ccmp_data *key = priv; - int data_len, i, blocks, last, len; - u8 *pos, *mic; - struct hostap_ieee80211_hdr *hdr; - u8 *b0 = key->tx_b0; - u8 *b = key->tx_b; - u8 *e = key->tx_e; - u8 *s0 = key->tx_s0; - - if (skb_headroom(skb) < CCMP_HDR_LEN || - skb_tailroom(skb) < CCMP_MIC_LEN || - skb->len < hdr_len) - return -1; - - data_len = skb->len - hdr_len; - pos = skb_push(skb, CCMP_HDR_LEN); - memmove(pos, pos + CCMP_HDR_LEN, hdr_len); - pos += hdr_len; - mic = skb_put(skb, CCMP_MIC_LEN); - - i = CCMP_PN_LEN - 1; - while (i >= 0) { - key->tx_pn[i]++; - if (key->tx_pn[i] != 0) - break; - i--; - } - - *pos++ = key->tx_pn[5]; - *pos++ = key->tx_pn[4]; - *pos++ = 0; - *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = key->tx_pn[3]; - *pos++ = key->tx_pn[2]; - *pos++ = key->tx_pn[1]; - *pos++ = key->tx_pn[0]; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); - - blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Authentication */ - xor_block(b, pos, len); - hostap_ccmp_aes_encrypt(key->tfm, b, b); - /* Encryption, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - hostap_ccmp_aes_encrypt(key->tfm, b0, e); - xor_block(pos, e, len); - pos += len; - } - - for (i = 0; i < CCMP_MIC_LEN; i++) - mic[i] = b[i] ^ s0[i]; - - return 0; -} - - -static int hostap_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_ccmp_data *key = priv; - u8 keyidx, *pos; - struct hostap_ieee80211_hdr *hdr; - u8 *b0 = key->rx_b0; - u8 *b = key->rx_b; - u8 *a = key->rx_a; - u8 pn[6]; - int i, blocks, last, len; - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; - u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; - - if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { - key->dot11RSNAStatsCCMPFormatErrors++; - return -1; - } - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from " MACSTR "\n", MAC2STR(hdr->addr2)); - } - key->dot11RSNAStatsCCMPFormatErrors++; - return -2; - } - keyidx >>= 6; - if (key->key_idx != keyidx) { - printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame " - "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv); - return -6; - } - if (!key->key_set) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from " MACSTR - " with keyid=%d that does not have a configured" - " key\n", MAC2STR(hdr->addr2), keyidx); - } - return -3; - } - - pn[0] = pos[7]; - pn[1] = pos[6]; - pn[2] = pos[5]; - pn[3] = pos[4]; - pn[4] = pos[1]; - pn[5] = pos[0]; - pos += 8; - - if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=" MACSTR - " previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - MAC2STR(hdr->addr2), MAC2STR(key->rx_pn), - MAC2STR(pn)); - } - key->dot11RSNAStatsCCMPReplays++; - return -4; - } - - ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); - xor_block(mic, b, CCMP_MIC_LEN); - - blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Decrypt, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - hostap_ccmp_aes_encrypt(key->tfm, b0, b); - xor_block(pos, b, len); - /* Authentication */ - xor_block(a, pos, len); - hostap_ccmp_aes_encrypt(key->tfm, a, a); - pos += len; - } - - if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - MACSTR "\n", MAC2STR(hdr->addr2)); - } - key->dot11RSNAStatsCCMPDecryptErrors++; - return -5; - } - - memcpy(key->rx_pn, pn, CCMP_PN_LEN); - - /* Remove hdr and MIC */ - memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); - skb_pull(skb, CCMP_HDR_LEN); - skb_trim(skb, skb->len - CCMP_MIC_LEN); - - return keyidx; -} - - -static int hostap_ccmp_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_ccmp_data *data = priv; - int keyidx; - struct crypto_tfm *tfm = data->tfm; - - keyidx = data->key_idx; - memset(data, 0, sizeof(*data)); - data->key_idx = keyidx; - data->tfm = tfm; - if (len == CCMP_TK_LEN) { - memcpy(data->key, key, CCMP_TK_LEN); - data->key_set = 1; - if (seq) { - data->rx_pn[0] = seq[5]; - data->rx_pn[1] = seq[4]; - data->rx_pn[2] = seq[3]; - data->rx_pn[3] = seq[2]; - data->rx_pn[4] = seq[1]; - data->rx_pn[5] = seq[0]; - } - crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN); - } else if (len == 0) { - data->key_set = 0; - } else - return -1; - - return 0; -} - - -static int hostap_ccmp_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_ccmp_data *data = priv; - - if (len < CCMP_TK_LEN) - return -1; - - if (!data->key_set) - return 0; - memcpy(key, data->key, CCMP_TK_LEN); - - if (seq) { - seq[0] = data->tx_pn[5]; - seq[1] = data->tx_pn[4]; - seq[2] = data->tx_pn[3]; - seq[3] = data->tx_pn[2]; - seq[4] = data->tx_pn[1]; - seq[5] = data->tx_pn[0]; - } - - return CCMP_TK_LEN; -} - - -static char * hostap_ccmp_print_stats(char *p, void *priv) -{ - struct hostap_ccmp_data *ccmp = priv; - p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - MAC2STR(ccmp->tx_pn), MAC2STR(ccmp->rx_pn), - ccmp->dot11RSNAStatsCCMPFormatErrors, - ccmp->dot11RSNAStatsCCMPReplays, - ccmp->dot11RSNAStatsCCMPDecryptErrors); - - return p; -} - - -static struct hostap_crypto_ops hostap_crypt_ccmp = { - .name = "CCMP", - .init = hostap_ccmp_init, - .deinit = hostap_ccmp_deinit, - .encrypt_mpdu = hostap_ccmp_encrypt, - .decrypt_mpdu = hostap_ccmp_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = hostap_ccmp_set_key, - .get_key = hostap_ccmp_get_key, - .print_stats = hostap_ccmp_print_stats, - .extra_prefix_len = CCMP_HDR_LEN, - .extra_postfix_len = CCMP_MIC_LEN -}; - - -static int __init hostap_crypto_ccmp_init(void) -{ - if (hostap_register_crypto_ops(&hostap_crypt_ccmp) < 0) - return -1; - - return 0; -} - - -static void __exit hostap_crypto_ccmp_exit(void) -{ - hostap_unregister_crypto_ops(&hostap_crypt_ccmp); -} - - -module_init(hostap_crypto_ccmp_init); -module_exit(hostap_crypto_ccmp_exit); diff --git a/drivers/net/wireless/hostap/hostap_crypt_tkip.c b/drivers/net/wireless/hostap/hostap_crypt_tkip.c deleted file mode 100644 index fcf1a014f4ac..000000000000 --- a/drivers/net/wireless/hostap/hostap_crypt_tkip.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Host AP crypt: host-based TKIP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - * - * 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. See README and COPYING for - * more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hostap_crypt.h" -#include "hostap_wlan.h" -#include "hostap_80211.h" -#include "hostap_config.h" - -#ifndef CONFIG_CRYPTO -#error CONFIG_CRYPTO is required to build this module. -#endif -#include -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: TKIP"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -struct hostap_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - - struct crypto_tfm *tfm_arc4; - struct crypto_tfm *tfm_michael; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; -}; - - -static void * hostap_tkip_init(int key_idx) -{ - struct hostap_tkip_data *priv; - - if (!try_module_get(THIS_MODULE)) - return NULL; - - priv = (struct hostap_tkip_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) - goto fail; - memset(priv, 0, sizeof(*priv)); - priv->key_idx = key_idx; - - priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); - if (priv->tfm_arc4 == NULL) { - printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate " - "crypto API arc4\n"); - goto fail; - } - - priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0); - if (priv->tfm_michael == NULL) { - printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); - goto fail; - } - - return priv; - -fail: - if (priv) { - if (priv->tfm_michael) - crypto_free_tfm(priv->tfm_michael); - if (priv->tfm_arc4) - crypto_free_tfm(priv->tfm_arc4); - kfree(priv); - } - module_put(THIS_MODULE); - return NULL; -} - - -static void hostap_tkip_deinit(void *priv) -{ - struct hostap_tkip_data *_priv = priv; - if (_priv && _priv->tfm_michael) - crypto_free_tfm(_priv->tfm_michael); - if (_priv && _priv->tfm_arc4) - crypto_free_tfm(_priv->tfm_arc4); - kfree(priv); - module_put(THIS_MODULE); -} - - -static inline u16 RotR1(u16 val) -{ - return (val >> 1) | (val << 15); -} - - -static inline u8 Lo8(u16 val) -{ - return val & 0xff; -} - - -static inline u8 Hi8(u16 val) -{ - return val >> 8; -} - - -static inline u16 Lo16(u32 val) -{ - return val & 0xffff; -} - - -static inline u16 Hi16(u32 val) -{ - return val >> 16; -} - - -static inline u16 Mk16(u8 hi, u8 lo) -{ - return lo | (((u16) hi) << 8); -} - - -static inline u16 Mk16_le(u16 *v) -{ - return le16_to_cpu(*v); -} - - -static const u16 Sbox[256] = -{ - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, -}; - - -static inline u16 _S_(u16 v) -{ - u16 t = Sbox[Hi8(v)]; - return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); -} - - -#define PHASE1_LOOP_COUNT 8 - -static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) -{ - int i, j; - - /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ - TTAK[0] = Lo16(IV32); - TTAK[1] = Hi16(IV32); - TTAK[2] = Mk16(TA[1], TA[0]); - TTAK[3] = Mk16(TA[3], TA[2]); - TTAK[4] = Mk16(TA[5], TA[4]); - - for (i = 0; i < PHASE1_LOOP_COUNT; i++) { - j = 2 * (i & 1); - TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); - TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); - TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); - TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); - TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; - } -} - - -static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, - u16 IV16) -{ - /* Make temporary area overlap WEP seed so that the final copy can be - * avoided on little endian hosts. */ - u16 *PPK = (u16 *) &WEPSeed[4]; - - /* Step 1 - make copy of TTAK and bring in TSC */ - PPK[0] = TTAK[0]; - PPK[1] = TTAK[1]; - PPK[2] = TTAK[2]; - PPK[3] = TTAK[3]; - PPK[4] = TTAK[4]; - PPK[5] = TTAK[4] + IV16; - - /* Step 2 - 96-bit bijective mixing using S-box */ - PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0])); - PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2])); - PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4])); - PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6])); - PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8])); - PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10])); - - PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12])); - PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14])); - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - - /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value - * WEPSeed[0..2] is transmitted as WEP IV */ - WEPSeed[0] = Hi8(IV16); - WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; - WEPSeed[2] = Lo8(IV16); - WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1); - -#ifdef __BIG_ENDIAN - { - int i; - for (i = 0; i < 6; i++) - PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); - } -#endif -} - - -static int hostap_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - int len; - u8 rc4key[16], *pos, *icv; - struct hostap_ieee80211_hdr *hdr; - u32 crc; - struct scatterlist sg; - - if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - if (!tkey->tx_phase1_done) { - tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, - tkey->tx_iv32); - tkey->tx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); - - len = skb->len - hdr_len; - pos = skb_push(skb, 8); - memmove(pos, pos + 8, hdr_len); - pos += hdr_len; - icv = skb_put(skb, 4); - - *pos++ = rc4key[0]; - *pos++ = rc4key[1]; - *pos++ = rc4key[2]; - *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = tkey->tx_iv32 & 0xff; - *pos++ = (tkey->tx_iv32 >> 8) & 0xff; - *pos++ = (tkey->tx_iv32 >> 16) & 0xff; - *pos++ = (tkey->tx_iv32 >> 24) & 0xff; - - crc = ~crc32_le(~0, pos, len); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = len + 4; - crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); - - tkey->tx_iv16++; - if (tkey->tx_iv16 == 0) { - tkey->tx_phase1_done = 0; - tkey->tx_iv32++; - } - - return 0; -} - - -static int hostap_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - u8 rc4key[16]; - u8 keyidx, *pos, icv[4]; - u32 iv32; - u16 iv16; - struct hostap_ieee80211_hdr *hdr; - u32 crc; - struct scatterlist sg; - int plen; - - if (skb->len < hdr_len + 8 + 4) - return -1; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from " MACSTR "\n", MAC2STR(hdr->addr2)); - } - return -2; - } - keyidx >>= 6; - if (tkey->key_idx != keyidx) { - printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame " - "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv); - return -6; - } - if (!tkey->key_set) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from " MACSTR - " with keyid=%d that does not have a configured" - " key\n", MAC2STR(hdr->addr2), keyidx); - } - return -3; - } - iv16 = (pos[0] << 8) | pos[2]; - iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); - pos += 8; - - if (iv32 < tkey->rx_iv32 || - (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=" MACSTR - " previous TSC %08x%04x received TSC " - "%08x%04x\n", MAC2STR(hdr->addr2), - tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); - } - tkey->dot11RSNAStatsTKIPReplays++; - return -4; - } - - if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { - tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); - tkey->rx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); - - plen = skb->len - hdr_len - 12; - - crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = plen + 4; - crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - if (memcmp(icv, pos + plen, 4) != 0) { - if (iv32 != tkey->rx_iv32) { - /* Previously cached Phase1 result was already lost, so - * it needs to be recalculated for the next packet. */ - tkey->rx_phase1_done = 0; - } - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - MACSTR "\n", MAC2STR(hdr->addr2)); - } - tkey->dot11RSNAStatsTKIPICVErrors++; - return -5; - } - - /* Update real counters only after Michael MIC verification has - * completed */ - tkey->rx_iv32_new = iv32; - tkey->rx_iv16_new = iv16; - - /* Remove IV and ICV */ - memmove(skb->data + 8, skb->data, hdr_len); - skb_pull(skb, 8); - skb_trim(skb, skb->len - 4); - - return keyidx; -} - - -static int michael_mic(struct hostap_tkip_data *tkey, u8 *key, u8 *hdr, - u8 *data, size_t data_len, u8 *mic) -{ - struct scatterlist sg[2]; - - if (tkey->tfm_michael == NULL) { - printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); - return -1; - } - sg[0].page = virt_to_page(hdr); - sg[0].offset = offset_in_page(hdr); - sg[0].length = 16; - - sg[1].page = virt_to_page(data); - sg[1].offset = offset_in_page(data); - sg[1].length = data_len; - - crypto_digest_init(tkey->tfm_michael); - crypto_digest_setkey(tkey->tfm_michael, key, 8); - crypto_digest_update(tkey->tfm_michael, sg, 2); - crypto_digest_final(tkey->tfm_michael, mic); - - return 0; -} - - -static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) -{ - struct hostap_ieee80211_hdr *hdr11; - - hdr11 = (struct hostap_ieee80211_hdr *) skb->data; - switch (le16_to_cpu(hdr11->frame_control) & - (WLAN_FC_FROMDS | WLAN_FC_TODS)) { - case WLAN_FC_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - case WLAN_FC_FROMDS: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ - break; - case WLAN_FC_FROMDS | WLAN_FC_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ - break; - case 0: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - } - - hdr[12] = 0; /* priority */ - hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ -} - - -static int hostap_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - u8 *pos; - - if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { - printk(KERN_DEBUG "Invalid packet for Michael MIC add " - "(tailroom=%d hdr_len=%d skb->len=%d)\n", - skb_tailroom(skb), hdr_len, skb->len); - return -1; - } - - michael_mic_hdr(skb, tkey->tx_hdr); - pos = skb_put(skb, 8); - if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) - return -1; - - return 0; -} - - -static void hostap_michael_mic_failure(struct net_device *dev, - struct hostap_ieee80211_hdr *hdr, - int keyidx) -{ - union iwreq_data wrqu; - char buf[128]; - - /* TODO: needed parameters: count, keyid, key type, src address, TSC */ - sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" - MACSTR ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC2STR(hdr->addr2)); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); -} - - -static int hostap_michael_mic_verify(struct sk_buff *skb, int keyidx, - int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - u8 mic[8]; - - if (!tkey->key_set) - return -1; - - michael_mic_hdr(skb, tkey->rx_hdr); - if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) - return -1; - if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct hostap_ieee80211_hdr *hdr; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from " MACSTR " keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", MAC2STR(hdr->addr2), - keyidx); - if (skb->dev) - hostap_michael_mic_failure(skb->dev, hdr, keyidx); - tkey->dot11RSNAStatsTKIPLocalMICFailures++; - return -1; - } - - /* Update TSC counters for RX now that the packet verification has - * completed. */ - tkey->rx_iv32 = tkey->rx_iv32_new; - tkey->rx_iv16 = tkey->rx_iv16_new; - - skb_trim(skb, skb->len - 8); - - return 0; -} - - -static int hostap_tkip_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - int keyidx; - struct crypto_tfm *tfm = tkey->tfm_michael; - struct crypto_tfm *tfm2 = tkey->tfm_arc4; - - keyidx = tkey->key_idx; - memset(tkey, 0, sizeof(*tkey)); - tkey->key_idx = keyidx; - tkey->tfm_michael = tfm; - tkey->tfm_arc4 = tfm2; - if (len == TKIP_KEY_LEN) { - memcpy(tkey->key, key, TKIP_KEY_LEN); - tkey->key_set = 1; - tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ - if (seq) { - tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | - (seq[3] << 8) | seq[2]; - tkey->rx_iv16 = (seq[1] << 8) | seq[0]; - } - } else if (len == 0) { - tkey->key_set = 0; - } else - return -1; - - return 0; -} - - -static int hostap_tkip_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - - if (len < TKIP_KEY_LEN) - return -1; - - if (!tkey->key_set) - return 0; - memcpy(key, tkey->key, TKIP_KEY_LEN); - - if (seq) { - /* Return the sequence number of the last transmitted frame. */ - u16 iv16 = tkey->tx_iv16; - u32 iv32 = tkey->tx_iv32; - if (iv16 == 0) - iv32--; - iv16--; - seq[0] = tkey->tx_iv16; - seq[1] = tkey->tx_iv16 >> 8; - seq[2] = tkey->tx_iv32; - seq[3] = tkey->tx_iv32 >> 8; - seq[4] = tkey->tx_iv32 >> 16; - seq[5] = tkey->tx_iv32 >> 24; - } - - return TKIP_KEY_LEN; -} - - -static char * hostap_tkip_print_stats(char *p, void *priv) -{ - struct hostap_tkip_data *tkip = priv; - p += sprintf(p, "key[%d] alg=TKIP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "replays=%d icv_errors=%d local_mic_failures=%d\n", - tkip->key_idx, tkip->key_set, - (tkip->tx_iv32 >> 24) & 0xff, - (tkip->tx_iv32 >> 16) & 0xff, - (tkip->tx_iv32 >> 8) & 0xff, - tkip->tx_iv32 & 0xff, - (tkip->tx_iv16 >> 8) & 0xff, - tkip->tx_iv16 & 0xff, - (tkip->rx_iv32 >> 24) & 0xff, - (tkip->rx_iv32 >> 16) & 0xff, - (tkip->rx_iv32 >> 8) & 0xff, - tkip->rx_iv32 & 0xff, - (tkip->rx_iv16 >> 8) & 0xff, - tkip->rx_iv16 & 0xff, - tkip->dot11RSNAStatsTKIPReplays, - tkip->dot11RSNAStatsTKIPICVErrors, - tkip->dot11RSNAStatsTKIPLocalMICFailures); - return p; -} - - -static struct hostap_crypto_ops hostap_crypt_tkip = { - .name = "TKIP", - .init = hostap_tkip_init, - .deinit = hostap_tkip_deinit, - .encrypt_mpdu = hostap_tkip_encrypt, - .decrypt_mpdu = hostap_tkip_decrypt, - .encrypt_msdu = hostap_michael_mic_add, - .decrypt_msdu = hostap_michael_mic_verify, - .set_key = hostap_tkip_set_key, - .get_key = hostap_tkip_get_key, - .print_stats = hostap_tkip_print_stats, - .extra_prefix_len = 4 + 4 /* IV + ExtIV */, - .extra_postfix_len = 8 + 4 /* MIC + ICV */ -}; - - -static int __init hostap_crypto_tkip_init(void) -{ - if (hostap_register_crypto_ops(&hostap_crypt_tkip) < 0) - return -1; - - return 0; -} - - -static void __exit hostap_crypto_tkip_exit(void) -{ - hostap_unregister_crypto_ops(&hostap_crypt_tkip); -} - - -module_init(hostap_crypto_tkip_init); -module_exit(hostap_crypto_tkip_exit); diff --git a/drivers/net/wireless/hostap/hostap_crypt_wep.c b/drivers/net/wireless/hostap/hostap_crypt_wep.c deleted file mode 100644 index 66c403f17631..000000000000 --- a/drivers/net/wireless/hostap/hostap_crypt_wep.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Host AP crypt: host-based WEP encryption implementation for Host AP driver - * - * Copyright (c) 2002-2004, Jouni Malinen - * - * 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. See README and COPYING for - * more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hostap_crypt.h" -#include "hostap_config.h" - -#ifndef CONFIG_CRYPTO -#error CONFIG_CRYPTO is required to build this module. -#endif -#include -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: WEP"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -struct prism2_wep_data { - u32 iv; -#define WEP_KEY_LEN 13 - u8 key[WEP_KEY_LEN + 1]; - u8 key_len; - u8 key_idx; - struct crypto_tfm *tfm; -}; - - -static void * prism2_wep_init(int keyidx) -{ - struct prism2_wep_data *priv; - - if (!try_module_get(THIS_MODULE)) - return NULL; - - priv = (struct prism2_wep_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) - goto fail; - memset(priv, 0, sizeof(*priv)); - priv->key_idx = keyidx; - - priv->tfm = crypto_alloc_tfm("arc4", 0); - if (priv->tfm == NULL) { - printk(KERN_DEBUG "hostap_crypt_wep: could not allocate " - "crypto API arc4\n"); - goto fail; - } - - /* start WEP IV from a random value */ - get_random_bytes(&priv->iv, 4); - - return priv; - -fail: - if (priv) { - if (priv->tfm) - crypto_free_tfm(priv->tfm); - kfree(priv); - } - module_put(THIS_MODULE); - return NULL; -} - - -static void prism2_wep_deinit(void *priv) -{ - struct prism2_wep_data *_priv = priv; - if (_priv && _priv->tfm) - crypto_free_tfm(_priv->tfm); - kfree(priv); - module_put(THIS_MODULE); -} - - -/* Perform WEP encryption on given skb that has at least 4 bytes of headroom - * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, - * so the payload length increases with 8 bytes. - * - * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) - */ -static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 crc, klen, len; - u8 key[WEP_KEY_LEN + 3]; - u8 *pos, *icv; - struct scatterlist sg; - - if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - len = skb->len - hdr_len; - pos = skb_push(skb, 4); - memmove(pos, pos + 4, hdr_len); - pos += hdr_len; - - klen = 3 + wep->key_len; - - wep->iv++; - - /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key - * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) - * can be used to speedup attacks, so avoid using them. */ - if ((wep->iv & 0xff00) == 0xff00) { - u8 B = (wep->iv >> 16) & 0xff; - if (B >= 3 && B < klen) - wep->iv += 0x0100; - } - - /* Prepend 24-bit IV to RC4 key and TX frame */ - *pos++ = key[0] = (wep->iv >> 16) & 0xff; - *pos++ = key[1] = (wep->iv >> 8) & 0xff; - *pos++ = key[2] = wep->iv & 0xff; - *pos++ = wep->key_idx << 6; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Append little-endian CRC32 and encrypt it to produce ICV */ - crc = ~crc32_le(~0, pos, len); - icv = skb_put(skb, 4); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - crypto_cipher_setkey(wep->tfm, key, klen); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = len + 4; - crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4); - - return 0; -} - - -/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of - * the frame: IV (4 bytes), encrypted payload (including SNAP header), - * ICV (4 bytes). len includes both IV and ICV. - * - * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on - * failure. If frame is OK, IV and ICV will be removed. - */ -static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 crc, klen, plen; - u8 key[WEP_KEY_LEN + 3]; - u8 keyidx, *pos, icv[4]; - struct scatterlist sg; - - if (skb->len < hdr_len + 8) - return -1; - - pos = skb->data + hdr_len; - key[0] = *pos++; - key[1] = *pos++; - key[2] = *pos++; - keyidx = *pos++ >> 6; - if (keyidx != wep->key_idx) - return -1; - - klen = 3 + wep->key_len; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Apply RC4 to data and compute CRC32 over decrypted data */ - plen = skb->len - hdr_len - 8; - - crypto_cipher_setkey(wep->tfm, key, klen); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = plen + 4; - crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - if (memcmp(icv, pos + plen, 4) != 0) { - /* ICV mismatch - drop frame */ - return -2; - } - - /* Remove IV and ICV */ - memmove(skb->data + 4, skb->data, hdr_len); - skb_pull(skb, 4); - skb_trim(skb, skb->len - 4); - - return 0; -} - - -static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < 0 || len > WEP_KEY_LEN) - return -1; - - memcpy(wep->key, key, len); - wep->key_len = len; - - return 0; -} - - -static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < wep->key_len) - return -1; - - memcpy(key, wep->key, wep->key_len); - - return wep->key_len; -} - - -static char * prism2_wep_print_stats(char *p, void *priv) -{ - struct prism2_wep_data *wep = priv; - p += sprintf(p, "key[%d] alg=WEP len=%d\n", - wep->key_idx, wep->key_len); - return p; -} - - -static struct hostap_crypto_ops hostap_crypt_wep = { - .name = "WEP", - .init = prism2_wep_init, - .deinit = prism2_wep_deinit, - .encrypt_mpdu = prism2_wep_encrypt, - .decrypt_mpdu = prism2_wep_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = prism2_wep_set_key, - .get_key = prism2_wep_get_key, - .print_stats = prism2_wep_print_stats, - .extra_prefix_len = 4 /* IV */, - .extra_postfix_len = 4 /* ICV */ -}; - - -static int __init hostap_crypto_wep_init(void) -{ - if (hostap_register_crypto_ops(&hostap_crypt_wep) < 0) - return -1; - - return 0; -} - - -static void __exit hostap_crypto_wep_exit(void) -{ - hostap_unregister_crypto_ops(&hostap_crypt_wep); -} - - -module_init(hostap_crypto_wep_init); -module_exit(hostap_crypto_wep_exit); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 72a8a19ad8c0..dc31f5351b36 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -4,7 +4,7 @@ * * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen * - * Copyright (c) 2002-2004, Jouni Malinen + * Copyright (c) 2002-2005, Jouni Malinen * * 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 @@ -2967,11 +2967,11 @@ static void prism2_check_sta_fw_version(local_info_t *local) static void prism2_crypt_deinit_entries(local_info_t *local, int force) { struct list_head *ptr, *n; - struct prism2_crypt_data *entry; + struct ieee80211_crypt_data *entry; for (ptr = local->crypt_deinit_list.next, n = ptr->next; ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct prism2_crypt_data, list); + entry = list_entry(ptr, struct ieee80211_crypt_data, list); if (atomic_read(&entry->refcnt) != 0 && !force) continue; @@ -3531,7 +3531,7 @@ static void prism2_free_local_data(struct net_device *dev) prism2_callback(local, PRISM2_CALLBACK_DISABLE); for (i = 0; i < WEP_KEYS; i++) { - struct prism2_crypt_data *crypt = local->crypt[i]; + struct ieee80211_crypt_data *crypt = local->crypt[i]; if (crypt) { if (crypt->ops) crypt->ops->deinit(crypt->priv); diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index bbed1e634583..f892aa87b13e 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -115,9 +115,9 @@ static int prism2_get_name(struct net_device *dev, static void prism2_crypt_delayed_deinit(local_info_t *local, - struct prism2_crypt_data **crypt) + struct ieee80211_crypt_data **crypt) { - struct prism2_crypt_data *tmp; + struct ieee80211_crypt_data *tmp; unsigned long flags; tmp = *crypt; @@ -147,7 +147,7 @@ static int prism2_ioctl_siwencode(struct net_device *dev, struct hostap_interface *iface; local_info_t *local; int i; - struct prism2_crypt_data **crypt; + struct ieee80211_crypt_data **crypt; iface = netdev_priv(dev); local = iface->local; @@ -175,18 +175,19 @@ static int prism2_ioctl_siwencode(struct net_device *dev, } if (*crypt == NULL) { - struct prism2_crypt_data *new_crypt; + struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = (struct prism2_crypt_data *) - kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; - memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); - new_crypt->ops = hostap_get_crypto_ops("WEP"); + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) { - request_module("hostap_crypt_wep"); - new_crypt->ops = hostap_get_crypto_ops("WEP"); + request_module("ieee80211_crypt_wep"); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); } if (new_crypt->ops) new_crypt->priv = new_crypt->ops->init(i); @@ -251,7 +252,7 @@ static int prism2_ioctl_giwencode(struct net_device *dev, local_info_t *local; int i, len; u16 val; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; iface = netdev_priv(dev); local = iface->local; @@ -3259,8 +3260,8 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, local_info_t *local = iface->local; struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; int i, ret = 0; - struct hostap_crypto_ops *ops; - struct prism2_crypt_data **crypt; + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; void *sta_ptr; u8 *addr; const char *alg, *module; @@ -3308,15 +3309,15 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, switch (ext->alg) { case IW_ENCODE_ALG_WEP: alg = "WEP"; - module = "hostap_crypt_wep"; + module = "ieee80211_crypt_wep"; break; case IW_ENCODE_ALG_TKIP: alg = "TKIP"; - module = "hostap_crypt_tkip"; + module = "ieee80211_crypt_tkip"; break; case IW_ENCODE_ALG_CCMP: alg = "CCMP"; - module = "hostap_crypt_ccmp"; + module = "ieee80211_crypt_ccmp"; break; default: printk(KERN_DEBUG "%s: unsupported algorithm %d\n", @@ -3325,10 +3326,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, goto done; } - ops = hostap_get_crypto_ops(alg); + ops = ieee80211_get_crypto_ops(alg); if (ops == NULL) { request_module(module); - ops = hostap_get_crypto_ops(alg); + ops = ieee80211_get_crypto_ops(alg); } if (ops == NULL) { printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", @@ -3347,17 +3348,18 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, } if (*crypt == NULL || (*crypt)->ops != ops) { - struct prism2_crypt_data *new_crypt; + struct ieee80211_crypt_data *new_crypt; prism2_crypt_delayed_deinit(local, crypt); - new_crypt = (struct prism2_crypt_data *) - kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } - memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; new_crypt->priv = new_crypt->ops->init(i); if (new_crypt->priv == NULL) { @@ -3436,7 +3438,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev, { struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; - struct prism2_crypt_data **crypt; + struct ieee80211_crypt_data **crypt; void *sta_ptr; int max_key_len, i; struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; @@ -3505,8 +3507,8 @@ static int prism2_ioctl_set_encryption(local_info_t *local, int param_len) { int ret = 0; - struct hostap_crypto_ops *ops; - struct prism2_crypt_data **crypt; + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; void *sta_ptr; param->u.crypt.err = 0; @@ -3544,16 +3546,16 @@ static int prism2_ioctl_set_encryption(local_info_t *local, goto done; } - ops = hostap_get_crypto_ops(param->u.crypt.alg); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { - request_module("hostap_crypt_wep"); - ops = hostap_get_crypto_ops(param->u.crypt.alg); + request_module("ieee80211_crypt_wep"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { - request_module("hostap_crypt_tkip"); - ops = hostap_get_crypto_ops(param->u.crypt.alg); + request_module("ieee80211_crypt_tkip"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { - request_module("hostap_crypt_ccmp"); - ops = hostap_get_crypto_ops(param->u.crypt.alg); + request_module("ieee80211_crypt_ccmp"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } if (ops == NULL) { printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", @@ -3568,17 +3570,18 @@ static int prism2_ioctl_set_encryption(local_info_t *local, local->host_decrypt = local->host_encrypt = 1; if (*crypt == NULL || (*crypt)->ops != ops) { - struct prism2_crypt_data *new_crypt; + struct ieee80211_crypt_data *new_crypt; prism2_crypt_delayed_deinit(local, crypt); - new_crypt = (struct prism2_crypt_data *) - kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } - memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); if (new_crypt->priv == NULL) { @@ -3642,7 +3645,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local, struct prism2_hostapd_param *param, int param_len) { - struct prism2_crypt_data **crypt; + struct ieee80211_crypt_data **crypt; void *sta_ptr; int max_key_len; diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index f215a22e8fee..a632d45f334d 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -2,7 +2,6 @@ #define HOSTAP_WLAN_H #include "hostap_config.h" -#include "hostap_crypt.h" #include "hostap_common.h" #define MAX_PARM_DEVICES 8 @@ -534,13 +533,6 @@ struct prism2_frag_entry { }; -struct prism2_crypt_data { - struct list_head list; /* delayed deletion list */ - struct hostap_crypto_ops *ops; - void *priv; - atomic_t refcnt; -}; - struct hostap_cmd_queue { struct list_head list; wait_queue_head_t compl; @@ -765,7 +757,7 @@ struct local_info { #define WEP_KEYS 4 #define WEP_KEY_LEN 13 - struct prism2_crypt_data *crypt[WEP_KEYS]; + struct ieee80211_crypt_data *crypt[WEP_KEYS]; int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ struct timer_list crypt_deinit_timer; struct list_head crypt_deinit_list; -- cgit v1.2.3 From 5bee720fd7fa5ed4eade96058acd3a684da30932 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 14 Aug 2005 19:08:39 -0700 Subject: [PATCH] hostap: Fix skb->cb use for TX meta data Old AP mode code for power saving was using skb->cb for couple of flags before the more generic 802.11 TX code started using the same buffer for struct hostap_skb_tx_data. This resulted in the power save code corrupting the magic value in beginning of the buffer and TX code dropping the power saved packets because of this for the case where STAs send PS-Poll frames with PwrMgmt flag set. This patch modifies the power save code to use the same struct hostap_skb_tx_data as rest of the TX path in order to avoid corrupting the data in skb->cb. In addition, this patch reorders fields in the structure and makes them use smaller types in order to make the structure fit in skb->cb on 64-bit hosts. Signed-off-by: Jouni Malinen Signed-off-by: Jeff Garzik --- drivers/net/wireless/hostap/hostap_80211_tx.c | 6 ++++-- drivers/net/wireless/hostap/hostap_ap.c | 30 +++++++++++++-------------- drivers/net/wireless/hostap/hostap_ap.h | 9 -------- drivers/net/wireless/hostap/hostap_wlan.h | 17 +++++++++------ 4 files changed, 30 insertions(+), 32 deletions(-) (limited to 'drivers/net/wireless/hostap/hostap_ap.h') diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c index 8f39871d6908..cfb3ecc783fa 100644 --- a/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -226,7 +226,8 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev) meta = (struct hostap_skb_tx_data *) skb->cb; memset(meta, 0, sizeof(*meta)); meta->magic = HOSTAP_SKB_TX_DATA_MAGIC; - meta->wds = use_wds; + if (use_wds) + meta->flags |= HOSTAP_TX_FLAGS_WDS; meta->ethertype = ethertype; meta->iface = iface; @@ -410,7 +411,8 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) case AP_TX_CONTINUE_NOT_AUTHORIZED: if (local->ieee_802_1x && HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && - meta->ethertype != ETH_P_PAE && !meta->wds) { + meta->ethertype != ETH_P_PAE && + !(meta->flags & HOSTAP_TX_FLAGS_WDS)) { printk(KERN_DEBUG "%s: dropped frame to unauthorized " "port (IEEE 802.1X): ethertype=0x%04x\n", dev->name, meta->ethertype); diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index c9aeefcd7612..550855a91509 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -1840,6 +1840,8 @@ static void ap_handle_dropped_data(local_info_t *local, static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta, struct sk_buff *skb) { + struct hostap_skb_tx_data *meta; + if (!(sta->flags & WLAN_STA_PS)) { /* Station has moved to non-PS mode, so send all buffered * frames using normal device queue. */ @@ -1849,11 +1851,11 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta, /* add a flag for hostap_handle_sta_tx() to know that this skb should * be passed through even though STA is using PS */ - memcpy(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN); - skb->cb[AP_SKB_CB_MAGIC_LEN] = AP_SKB_CB_BUFFERED_FRAME; + meta = (struct hostap_skb_tx_data *) skb->cb; + meta->flags |= HOSTAP_TX_FLAGS_BUFFERED_FRAME; if (!skb_queue_empty(&sta->tx_buf)) { /* indicate to STA that more frames follow */ - skb->cb[AP_SKB_CB_MAGIC_LEN] |= AP_SKB_CB_ADD_MOREDATA; + meta->flags |= HOSTAP_TX_FLAGS_ADD_MOREDATA; } dev_queue_xmit(skb); } @@ -2707,7 +2709,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) atomic_inc(&sta->users); spin_unlock(&local->ap->sta_table_lock); - if (local->iw_mode == IW_MODE_MASTER && sta == NULL && !meta->wds && + if (local->iw_mode == IW_MODE_MASTER && sta == NULL && + !(meta->flags & HOSTAP_TX_FLAGS_WDS) && meta->iface->type != HOSTAP_INTERFACE_MASTER && meta->iface->type != HOSTAP_INTERFACE_AP) { #if 0 @@ -2743,18 +2746,15 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) if (!(sta->flags & WLAN_STA_PS)) goto out; - if (memcmp(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN) == 0) { - if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_ADD_MOREDATA) { - /* indicate to STA that more frames follow */ - hdr->frame_control |= - __constant_cpu_to_le16(WLAN_FC_MOREDATA); - } + if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) { + /* indicate to STA that more frames follow */ + hdr->frame_control |= __constant_cpu_to_le16(WLAN_FC_MOREDATA); + } - if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_BUFFERED_FRAME) { - /* packet was already buffered and now send due to - * PS poll, so do not rebuffer it */ - goto out; - } + if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) { + /* packet was already buffered and now send due to + * PS poll, so do not rebuffer it */ + goto out; } if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) { diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h index 137f78e4532b..512abc2c83a3 100644 --- a/drivers/net/wireless/hostap/hostap_ap.h +++ b/drivers/net/wireless/hostap/hostap_ap.h @@ -6,15 +6,6 @@ /* maximum number of frames to buffer per STA */ #define STA_MAX_TX_BUFFER 32 -/* Flags used in skb->cb[6] to control how the packet is handled in TX path. - * skb->cb[0..5] must contain magic value 'hostap' to indicate that cb[6] is - * used. */ -#define AP_SKB_CB_MAGIC "hostap" -#define AP_SKB_CB_MAGIC_LEN 6 -#define AP_SKB_CB_BUFFERED_FRAME BIT(0) -#define AP_SKB_CB_ADD_MOREDATA BIT(1) - - /* STA flags */ #define WLAN_STA_AUTH BIT(0) #define WLAN_STA_ASSOC BIT(1) diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index a632d45f334d..6f5bea8a5c23 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -941,16 +941,21 @@ struct hostap_interface { #define HOSTAP_SKB_TX_DATA_MAGIC 0xf08a36a2 -/* TX meta data - stored in skb->cb buffer, so this must be not increase over - * 48-byte limit */ +/* + * TX meta data - stored in skb->cb buffer, so this must not be increased over + * the 40-byte limit + */ struct hostap_skb_tx_data { - unsigned int magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ - int rate; /* transmit rate */ + u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ + u8 rate; /* transmit rate */ +#define HOSTAP_TX_FLAGS_WDS BIT(0) +#define HOSTAP_TX_FLAGS_BUFFERED_FRAME BIT(1) +#define HOSTAP_TX_FLAGS_ADD_MOREDATA BIT(2) + u8 flags; /* HOSTAP_TX_FLAGS_* */ + u16 tx_cb_idx; struct hostap_interface *iface; unsigned long jiffies; /* queueing timestamp */ - int wds; unsigned short ethertype; - int tx_cb_idx; }; -- cgit v1.2.3 From c0f72ca8e4f1b459b5582c1c8dcaf7e53151f069 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 14 Aug 2005 19:08:43 -0700 Subject: [PATCH] hostap: Replace hostap_ieee80211_hdr with ieee80211_hdr Replace hostap-specific struct hostap_ieee80211_hdr with struct ieee80211_hdr from net/ieee80211.h. Signed-off-by: Jouni Malinen Signed-off-by: Jeff Garzik --- drivers/net/wireless/hostap/hostap_80211.h | 11 --- drivers/net/wireless/hostap/hostap_80211_rx.c | 60 ++++++++-------- drivers/net/wireless/hostap/hostap_80211_tx.c | 36 +++++----- drivers/net/wireless/hostap/hostap_ap.c | 99 +++++++++++++-------------- drivers/net/wireless/hostap/hostap_ap.h | 9 +-- drivers/net/wireless/hostap/hostap_hw.c | 2 - 6 files changed, 98 insertions(+), 119 deletions(-) (limited to 'drivers/net/wireless/hostap/hostap_ap.h') diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h index f3ad3445c72e..bf506f50d722 100644 --- a/drivers/net/wireless/hostap/hostap_80211.h +++ b/drivers/net/wireless/hostap/hostap_80211.h @@ -1,17 +1,6 @@ #ifndef HOSTAP_80211_H #define HOSTAP_80211_H -struct hostap_ieee80211_hdr { - u16 frame_control; - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - u16 seq_ctrl; - u8 addr4[6]; -} __attribute__ ((packed)); - - struct hostap_ieee80211_mgmt { u16 frame_control; u16 duration; diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index f4ca1e88f314..5363400a5da2 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -6,10 +6,10 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats) { - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u16 fc; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d " "jiffies=%ld\n", @@ -19,7 +19,7 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, if (skb->len < 2) return; - fc = le16_to_cpu(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_ctl); printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s", fc, HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc), fc & WLAN_FC_TODS ? " [ToDS]" : "", @@ -31,7 +31,7 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, } printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id), - le16_to_cpu(hdr->seq_ctrl)); + le16_to_cpu(hdr->seq_ctl)); printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR, MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3)); @@ -51,7 +51,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, int hdrlen, phdrlen, head_need, tail_need; u16 fc; int prism_header, ret; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; iface = netdev_priv(dev); local = iface->local; @@ -70,8 +70,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, phdrlen = 0; } - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); if (type == PRISM2_RX_MGMT && (fc & WLAN_FC_PVER)) { printk(KERN_DEBUG "%s: dropped management frame with header " @@ -215,21 +215,21 @@ prism2_frag_cache_find(local_info_t *local, unsigned int seq, /* Called only as a tasklet (software IRQ) */ static struct sk_buff * -prism2_frag_cache_get(local_info_t *local, struct hostap_ieee80211_hdr *hdr) +prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr) { struct sk_buff *skb = NULL; u16 sc; unsigned int frag, seq; struct prism2_frag_entry *entry; - sc = le16_to_cpu(hdr->seq_ctrl); + sc = le16_to_cpu(hdr->seq_ctl); frag = WLAN_GET_SEQ_FRAG(sc); seq = WLAN_GET_SEQ_SEQ(sc) >> 4; if (frag == 0) { /* Reserve enough space to fit maximum frame length */ skb = dev_alloc_skb(local->dev->mtu + - sizeof(struct hostap_ieee80211_hdr) + + sizeof(struct ieee80211_hdr) + 8 /* LLC */ + 2 /* alignment */ + 8 /* WEP */ + ETH_ALEN /* WDS */); @@ -267,13 +267,13 @@ prism2_frag_cache_get(local_info_t *local, struct hostap_ieee80211_hdr *hdr) /* Called only as a tasklet (software IRQ) */ static int prism2_frag_cache_invalidate(local_info_t *local, - struct hostap_ieee80211_hdr *hdr) + struct ieee80211_hdr *hdr) { u16 sc; unsigned int seq; struct prism2_frag_entry *entry; - sc = le16_to_cpu(hdr->seq_ctrl); + sc = le16_to_cpu(hdr->seq_ctl); seq = WLAN_GET_SEQ_SEQ(sc) >> 4; entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1); @@ -441,7 +441,7 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb, u16 stype) { if (local->iw_mode == IW_MODE_MASTER) { - hostap_update_sta_ps(local, (struct hostap_ieee80211_hdr *) + hostap_update_sta_ps(local, (struct ieee80211_hdr *) skb->data); } @@ -519,7 +519,7 @@ static inline struct net_device *prism2_rx_get_wds(local_info_t *local, static inline int -hostap_rx_frame_wds(local_info_t *local, struct hostap_ieee80211_hdr *hdr, +hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr, u16 fc, struct net_device **wds) { /* FIX: is this really supposed to accept WDS frames only in Master @@ -577,14 +577,14 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb) { struct net_device *dev = local->dev; u16 fc, ethertype; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u8 *pos; if (skb->len < 24) return 0; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); /* check that the frame is unicast frame to us */ if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_TODS && @@ -615,14 +615,14 @@ static inline int hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, struct ieee80211_crypt_data *crypt) { - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; int res, hdrlen; if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) return 0; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); + hdr = (struct ieee80211_hdr *) skb->data; + hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); if (local->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) { @@ -654,14 +654,14 @@ static inline int hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, int keyidx, struct ieee80211_crypt_data *crypt) { - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; int res, hdrlen; if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) return 0; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); + hdr = (struct ieee80211_hdr *) skb->data; + hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); atomic_inc(&crypt->refcnt); res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); @@ -685,7 +685,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, { struct hostap_interface *iface; local_info_t *local; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; size_t hdrlen; u16 fc, type, stype, sc; struct net_device *wds = NULL; @@ -712,16 +712,16 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, dev = local->ddev; iface = netdev_priv(dev); - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; stats = hostap_get_stats(dev); if (skb->len < 10) goto rx_dropped; - fc = le16_to_cpu(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_ctl); type = HOSTAP_FC_GET_TYPE(fc); stype = HOSTAP_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctrl); + sc = le16_to_cpu(hdr->seq_ctl); frag = WLAN_GET_SEQ_FRAG(sc); hdrlen = hostap_80211_get_hdrlen(fc); @@ -883,7 +883,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, if (local->host_decrypt && (fc & WLAN_FC_ISWEP) && (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0) goto rx_dropped; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; /* skb: hdr + (possibly fragmented) plaintext payload */ @@ -935,7 +935,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, /* this was the last fragment and the frame will be * delivered, so remove skb from fragment cache */ skb = frag_skb; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; prism2_frag_cache_invalidate(local, hdr); } @@ -946,7 +946,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt)) goto rx_dropped; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; if (crypt && !(fc & WLAN_FC_ISWEP) && !local->open_wep) { if (local->ieee_802_1x && hostap_is_eapol_frame(local, skb)) { diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c index cfb3ecc783fa..2b38a5230992 100644 --- a/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -1,9 +1,9 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb) { - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u16 fc; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n", name, skb->len, jiffies); @@ -11,7 +11,7 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb) if (skb->len < 2) return; - fc = le16_to_cpu(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_ctl); printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s", fc, HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc), fc & WLAN_FC_TODS ? " [ToDS]" : "", @@ -23,7 +23,7 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb) } printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id), - le16_to_cpu(hdr->seq_ctrl)); + le16_to_cpu(hdr->seq_ctl)); printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR, MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3)); @@ -41,7 +41,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev) struct hostap_interface *iface; local_info_t *local; int need_headroom, need_tailroom = 0; - struct hostap_ieee80211_hdr hdr; + struct ieee80211_hdr hdr; u16 fc, ethertype = 0; enum { WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME @@ -180,7 +180,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev) memcpy(&hdr.addr3, local->bssid, ETH_ALEN); } - hdr.frame_control = cpu_to_le16(fc); + hdr.frame_ctl = cpu_to_le16(fc); skb_pull(skb, skip_header_bytes); need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len; @@ -244,7 +244,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) struct hostap_interface *iface; local_info_t *local; struct hostap_skb_tx_data *meta; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u16 fc; iface = netdev_priv(dev); @@ -266,8 +266,8 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) meta->iface = iface; if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) { - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); if (HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && HOSTAP_FC_GET_STYPE(fc) == WLAN_FC_STYPE_DATA) { u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN + @@ -289,7 +289,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, { struct hostap_interface *iface; local_info_t *local; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u16 fc; int hdr_len, res; @@ -303,7 +303,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, if (local->tkip_countermeasures && crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " "TX packet to " MACSTR "\n", @@ -325,8 +325,8 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, return NULL; } - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); hdr_len = hostap_80211_get_hdrlen(fc); /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so @@ -360,7 +360,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) ap_tx_ret tx_ret; struct hostap_skb_tx_data *meta; int no_encrypt = 0; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; iface = netdev_priv(dev); local = iface->local; @@ -403,8 +403,8 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_ret = hostap_handle_sta_tx(local, &tx); skb = tx.skb; meta = (struct hostap_skb_tx_data *) skb->cb; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); switch (tx_ret) { case AP_TX_CONTINUE: break; @@ -445,7 +445,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) /* remove special version from the frame header */ fc &= ~WLAN_FC_PVER; - hdr->frame_control = cpu_to_le16(fc); + hdr->frame_ctl = cpu_to_le16(fc); } if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA) { @@ -467,7 +467,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Add ISWEP flag both for firmware and host based encryption */ fc |= WLAN_FC_ISWEP; - hdr->frame_control = cpu_to_le16(fc); + hdr->frame_ctl = cpu_to_le16(fc); } else if (local->drop_unencrypted && HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && meta->ethertype != ETH_P_PAE) { diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 550855a91509..5cd8d23c30ee 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -590,22 +590,22 @@ static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data) { struct ap_data *ap = data; u16 fc; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; if (!ap->local->hostapd || !ap->local->apdev) { dev_kfree_skb(skb); return; } - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); /* Pass the TX callback frame to the hostapd; use 802.11 header version * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */ fc &= ~WLAN_FC_PVER; fc |= ok ? BIT(1) : BIT(0); - hdr->frame_control = cpu_to_le16(fc); + hdr->frame_ctl = cpu_to_le16(fc); skb->dev = ap->local->apdev; skb_pull(skb, hostap_80211_get_hdrlen(fc)); @@ -622,7 +622,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data) { struct ap_data *ap = data; struct net_device *dev = ap->local->dev; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u16 fc, *pos, auth_alg, auth_transaction, status; struct sta_info *sta = NULL; char *txt = NULL; @@ -632,8 +632,8 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data) return; } - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_AUTH || skb->len < IEEE80211_MGMT_HDR_LEN + 6) { @@ -691,7 +691,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) { struct ap_data *ap = data; struct net_device *dev = ap->local->dev; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u16 fc, *pos, status; struct sta_info *sta = NULL; char *txt = NULL; @@ -701,8 +701,8 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) return; } - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || (HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ASSOC_RESP && HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_REASSOC_RESP) || @@ -756,12 +756,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data) { struct ap_data *ap = data; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; struct sta_info *sta; if (skb->len < 24) goto fail; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; if (ok) { spin_lock(&ap->sta_table_lock); sta = ap_get_sta(ap, hdr->addr1); @@ -917,7 +917,7 @@ static void prism2_send_mgmt(struct net_device *dev, { struct hostap_interface *iface; local_info_t *local; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; u16 fc; struct sk_buff *skb; struct hostap_skb_tx_data *meta; @@ -943,7 +943,7 @@ static void prism2_send_mgmt(struct net_device *dev, fc = (type << 2) | (subtype << 4); hdrlen = hostap_80211_get_hdrlen(fc); - hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, hdrlen); + hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen); if (body) memcpy(skb_put(skb, body_len), body, body_len); @@ -967,7 +967,7 @@ static void prism2_send_mgmt(struct net_device *dev, memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */ } - hdr->frame_control = cpu_to_le16(fc); + hdr->frame_ctl = cpu_to_le16(fc); meta = (struct hostap_skb_tx_data *) skb->cb; memset(meta, 0, sizeof(*meta)); @@ -1284,8 +1284,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats) { struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; size_t hdrlen; struct ap_data *ap = local->ap; char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL; @@ -1298,7 +1297,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, len = skb->len - IEEE80211_MGMT_HDR_LEN; - fc = le16_to_cpu(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_ctl); hdrlen = hostap_80211_get_hdrlen(fc); if (len < 6) { @@ -1498,8 +1497,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats, int reassoc) { struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; char body[12], *p, *lpos; int len, left; u16 *pos; @@ -1706,8 +1704,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats) { struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN); int len; u16 reason_code, *pos; @@ -1748,8 +1745,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats) { struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; char *body = skb->data + IEEE80211_MGMT_HDR_LEN; int len; u16 reason_code, *pos; @@ -1787,7 +1783,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb, /* Called only as a scheduled task for pending AP frames. */ static void ap_handle_data_nullfunc(local_info_t *local, - struct hostap_ieee80211_hdr *hdr) + struct ieee80211_hdr *hdr) { struct net_device *dev = local->dev; @@ -1804,7 +1800,7 @@ static void ap_handle_data_nullfunc(local_info_t *local, /* Called only as a scheduled task for pending AP frames. */ static void ap_handle_dropped_data(local_info_t *local, - struct hostap_ieee80211_hdr *hdr) + struct ieee80211_hdr *hdr) { struct net_device *dev = local->dev; struct sta_info *sta; @@ -1863,7 +1859,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta, /* Called only as a scheduled task for pending AP frames. */ static void handle_pspoll(local_info_t *local, - struct hostap_ieee80211_hdr *hdr, + struct ieee80211_hdr *hdr, struct hostap_80211_rx_status *rx_stats) { struct net_device *dev = local->dev; @@ -1874,7 +1870,7 @@ static void handle_pspoll(local_info_t *local, PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR " PWRMGT=%d\n", MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), - !!(le16_to_cpu(hdr->frame_control) & WLAN_FC_PWRMGT)); + !!(le16_to_cpu(hdr->frame_ctl) & WLAN_FC_PWRMGT)); if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR @@ -1982,8 +1978,7 @@ static void handle_wds_oper_queue(void *data) static void handle_beacon(local_info_t *local, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats) { - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; char *body = skb->data + IEEE80211_MGMT_HDR_LEN; int len, left; u16 *pos, beacon_int, capability; @@ -2141,12 +2136,12 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb, struct net_device *dev = local->dev; #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ u16 fc, type, stype; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; /* FIX: should give skb->len to handler functions and check that the * buffer is long enough */ - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); type = HOSTAP_FC_GET_TYPE(fc); stype = HOSTAP_FC_GET_STYPE(fc); @@ -2259,7 +2254,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb, struct hostap_interface *iface; local_info_t *local; u16 fc; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; iface = netdev_priv(dev); local = iface->local; @@ -2269,8 +2264,8 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb, local->stats.rx_packets++; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL && HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && @@ -2290,7 +2285,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb, static void schedule_packet_send(local_info_t *local, struct sta_info *sta) { struct sk_buff *skb; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; struct hostap_80211_rx_status rx_stats; if (skb_queue_empty(&sta->tx_buf)) @@ -2303,10 +2298,10 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta) return; } - hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, 16); + hdr = (struct ieee80211_hdr *) skb_put(skb, 16); /* Generate a fake pspoll frame to start packet delivery */ - hdr->frame_control = __constant_cpu_to_le16( + hdr->frame_ctl = __constant_cpu_to_le16( (WLAN_FC_TYPE_CTRL << 2) | (WLAN_FC_STYPE_PSPOLL << 4)); memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN); memcpy(hdr->addr2, sta->addr, ETH_ALEN); @@ -2686,7 +2681,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) struct sta_info *sta = NULL; struct sk_buff *skb = tx->skb; int set_tim, ret; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; struct hostap_skb_tx_data *meta; meta = (struct hostap_skb_tx_data *) skb->cb; @@ -2695,7 +2690,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) meta->iface->type == HOSTAP_INTERFACE_STA) goto out; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; if (hdr->addr1[0] & 0x01) { /* broadcast/multicast frame - no AP related processing */ @@ -2748,7 +2743,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) { /* indicate to STA that more frames follow */ - hdr->frame_control |= __constant_cpu_to_le16(WLAN_FC_MOREDATA); + hdr->frame_ctl |= __constant_cpu_to_le16(WLAN_FC_MOREDATA); } if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) { @@ -2821,10 +2816,10 @@ void hostap_handle_sta_release(void *ptr) void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb) { struct sta_info *sta; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; struct hostap_skb_tx_data *meta; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; meta = (struct hostap_skb_tx_data *) skb->cb; spin_lock(&local->ap->sta_table_lock); @@ -2890,8 +2885,8 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta, /* Called only as a tasklet (software IRQ). Called for each RX frame to update - * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */ -int hostap_update_sta_ps(local_info_t *local, struct hostap_ieee80211_hdr *hdr) + * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */ +int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr) { struct sta_info *sta; u16 fc; @@ -2905,7 +2900,7 @@ int hostap_update_sta_ps(local_info_t *local, struct hostap_ieee80211_hdr *hdr) if (!sta) return -1; - fc = le16_to_cpu(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_ctl); hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT, HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc)); @@ -2924,14 +2919,14 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, int ret; struct sta_info *sta; u16 fc, type, stype; - struct hostap_ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr; if (local->ap == NULL) return AP_RX_CONTINUE; - hdr = (struct hostap_ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_ctl); type = HOSTAP_FC_GET_TYPE(fc); stype = HOSTAP_FC_GET_STYPE(fc); @@ -3057,7 +3052,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, /* Called only as a tasklet (software IRQ) */ int hostap_handle_sta_crypto(local_info_t *local, - struct hostap_ieee80211_hdr *hdr, + struct ieee80211_hdr *hdr, struct ieee80211_crypt_data **crypt, void **sta_ptr) { @@ -3159,7 +3154,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr) /* Called only as a tasklet (software IRQ) */ int hostap_update_rx_stats(struct ap_data *ap, - struct hostap_ieee80211_hdr *hdr, + struct ieee80211_hdr *hdr, struct hostap_80211_rx_status *rx_stats) { struct sta_info *sta; diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h index 512abc2c83a3..816a52bcea8f 100644 --- a/drivers/net/wireless/hostap/hostap_ap.h +++ b/drivers/net/wireless/hostap/hostap_ap.h @@ -233,8 +233,7 @@ struct hostap_tx_data { ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); void hostap_handle_sta_release(void *ptr); void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb); -int hostap_update_sta_ps(local_info_t *local, - struct hostap_ieee80211_hdr *hdr); +int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr); typedef enum { AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED } ap_rx_ret; @@ -242,15 +241,13 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats, int wds); -int hostap_handle_sta_crypto(local_info_t *local, - struct hostap_ieee80211_hdr *hdr, +int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr, struct ieee80211_crypt_data **crypt, void **sta_ptr); int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); int hostap_add_sta(struct ap_data *ap, u8 *sta_addr); -int hostap_update_rx_stats(struct ap_data *ap, - struct hostap_ieee80211_hdr *hdr, +int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr, struct hostap_80211_rx_status *rx_stats); void hostap_update_rates(local_info_t *local); void hostap_add_wds_links(local_info_t *local); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 30c215106714..03c81b824242 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -1817,7 +1817,6 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev) struct hostap_interface *iface; local_info_t *local; struct hfa384x_tx_frame txdesc; - struct hostap_ieee80211_hdr *hdr; struct hostap_skb_tx_data *meta; int hdr_len, data_len, idx, res, ret = -1; u16 tx_control, fc; @@ -1826,7 +1825,6 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev) local = iface->local; meta = (struct hostap_skb_tx_data *) skb->cb; - hdr = (struct hostap_ieee80211_hdr *) skb->data; prism2_callback(local, PRISM2_CALLBACK_TX_START); -- cgit v1.2.3