⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 am930mac.c

📁 Linux Wireless LAN Project 的目标是开发一个完整的
💻 C
📖 第 1 页 / 共 4 页
字号:
			if ( pb->p80211hostbuf == NULL )			{				WLAN_LOG_DEBUG0(2,"pballoc_p80211 failed.\n");				#if (WLAN_OS == WLAN_LINUX_KERNEL)					am930llc_pbfree(pb);				#elif (WLAN_OS == WLAN_LWOS)					am930lw_pbfree(pb);				#else					#error "No WLAN_OS match!"				#endif			}			else			{				/* copy the header from the first frame and clear MoreFrag */				memcpy( 					pb->p80211buf, 					mac->defragpool[hash].pb[0]->p80211hostbuf,					WLAN_HDR_A3_LEN);				pb->p80211_hdr->a3.fc &= host2ieee16(~WLAN_SET_FC_MOREFRAG(1));				offset = 0;		/* current offset into data portion of frame */				/* now, copy  the data from each fragment */				for( i = 0; i < nfrag && !isbad; i++)				{					if ( iscrypt )					{						mac->defragpool[hash].pb[i] = 							am930mac_wep_decrypt(mac, mac->defragpool[hash].pb[i]);					}										if ( mac->defragpool[hash].pb[i] == NULL )					{						/* decryption failure */						isbad = 1;						WLAN_LOG_DEBUG0(1, "defragfinish, decrypt fail, dropped .\n");					}					else					{						/* we're ok, move the data */						memcpy( 							pb->p80211_payload + offset, 							mac->defragpool[hash].pb[i]->p80211_payload,							mac->defragpool[hash].pb[i]->p80211_payloadlen );								offset += 							mac->defragpool[hash].pb[i]->p80211_payloadlen;					}									}			}		}	}	/* deallocate the fragpool */	for ( i = 0; i < WLAN_FRAGS_MAX; i++)	{		if ( mac->defragpool[hash].pb[i] != NULL )		{			#if (WLAN_OS == WLAN_LINUX_KERNEL)				am930llc_pbfree(mac->defragpool[hash].pb[i]);			#elif (WLAN_OS == WLAN_LWOS)				am930lw_pbfree(mac->defragpool[hash].pb[i]);			#else				#error "No WLAN_OS match!"			#endif		}		mac->defragpool[hash].pb[i] = NULL;	}	mac->defragpool[hash].lifetime = 0;	mac->defragpool[hash].seq = UINT16_MAX;	DBFEXIT;	return pb;}/*----------------------------------------------------------------*	am930mac_defrag**	Checks a frame to see if it's part of a fragmented MSDU.  If*	so, then it puts it into a defragpool and returns NULL.  *	If the MoreFrag field is clear, then we invoke the *	defragmentation process build a new pb and return that to*	the caller.  If the frame doesn't need any kind of defrag*	behavior, we just return it to caller.**	Arguments:*		mac		- the receiver*		pb		- packet buffer containing the frame*	*	returns: *		pb		- if the frame doesn't need any defrag handling*	<a new pb>	- if the frame passed in was the last fragment and we*					successfully defragmented.*		NULL	- The frame passed in was consumed by the defrag code*					because:*					- the frame passed in is a middle fragment and we*						have no fragment pool*					- the frame was the last fragment in a series *						and we failed to finish the defragmentation *						due to missing fragments or decryption failure.*					- the frame was successfully placed in a fragment*						pool.*	NOTE:*	The 802.11 SDL implies that an 802.11 STA associated with an*	AP will always and only receive frames from the AP and that*	the AP is responsible for generating any fragments as part of a*	_single_ MA-UNITDATA.request .  Therefore*	it should be impossible for the STA MAC to have to deal w/ multiple*	fragmented frames simultaneously.  To cover possible implementation*	differences, we're still going to keep track of (potentially) *	multiple fragment pools identified by SRC address and sequence*	number.  In all other cases, multiple pools are required.----------------------------------------------------------------*/wlan_pb_t *am930mac_defrag( am930mac_t *mac, wlan_pb_t *pb){	UINT32			hash = 0;	UINT8			*srcaddr = NULL;	UINT32			morefrag;	UINT32			seq;	UINT32			fragnum;	wlan_flags_t	flags;	UINT32			i;	DBFENTER;	/*  collect the fragpool table index */	switch(mac->mode)	{		case AM930_MACMODE_ESS_AP:		/* source addr is associated STA */		case AM930_MACMODE_IBSS_STA:	/* source addr is peer STA */ 			hash = WLAN_MACADDR_HASH8(pb->p80211_hdr->a3.a2) & AM930MAC_FRAGPOOL_MASK;			srcaddr = pb->p80211_hdr->a3.a2;			break;		/* TODO: consider wisdom of using SA */		case AM930_MACMODE_ESS_STA:		/* source addr is !AP, use SA */			hash = WLAN_MACADDR_HASH8(pb->p80211_hdr->a3.a3) & AM930MAC_FRAGPOOL_MASK;			srcaddr = pb->p80211_hdr->a3.a3;			break;	}	morefrag = WLAN_GET_FC_MOREFRAG( ieee2host16(pb->p80211_hdr->a3.fc)); 	seq = WLAN_GET_SEQ_SEQNUM(ieee2host16(pb->p80211_hdr->a3.seq));	fragnum = WLAN_GET_SEQ_FRGNUM(ieee2host16(pb->p80211_hdr->a3.seq));	WLAN_LOG_DEBUG3(3, "defrag more=%ld seq=%ld fnum=%ld\n", morefrag, seq, fragnum);		if ( (morefrag == 0) && (fragnum != 0) )	{		/* It's the final in a fragment sequence */		/*  This next comparison relies on the fact that it is _extremely_ */		/*  unlikely that two MAC addresses that hash the same will be     */		/*  using the same sequence # at the same time. If it occurs,      */		/*  we'll nonfatally trash one MSDU from each STA.                 */		spin_lock_irqsave( &mac->fragpool_lock, flags);		if ( mac->defragpool[hash].seq == seq )		{			/* Ok, it's the last in a sequence that we're keeping */			mac->defragpool[hash].pb[fragnum] = pb; /* pb owned by pool now */			mac->defragpool[hash].seq = AM930MAC_FRAGPOOL_COMPLETE;			spin_unlock_irqrestore( &mac->fragpool_lock, flags);			pb = am930mac_defragfinish( mac, hash); /* also deallocs pool */			/* pb is either defragged frame in a new pb, or NULL if defrag */			/*  failed */		}		else		{			spin_unlock_irqrestore( &mac->fragpool_lock, flags);			/* Either we've a hash collision or there's something bogus */			/*  about our fragpools. Drop the frame. */			#if (WLAN_OS == WLAN_LINUX_KERNEL)				am930llc_pbfree(pb);			#elif (WLAN_OS == WLAN_LWOS)				am930lw_pbfree(pb);			#else				#error "No WLAN_OS match!"			#endif			pb = NULL;			WLAN_LOG_DEBUG0(1, "defrag final mismatch, dropped.\n");		}	}	else if ( morefrag != 0 )	{		if ( fragnum == 0 )		{			/* is fragpool avail? */			spin_lock_irqsave( &mac->fragpool_lock, flags);			if ( 0 == 				memcmp(srcaddr, mac->defragpool[hash].srcaddr, WLAN_ADDR_LEN) &&				seq != mac->defragpool[hash].seq )			{				/* it's the same STA, it's given up on prior frame */				/*  we can reclaim this fragpool */				mac->defragpool[hash].seq = AM930MAC_FRAGPOOL_COMPLETE;				for ( i = 0; i < WLAN_FRAGS_MAX; i++)				{					if ( mac->defragpool[hash].pb[i] != NULL )					{						#if (WLAN_OS == WLAN_LINUX_KERNEL)							am930llc_pbfree(mac->defragpool[hash].pb[i]);						#elif (WLAN_OS == WLAN_LWOS)							am930lw_pbfree(mac->defragpool[hash].pb[i]);						#else							#error "No WLAN_OS match!"						#endif					}					mac->defragpool[hash].pb[i] = NULL;				}				mac->defragpool[hash].lifetime = 0;				mac->defragpool[hash].seq = AM930MAC_FRAGPOOL_FREE;			}			if ( mac->defragpool[hash].seq == AM930MAC_FRAGPOOL_FREE )			{				/* empty slot, create new pool */				mac->defragpool[hash].seq = seq;				memcpy( mac->defragpool[hash].srcaddr, srcaddr, WLAN_ADDR_LEN);				mac->defragpool[hash].lifetime = 					jiffies + wlan_tu2ticks(mac->maxrxlifetime);				mac->defragpool[hash].pb[fragnum] = pb;	/* fragpool owns pb */				spin_unlock_irqrestore( &mac->fragpool_lock, flags);				pb = NULL;		/* tell caller we've consumed it */			}			else			{				/* collision on hash, frag sequence in progress:      */				/*   from same STA (impossible?), or                  */				/*   frame DUP from same STA (f/w should prevent), or */				/*   from hash colliding STA.  Drop frame.            */				/* check to see if it's same STA */				spin_unlock_irqrestore( &mac->fragpool_lock, flags);				#if (WLAN_OS == WLAN_LINUX_KERNEL)				am930llc_pbfree(pb);				#elif (WLAN_OS == WLAN_LWOS)				am930lw_pbfree(pb);				#else				#error "No WLAN_OS match!"				#endif				pb = NULL;				WLAN_LOG_DEBUG0(1, "defrag initial mismatch, dropped.\n");			}		}		else	/* fragnum != 0 */		{			spin_lock_irqsave( &mac->fragpool_lock, flags);			if ( mac->defragpool[hash].seq == seq &&				 mac->defragpool[hash].pb[fragnum] == NULL )			{				mac->defragpool[hash].pb[fragnum] = pb;				spin_unlock_irqrestore( &mac->fragpool_lock, flags);				pb = NULL;			}			else			{				/* collision on hash, frag sequence in progress:      */				/*   from same STA (diff seq, impossible?), or        */				/*   from hash colliding STA.  Drop frame.            */				spin_unlock_irqrestore( &mac->fragpool_lock, flags);				#if (WLAN_OS == WLAN_LINUX_KERNEL)					am930llc_pbfree(pb);				#elif (WLAN_OS == WLAN_LWOS)					am930lw_pbfree(pb);				#else					#error "No WLAN_OS match!"				#endif				pb = NULL;				WLAN_LOG_DEBUG0(1, "defrag intermediate mismatch, dropped.\n");			}		}	}	/* else morefrag==0 && fragnum==0, just return pb */	DBFEXIT;	return pb;}/*----------------------------------------------------------------*	am930mac_rxframe_err**	returns: nothing----------------------------------------------------------------*/void am930mac_rxframe_err(am930mac_t *mac){#if (WLAN_OS == WLAN_LINUX_KERNEL)	am930llc_rxframe_err(mac->llc);#elif (WLAN_OS == WLAN_LWOS)	am930lw_rxframe_err( mac->lw);#else	#error "No WLAN_OS match!"#endif	return;}/*----------------------------------------------------------------*	am930mac_rxmgmt**	Private helper for the rxframe method.  Checks to make sure*	the received frame is actually directed to us (or is multi/broadcast)*	before handing the frame off to the mgr component.**	returns: nothing----------------------------------------------------------------*/void am930mac_rxmgmt( am930mac_t *mac, wlan_pb_t *pb, am930rxstats_t *stats){	int		notme = 0;	DBFENTER;	WLAN_LOG_DEBUG0(3, "mgmt frm received\n");	/* Make sure this frame is really for me in case we're in promiscuous mode */	if ( (pb->p80211_hdr->a3.a1[0] & 0x01) == 0 ) /* is multicast? */		notme = memcmp( pb->p80211_hdr->a3.a1, mac->hw->addr, WLAN_ADDR_LEN);	if ( notme )	{		/* mgmt frame with DA that's not me...silently drop it */		am930shim_pbfree( pb );		kfree_s(stats, sizeof(am930rxstats_t));	}	else	{		am930mgr_rxmgmt( mac->mgr, pb, stats);	}	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mac_timerfunc**	Called 10 times per second by llc.**	returns: nothing----------------------------------------------------------------*/void am930mac_timerfunc(am930mac_t *mac){	int 			i;	int 			j;	wlan_flags_t	flags;	for ( i = 0; i < AM930MAC_FRAGPOOLS_MAX; i++)	{		/* lock the whole table */		spin_lock_irqsave( &mac->fragpool_lock, flags);		if ( mac->defragpool[i].seq != AM930MAC_FRAGPOOL_FREE && 			mac->defragpool[i].seq != AM930MAC_FRAGPOOL_COMPLETE && 			time_after_eq( jiffies, mac->defragpool[i].lifetime) )		{			/* mark it as complete so noone messes with it */			mac->defragpool[i].seq = AM930MAC_FRAGPOOL_COMPLETE;			for ( j=0; j < WLAN_FRAGS_MAX; j++)			{				if ( mac->defragpool[i].pb[j] != NULL )				{				#if (WLAN_OS == WLAN_LINUX_KERNEL)					am930llc_pbfree(mac->defragpool[i].pb[j]);				#elif (WLAN_OS == WLAN_LWOS)					am930lw_pbfree(mac->defragpool[i].pb[j]);				#else					#error "No WLAN_OS match!"				#endif				}				mac->defragpool[i].pb[j] = NULL;			}			mac->defragpool[i].seq = AM930MAC_FRAGPOOL_FREE;		}		spin_unlock_irqrestore( &mac->fragpool_lock, flags);	}}/*----------------------------------------------------------------*	am930mac_txllc**	Public method called from the llc object to send a frame. This *	function takes a pb and addresses, formats the 802.11 header*	and then enqueues the frame.  The frame will be transmitted in*	response to some future tx complete interrupt.**	returns: *		0 success *		1 alloc failure*		2 queue full*		3 queue busy----------------------------------------------------------------*/UINT32 am930mac_txllc( am930mac_t *mac, UINT8 *daddr, UINT8 *saddr, 						wlan_pb_t *pb){	UINT32				result = 0;	wlan_stable_item_t	*sta;	DBFENTER;	if ( mac->mode == AM930_MACMODE_NOTRUNNING ||		 mac->mode == AM930_MACMODE_NOTJOINED )	{		WLAN_LOG_WARNING0("tx attempt, not joined, frame dropped\n");		return result;	}	switch( mac->mode )	{		case AM930_MACMODE_IBSS_STA:			/* copy the addresses to the 802.11 header */			memcpy( pb->p80211_hdr->a3.a1, daddr, WLAN_ADDR_LEN);			memcpy( pb->p80211_hdr->a3.a2, saddr, WLAN_ADDR_LEN);			memcpy( pb->p80211_hdr->a3.a3, mac->mgr->curr_bssid, WLAN_BSSID_LEN);				/* set the rest of the 802.11 header */			pb->p80211_hdr->a3.fc = host2ieee16( 				WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA ) |				WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY) );			pb->p80211_hdr->a3.dur = 0;			pb->p80211_hdr->a3.seq = 0;			/* let the cryptor determine the need */			am930mac_wep_encrypt( mac, pb );			break;		case AM930_MACMODE_ESS_STA:			/* copy the addresses to the 802.11 header */			memcpy( pb->p80211_hdr->a3.a1, mac->mgr->curr_bssid, WLAN_BSSID_LEN);			memcpy( pb->p80211_hdr->a3.a2, saddr, WLAN_ADDR_LEN);			memcpy( pb->p80211_hdr->a3.a3, daddr, WLAN_ADDR_LEN);				/* set the rest of the 802.11 header */			pb->p80211_hdr->a3.fc = host2ieee16( 				WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA ) |				WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY) |				WLAN_SET_FC_TODS(1) );			pb->p80211_hdr->a3.dur = 0;			pb->p80211_hdr->a3.seq = 0;			/* let the cryptor determine the need */			am930mac_wep_encrypt( mac, pb );			break;		case AM930_MACMODE_ESS_AP:			/* Check that we want to tx this frame */			sta = am930mgr_stable_lookup( mac->mgr, daddr);			if ( (daddr[0] & 0x01) || sta != NULL)			{				/* copy the addresses to the 802.11 header */				memcpy( pb->p80211_hdr->a3.a1, daddr, WLAN_ADDR_LEN);				memcpy( pb->p80211_hdr->a3.a2, mac->mgr->curr_bssid, WLAN_BSSID_LEN);				memcpy( pb->p80211_hdr->a3.a3, saddr, WLAN_ADDR_LEN);					/* set the rest of the 802.11 header */				pb->p80211_hdr->a3.fc = host2ieee16( 					WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA ) |					WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY) |					WLAN_SET_FC_FROMDS(1) );				pb->p80211_hdr->a3.dur = 0;				pb->p80211_hdr->a3.seq = 0;								if ( ((daddr[0] & 0x01) && mac->exclude_unencrypted) || /* ismulti */					 ( sta != NULL &&  /* is directed (relying on short-circuit) */					  	( (sta->sta.info & WLAN_STA_INFO_WEPON) || /* sta uses wep */						 mac->exclude_unencrypted)) )               /* MUST use wep */				{					/* let the cryptor determine the need */					am930mac_wep_encrypt(mac, pb);				}			}			else			{

⌨️ 快捷键说明

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