📄 ieee80211_module.c
字号:
/******************************************************************************* Copyright(c) 2004 Intel Corporation. All rights reserved. Portions of this file are based on the WEP enablement code provided by the Host AP project hostap-drivers v0.1.3 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen <jkmaline@cc.hut.fi> Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> Some management frame logic and misc modifications for the rtl8180-sa2004 driver by Andrea Merello <andreamrl@tiscali.it> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The full GNU General Public License is included in this distribution in the file called LICENSE. Contact Information: James P. Ketrenos <ipw2100-admin@linux.intel.com> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Please note that this file has been modified, so please don't report bugs to the contact above uless you are sure it is really a bug in the *ORIGINAL* code. *******************************************************************************/#include <linux/init.h>#include <linux/compiler.h>#include <linux/config.h>#include <linux/errno.h>#include <linux/if_arp.h>#include <linux/in6.h>#include <linux/in.h>#include <linux/ip.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/netdevice.h>#include <linux/pci.h>#include <linux/proc_fs.h>#include <linux/skbuff.h>#include <linux/slab.h>#include <linux/tcp.h>#include <linux/types.h>#include <linux/version.h>#include <linux/wireless.h>#include <linux/etherdevice.h>#include <asm/uaccess.h>#include "ieee802_11.h"#include "ieee80211.h"#define MODULE_NAME "ieee80211-r8180"MODULE_DESCRIPTION("802.11 data/management/control stack");MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation \<jketreno@linux.intel.com>.. Modified by others...");MODULE_LICENSE("GPL");const long wlan_frequencies[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484 };inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_beacon *beacon,struct ieee80211_device *ieee){ struct sk_buff *skb; struct ieee80211_authentication *auth; int len=30; skb=dev_alloc_skb(len+1); skb->len=len; auth = (struct ieee80211_authentication *)skb->data; auth->header.frame_control=0xb0; auth->header.duration_id=0x013a; memcpy(auth->header.addr1,beacon->bssid,ETH_ALEN); memcpy(auth->header.addr2,ieee->dev->dev_addr,ETH_ALEN); memcpy(auth->header.addr3,beacon->bssid,ETH_ALEN); auth->header.seq_ctrl= cpu_to_le16(ieee->seq_ctrl <<4); if(ieee->seq_ctrl == 0xFFF) ieee->seq_ctrl =0; else ieee->seq_ctrl++; auth->algorithm=0; auth->transaction=ieee->associate_seq; ieee->associate_seq++; auth->status=0; //success return skb; }inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee){ unsigned int len; u8 *tag; struct sk_buff *skb; struct ieee80211_probe_request *req; len = strlen(ieee->ssid); skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + 2 + len + 2 + 4); skb->len = sizeof(struct ieee80211_probe_request) + 2 + len + 2 + 4; req = (struct ieee80211_probe_request *)skb->data; req->header.frame_control = cpu_to_le16(IEEE802_11_STYPE_PROBE_REQ); req->header.duration_id = 0x013a; memset(req->header.addr1, 0xff, ETH_ALEN); memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); memset(req->header.addr3, 0xff, ETH_ALEN); req->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl << 4); if(ieee->seq_ctrl == 0xFFF) ieee->seq_ctrl =0; else ieee->seq_ctrl++; tag = ((u8 *)req) + sizeof(struct ieee80211_probe_request); *tag++ = MFIE_TYPE_SSID; *tag++ = len; memcpy(tag, ieee->ssid, len); tag += len; *tag++ = MFIE_TYPE_RATES; *tag++ = 4; *tag++ = 0x82; *tag++ = 0x84; *tag++ = 0x8b; *tag++ = 0x96; return skb;}static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest){ char *ssid = ieee->master_essid; u8 *tag; int beacon_size; short encrypt; struct ieee80211_crypt_data* crypt; struct ieee_tx_beacon *beacon_buf; struct sk_buff *skb; beacon_size= sizeof(struct ieee_tx_beacon)+strlen(ssid)+11; //beacon_buf = kmalloc(beacon_size); skb=dev_alloc_skb(beacon_size+1); beacon_buf = (struct ieee_tx_beacon*) skb->data; memcpy (beacon_buf->addr1,dest,ETH_ALEN); memcpy (beacon_buf->addr2,ieee->dev->dev_addr,ETH_ALEN); memcpy (beacon_buf->addr3,ieee->beacon_cell_ssid,ETH_ALEN); //b->seq_ctrl //b->timestamp; beacon_buf->duration_id = 0x314; beacon_buf->interval = cpu_to_le16(ieee->beacon_interval); beacon_buf->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? 1:2); beacon_buf->seq_ctrl= cpu_to_le16(ieee->seq_ctrl <<4); if(ieee->seq_ctrl == 0xFFF) ieee->seq_ctrl =0; else ieee->seq_ctrl++; ; if(ieee->host_encrypt) crypt = ieee->crypt[ieee->tx_keyidx]; else crypt = NULL; encrypt = ( crypt && crypt->ops); if(ieee->hw_wep || encrypt) beacon_buf->capability |= BEACON_CAPABILITY_WEP; else beacon_buf->capability &= ~BEACON_CAPABILITY_WEP; beacon_buf->frame_control = cpu_to_le16(IEEE802_11_STYPE_PROBE_RESP); tag = (u8*) beacon_buf + sizeof(struct ieee_tx_beacon); *(tag++) = 0; /* tag 0: ssid */ *(tag++) = strlen(ssid); memcpy(tag,ssid,strlen(ssid)); tag+=strlen(ssid); *(tag++) = 1; /* tag 1: rates */ *(tag++) = 4; *(tag++) = 0x82; *(tag++) = 0x84; *(tag++) = 0xb; *(tag++) = 0x16; *(tag++) = 3; /* tag 3: channel */ *(tag++) = 1; *(tag++) = ieee->master_chan; skb->len = beacon_size; skb->dev = ieee->dev; return skb;}struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest){ struct sk_buff *skb; u8* tag; struct ieee80211_crypt_data* crypt; struct ieee80211_association_response_hdr *assoc; short encrypt; int len = sizeof(struct ieee80211_association_response_hdr)+6; skb=dev_alloc_skb(len+1); assoc = (struct ieee80211_association_response_hdr *) skb_put(skb,sizeof(struct ieee80211_association_response_hdr)); assoc->frame_control = cpu_to_le16(0x10); memcpy(assoc->addr1,dest,ETH_ALEN); memcpy(assoc->addr3,ieee->dev->dev_addr,ETH_ALEN); memcpy(assoc->addr2,ieee->dev->dev_addr,ETH_ALEN); assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? 1:2); assoc->seq= cpu_to_le16(ieee->seq_ctrl <<4); if(ieee->seq_ctrl == 0xFFF) ieee->seq_ctrl =0; else ieee->seq_ctrl++; if(ieee->host_encrypt) crypt = ieee->crypt[ieee->tx_keyidx]; else crypt = NULL; encrypt = ( crypt && crypt->ops); if(ieee->hw_wep || encrypt) assoc->capability |= BEACON_CAPABILITY_WEP; else assoc->capability &= ~BEACON_CAPABILITY_WEP; assoc->status = 0; assoc->id = cpu_to_le16(ieee->assoc_id); if(ieee->assoc_id == 0xffff) ieee->assoc_id=0; else ieee->assoc_id++; tag = (u8*) skb_put(skb,6); tag[0] = 1; tag[1] = 4; tag[2] = 0x82; tag[3] = 0x84; tag[4] = 0xb; tag[5] = 0x16; return skb;}struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest){ struct sk_buff *skb; struct ieee80211_authentication *auth; skb=dev_alloc_skb(sizeof(struct ieee80211_authentication)+1); skb->len=sizeof(struct ieee80211_authentication); auth = (struct ieee80211_authentication *)skb->data; auth->status = cpu_to_le16(status); auth->transaction = cpu_to_le16(2); auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); auth->header.seq_ctrl= cpu_to_le16(ieee->seq_ctrl <<4); if(ieee->seq_ctrl == 0xFFF) ieee->seq_ctrl =0; else ieee->seq_ctrl++; memcpy(auth->header.addr3,ieee->dev->dev_addr,ETH_ALEN); memcpy(auth->header.addr2,ieee->dev->dev_addr,ETH_ALEN); memcpy(auth->header.addr1,dest, ETH_ALEN); auth->header.frame_control=cpu_to_le16(0xb0); return skb; }void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest){ struct sk_buff *buf=ieee80211_assoc_resp(ieee, dest); ieee->func->tx_80211(buf, ieee->dev);}void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest){ struct sk_buff *buf=ieee80211_auth_resp(ieee, s, dest); ieee->func->tx_80211(buf, ieee->dev);}void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest){ struct sk_buff *buf=ieee80211_probe_resp(ieee, dest); ieee->func->tx_80211(buf, ieee->dev);}inline struct sk_buff *ieee80211_association_req(struct ieee80211_beacon *beacon,struct ieee80211_device *ieee){ struct sk_buff *skb; struct ieee80211_association_request_hdr *hdr; u8 *tag; int len=sizeof(struct ieee80211_association_request_hdr)+ + 2 + beacon->ssid_len//essid tagged val + 2 + beacon->rates_len;//rates tagged val skb=dev_alloc_skb(len+1); skb->len=len; hdr = (struct ieee80211_association_request_hdr *)skb->data; tag = (u8*)skb->data + sizeof(struct ieee80211_association_request_hdr); hdr->frame_control=0x0; hdr->duration= 37; memcpy(hdr->addr1,beacon->bssid,ETH_ALEN); memcpy(hdr->addr2,ieee->dev->dev_addr,ETH_ALEN); memcpy(hdr->addr3,beacon->bssid,ETH_ALEN); hdr->seq= cpu_to_le16(ieee->seq_ctrl <<4); if(ieee->seq_ctrl == 0xFFF) ieee->seq_ctrl =0; else ieee->seq_ctrl++; hdr->capability=0x1; if( beacon->capability & WLAN_CAPABILITY_PRIVACY ) hdr->capability |= WLAN_CAPABILITY_PRIVACY; hdr->listen_interval=0xa; tag[0]= 0; //ssid tag[1]= beacon->ssid_len; memcpy(tag+2,beacon->ssid,beacon->ssid_len); tag=tag +2+beacon->ssid_len; tag[0]=1; //rates tag[1]=4; tag[2]=0x82; tag[3]=0x84; tag[4]=0x8b; tag[5]=0x96; return skb;}void ieee80211_associate_step1(struct ieee80211_device *ieee){ struct ieee80211_beacon *beacon = ieee->ass_beacon; struct sk_buff *skb; //int err; //del_timer_sync(&priv->scan_timer); ieee->associate_seq=1; ieee->seq_ctrl=0; IEEE80211DMESG("Stopping scan"); ieee->func->stop_scan(ieee->dev); ieee->func->set_chan(ieee->dev,beacon->channel); ieee->ieee_stats.tx_aut++; skb=ieee80211_authentication_req(beacon,ieee); ieee->associate_state = ASSOC_AUTH ; IEEE80211DMESG("Sending authentication request"); ieee->func->tx_80211(skb,ieee->dev); ieee->associate_timer.expires = jiffies + (HZ / 2); add_timer(&ieee->associate_timer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -