am930mgr.c

来自「Linux Wireless LAN Project 的目标是开发一个完整的」· C语言 代码 · 共 2,470 行 · 第 1/5 页

C
2,470
字号
/* am930mgr.c: Handles the 802.11 mac management functions.*	--------------------------------------------------------------------**   Linux WLAN **   The contents of this file are subject to the Mozilla Public*   License Version 1.0 (the "License"); you may not use this file*   except in compliance with the License. You may obtain a copy of*   the License at http://www.mozilla.org/MPL/**   Software distributed under the License is distributed on an "AS*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or*   implied. See the License for the specific language governing*   rights and limitations under the License.**   The initial developer of the original code is Mark S. Mathews*   <mark@absoval.com>.  Portions created by Mark S. Mathews*   are Copyright (C) 1998 AbsoluteValue Software, Inc.  All Rights Reserved.*   *	--------------------------------------------------------------------**	The author may be reached as mark@absoval.com, or C/O AbsoluteValue*	Software Inc., P.O. Box 941149, Maitland, FL, 32794-1149**	Thanks to David Hinds, Donald Becker, and the rest of the Linux*	developers worldwide for making all of this possible.**	--------------------------------------------------------------------*	*/#include <linux/config.h>#include <wlan/wlan_compat.h>#if (WLAN_OS == WLAN_LINUX_KERNEL)/* The following prevents "kernel_version" from being set in this file. */#define __NO_VERSION__/* PCMCIA headers generated during PCMCIA package installation */#ifdef WLAN_PCMCIA#include <pcmcia/config.h>#include <pcmcia/k_compat.h>#endif/* Module related headers, non-module drivers should not include */#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>/* Ethernet and network includes */#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/ioport.h>/* Standard driver includes */#include <linux/delay.h>#include <linux/types.h>#include <linux/fcntl.h>#include <asm/system.h>#include <asm/io.h>#include <linux/in.h>#include <linux/ptrace.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/malloc.h>#include <linux/string.h>#include <linux/timer.h>#include <asm/bitops.h>#include <linux/errno.h>/* Card and Driver services includes */#ifdef WLAN_PCMCIA#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/ds.h>#include <pcmcia/cisreg.h>#endif#include <wlan/version.h>#include <wlan/am930mib.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/wlan_ioctl.h>#include <wlan/wlan_stable.h>#ifdef PCMCIA#include "am930di.h"#endif#include "am930llc.h"#include "am930mac.h"#include "am930hw.h"#include "am930mgr.h"#elif (WLAN_OS == WLAN_LWOS)#include <stddef.h>#include <stdlibsys.h>#include <direct.h>#include <hal.h>#include <mem.h>#include <kernel.h>#include <spi.h>#include <clock.h>#include <wlan/wlan_compat.h>#include <wlan/version.h>#include <wlan/am930mib.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/am930mib.h>#include <wlan/wlan_stable.h>#include <wlan/wlan_ioctl.h>#include <lw-wlan.h>#include <wlan/am930mac.h>#include <wlan/am930hw.h>#include <wlan/am930mgr.h>#else	#error "No WLAN_OS match!"#endif/*================================================================*//* Local Constants  *//*================================================================*//* Local Functions  */static void am930mgr_authen1_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_authen2_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_authen3_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_authen4_rx( am930mgr_t *mgr, wlan_fr_authen_t *f );static void am930mgr_mkchallengetext( am930mgr_t *mgr, 	UINT8 *chbuf, UINT chbuflen, UINT8 *key, UINT keylen);static wlan_pb_t *am930mgr_mkfrm_assocreq( am930mgr_t *mgr, 	UINT8 *daddr, UINT16 capinfo, UINT16 listen_int,	wlan_ie_ssid_t *ssid,  wlan_ie_supp_rates_t *rates);static wlan_pb_t *am930mgr_mkfrm_assocresp( am930mgr_t *mgr, 	UINT8 *daddr, UINT16 capinfo, UINT16 status, UINT16 aid, 	wlan_ie_supp_rates_t *rates);static wlan_pb_t *am930mgr_mkfrm_auth( am930mgr_t *mgr, 	UINT8 *daddr, UINT16 alg, UINT16 seq, UINT16 status, UINT8 *challenge);static wlan_pb_t *am930mgr_mkfrm_deauth( am930mgr_t *mgr, 	UINT8 *daddr, UINT16 reason);static wlan_pb_t *am930mgr_mkfrm_disassoc( am930mgr_t *mgr, 	UINT8 *daddr, UINT16 reason);static wlan_pb_t *am930mgr_mkfrm_reassocresp( am930mgr_t *mgr, 	UINT8 *daddr, UINT16 capinfo, UINT16 status, UINT16 aid, 	wlan_ie_supp_rates_t *rates);static int am930mgr_rates_basicissubset( am930mgr_t *mgr, 	wlan_ie_supp_rates_t *r1, wlan_ie_supp_rates_t *r2);static UINT8 am930mgr_rates_max(wlan_ie_supp_rates_t *rates);static void am930mgr_timerfunc(am930mgr_t *mgr);/*================================================================*//* Local Statics  *//*----------------------------------------------------------------*	am930mgr_construct**	Allocates and initializes the mgr object and it's subobjects.**	returns: NULL on failure, the address of the new object*            otherwise.----------------------------------------------------------------*/am930mgr_t* am930mgr_construct(am930mac_t *mac, am930hw_t *hw){	am930mgr_t* mgr = NULL;	DBFENTER;	if ( mac != NULL )	{		mgr = kmalloc( sizeof(am930mgr_t), GFP_KERNEL);		if ( mgr != NULL )		{			memset( mgr, 0, sizeof(am930mgr_t));			mgr->mac = mac;			mgr->hw = hw;			/* TODO: make this parameterized! */			mgr->challengekey[0] = 0xa4;			mgr->challengekey[1] = 0xf6;			mgr->challengekey[2] = 0xd2;			mgr->challengekey[3] = 0x54;			mgr->challengekey[4] = 0xc6;			mgr->challengekey[5] = 0xc6;			mgr->challengekey[6] = 0x56;			mgr->challengekey[7] = 0xe6;			mgr->challengekey[8] = 0x02;			mgr->challengekey[9] = 0x64;			mgr->challengekey[10] = 0xe2;			mgr->challengekey[11] = 0x02;			mgr->challengekey[12] = 0xd4;			mgr->challengekey[13] = 0x16;			mgr->challengekey[14] = 0x47;			mgr->challengekey[15] = 0x86;			mgr->challengekey[16] = 0x56;			mgr->challengekey[17] = 0x77;			mgr->challengekey[18] = 0x37;/*			mgr->timerfunc = am930mgr_timerfunc; */			/* Management transaction timeout, default 10 seconds */			/*  for auth and assoc */			mgr->mgmt_trans_timeout = wlan_seconds2ticks(10);						/* Authenticated station timeout (AP), default 60 minutes */			mgr->ap_auth_timeout = wlan_minutes2ticks(60);			/* Associated station timeout (AP), default 30 minutes */			mgr->ap_assoc_timeout = wlan_minutes2ticks(30);		}	}	DBFEXIT;	return mgr;}/*----------------------------------------------------------------*	am930mgr_timerfunc**	Timer function called from llc.  We currently assume that this*	function will be called every 1/10th second.  Lets code*	all the time stuff so it doesn't matter....use absolute time*	from the system time register.**	returns: nothing----------------------------------------------------------------*/void am930mgr_timerfunc(am930mgr_t *mgr){	static UINT 		count = 0;	wlan_stable_item_t	*sta;	wlan_stable_item_t	*sta_dealloc;	UINT				i;	DBFENTER;	if ( mgr->mac->mode == AM930_MACMODE_ESS_AP && ++count > 9 )	{		/* only scan the stable once per second. */		count = 0;		for ( i = 0; i < WLAN_STABLE_LEN; i++ )		{			sta = mgr->stable[i];			while (sta != NULL)			{				/* Looking for: */				/* stations that need deallocation */				if ( sta->sta.state == WLAN_STA_STATE_FREE )				{					if (sta->prev == NULL && sta->next == NULL)					{						mgr->stable[i] = NULL;					}					else if  ( sta->prev == NULL && sta->next != NULL )					{						mgr->stable[i] = sta->next;						sta->next->prev = NULL;					}					else if ( sta->prev != NULL && sta->next == NULL )					{						sta->prev->next = NULL;					}					else					{						sta->prev->next = sta->next;						sta->next->prev = sta->prev;					}					mgr->aidtable[sta->sta.aid] = NULL;					sta_dealloc = sta;					sta = sta->next;					am930shim_free(sta_dealloc, sizeof(wlan_stable_item_t));					continue;				}				/* timed out authentication transactions */				if ( (sta->sta.state == WLAN_STA_STATE_PENDING_ACTIVE) &&				     (sta->sta.info & WLAN_STA_INFO_AUTH) &&					 time_after_eq( jiffies, sta->sta.timeout) )				{					sta->sta.state = WLAN_STA_STATE_FREE;					sta->sta.info = 0;				}				/* inactive stations (mark them for future dealloc) */				/*				if ( (sta->sta.state == WLAN_STA_STATE_ACTIVE) &&					 time_after_eq( jiffies, sta->				*/				sta = sta->next;			}		}	}	else	{		/* if we're a STA in INFRA we need to watch for:             */		/*    - Timed out authentication transactions                */		/*    - Timed out association transactions                   */		/*    - if associated, Inactivity from the AP                */	}		DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mgr_destruct**	destroys the mgr object**	returns: nothing----------------------------------------------------------------*/void am930mgr_destruct( am930mgr_t *mgr ){	knownbss_t	*bss;	DBFENTER;	if ( mgr != NULL )	{		/* Free the remaining bss's */		while ( mgr->bsslist != NULL )		{			bss = mgr->bsslist;			mgr->bsslist = bss->next;			/* TODO: when we add ttl, need to kill any timer funcs */			kfree_s( bss, sizeof( knownbss_t )); 		}		kfree_s(mgr, sizeof(am930mgr_t));	}	DBFEXIT;}/*----------------------------------------------------------------*	am930mgr_assoc_begin_sta**	Start the station association procedure.  Namely, send an*	association request frame to the AP.**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_assoc_begin_sta(am930mgr_t *mgr){	wlan_pb_t				*pb;	UINT16					capinfo;	/* bogus hardcode, needs fixing */	UINT8					rates[] = {WLAN_EID_SUPP_RATES, 2, 0x82, 0x84};	DBFENTER;	capinfo = WLAN_SET_MGMT_CAP_INFO_ESS(1);	if ( mgr->mac->exclude_unencrypted )	{		capinfo |= WLAN_SET_MGMT_CAP_INFO_PRIVACY(1);	}	/* build an assocreq frame and send it */	pb = am930mgr_mkfrm_assocreq( mgr, 			mgr->curr_bssid,			capinfo,			0, /* listen_int, indicates no PS mode? */			(wlan_ie_ssid_t*)mgr->curr_ssid,			(wlan_ie_supp_rates_t*)rates);									if (pb != NULL )	{		/* send the frame */		am930mac_txmac( mgr->mac, pb);		mgr->mac->state = AM930_MACSTATE_ASSOCPENDING;	}	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mgr_assoc_stop**	Stop and clean up a pending association attempt.**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_assoc_stop(am930mgr_t *mgr){	if ( mgr->mac->state == AM930_MACSTATE_ASSOCPENDING ) {		mgr->mac->state = AM930_MACSTATE_AUTH;	}}/*----------------------------------------------------------------*	am930mgr_assocreq_rx**	Handle incoming association response frames.*	NOTE: The reassocreq_rx is basically a cut-n-paste of this *		function (bad Mark, bad, bad).  If you change anything*		here it should probably be changed in reassocreq as well.**	Arguments:*		rxpb	packet buffer containing assocreq frame*		stats	receive statitistics for assocreq frame**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_assocreq_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){	wlan_fr_assocreq_t	f;	wlan_stable_item_t	*sta;	wlan_pb_t			*pb;	DBFENTER;	/* decode the frame */	f.len = rxpb->p80211buflen - WLAN_CRC_LEN;	f.buf = rxpb->p80211buf;	wlan_mgmt_decode_assocreq(&f);	/* Check for class2 error */	sta = am930mgr_stable_lookup( mgr, f.hdr->a3.a2);	if ( sta == NULL || !(sta->sta.info & WLAN_STA_INFO_AUTH) )	{    	pb = am930mgr_mkfrm_deauth( mgr, 				f.hdr->a3.a2, 				WLAN_MGMT_REASON_CLASS2_NONAUTH);		if ( pb != NULL ) 		{			am930mac_txmac( mgr->mac, pb);		}    	return;	}	/* Check to make sure we're the SS the station says we are */	/* assume bad BSSID would be rejected by rx filter */	if ( memcmp( f.ssid->ssid, mgr->curr_ssid + WLAN_IEHDR_LEN, 				mgr->curr_ssid[1]) != 0 )	{		pb = am930mgr_mkfrm_assocresp( mgr, 				f.hdr->a3.a2, 				am930mac_mk_capinfo(mgr->mac),				WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC,				0, /* AID */				(wlan_ie_supp_rates_t*)mgr->mac->oprates );		if ( pb != NULL )		{			am930mac_txmac( mgr->mac, pb);		}		return;	}	/* Capability Info check */	/*   condition 1: is it not asking for an ESS? */	/*   condition 2: is it asking for polling? (we don't support it) */	/*   condition 3: is it asking for WEP and our wep keys aren't set? */   	if (		(WLAN_GET_MGMT_CAP_INFO_ESS(ieee2host16(*f.cap_info)) == 0) ||       	((WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(ieee2host16(*f.cap_info)) == 1) && 		 		(WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(ieee2host16(*f.cap_info)) == 0)) ||       	((WLAN_GET_MGMT_CAP_INFO_PRIVACY(ieee2host16(*f.cap_info)) == 1) && 	 		(mgr->mac->privacy_invoked == 0)) )	{       	pb = am930mgr_mkfrm_assocresp( mgr,			f.hdr->a3.a2,			am930mac_mk_capinfo(mgr->mac),			WLAN_MGMT_STATUS_CAPS_UNSUPPORTED,			0, /* AID */			(wlan_ie_supp_rates_t*)mgr->mac->oprates );		if  ( pb != NULL )		{        	am930mac_txmac( mgr->mac, pb);		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?