am930mgr.c

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

C
2,470
字号
		return;	}	/* Basic Rate Check */	if ( !am930mgr_rates_basicissubset( mgr, 			(wlan_ie_supp_rates_t*)mgr->mac->oprates, f.supp_rates) )	{		/* mismatch in basic rates */		pb = am930mgr_mkfrm_assocresp( mgr,				f.hdr->a3.a2,				am930mac_mk_capinfo(mgr->mac),				WLAN_MGMT_STATUS_ASSOC_DENIED_RATES,				0, /* AID */				(wlan_ie_supp_rates_t*)mgr->mac->oprates );		if  ( pb != NULL )		{        	am930mac_txmac( mgr->mac, pb);		}		return;	}	/* Made it! we're now ready to handle success! */	if ( (sta->sta.listen_int = ieee2host16(*f.listen_int)) )	{		sta->sta.info |= WLAN_STA_INFO_PSMODE;	} 		if ( WLAN_GET_MGMT_CAP_INFO_PRIVACY(ieee2host16(*f.cap_info)) )	{		sta->sta.info |= WLAN_STA_INFO_WEPON;	}		sta->sta.rate = sta->sta.max_rate = am930mgr_rates_max(f.supp_rates);	sta->sta.info |= WLAN_STA_INFO_ASSOC;	pb = am930mgr_mkfrm_assocresp( mgr,			f.hdr->a3.a2,			am930mac_mk_capinfo(mgr->mac),			WLAN_MGMT_STATUS_SUCCESS,			sta->sta.aid | BIT14 | BIT15,			(wlan_ie_supp_rates_t*)mgr->mac->oprates );    if ( pb != NULL )	{		am930mac_txmac( mgr->mac, pb);	}	DBFEXIT;    return;}/*----------------------------------------------------------------*	am930mgr_assocresp_rx**	Handle incoming association response frames**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_assocresp_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){	wlan_fr_assocresp_t	f;	DBFENTER;	/* We better be assoc pending, otherwise ignore it */	if ( mgr->mac->state == AM930_MACSTATE_ASSOCPENDING )	{		/* decode the frame */		f.len = rxpb->p80211buflen - WLAN_CRC_LEN;		f.buf = rxpb->p80211buf;		wlan_mgmt_decode_assocresp(&f);			/* save values and set mode */		if ( ieee2host16(*(f.status)) == WLAN_MGMT_STATUS_SUCCESS )		{			mgr->curr_aid = ieee2host16(*(f.aid));			mgr->mac->state = AM930_MACSTATE_ASSOC;			if ( (mgr->curr_aid >> 14) != (BIT0 | BIT1) )			{				WLAN_LOG_WARNING0("AID from AP, has two msb clear.\n");			}			WLAN_LOG_NOTICE1(				"Association Successful, AID=%d.\n", 				mgr->curr_aid & ~(BIT14|BIT15));			am930llc_cmdcomplete(mgr->mac->llc, 0);		}		else		{			/* jump back to the auth state and indicate the error */			mgr->mac->state = AM930_MACSTATE_AUTH;			am930mgr_prstatus(mgr, ieee2host16(*(f.status)) );			am930llc_cmdcomplete(mgr->mac->llc, ieee2host16(*(f.status)) );		}	}	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mgr_auth_begin_sta**	Start the station authentication procedure.  Namely, send an*	auth frame to the AP.**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen_begin_sta(am930mgr_t *mgr, UINT16 authalg){	wlan_fr_authen_t	*f;	wlan_pb_t			*pb;	DBFENTER;	/* initial setup of frame */	pb = am930shim_pballoc();	if (pb != NULL )	{		f = kmalloc( sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN, GFP_ATOMIC );		if ( f != NULL )		{			memset( f, 0, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN);			f->buf = ((UINT8*)f) + sizeof(wlan_fr_authen_t);			f->len = WLAN_AUTHEN_FR_MAXLEN;			wlan_mgmt_encode_authen(f);						/* insert values */			f->hdr->a3.fc = host2ieee16(				WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | 				WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN));			memcpy( f->hdr->a3.a1, mgr->curr_bssid, WLAN_BSSID_LEN);			memcpy( f->hdr->a3.a2, mgr->hw->addr, WLAN_ADDR_LEN);			memcpy( f->hdr->a3.a3, mgr->curr_bssid, WLAN_BSSID_LEN);				*(f->auth_alg) = host2ieee16(authalg);			*(f->auth_seq) = host2ieee16(1);					/* now copy the constructed frame to a pb and tx */			am930shim_pballoc_p80211( pb, f->len);			/* bogus: add 4 because pballoc assumes rx+FCS and subtracts 4 */			pb->p80211_payloadlen += 4;			if ( pb->p80211hostbuf != NULL )  /* note silent failure */			{					memcpy( pb->p80211buf, f->buf, f->len);				/* send the frame */				am930mac_txmac( mgr->mac, pb);				mgr->mac->state = AM930_MACSTATE_AUTHPENDING;			}				else			{				am930shim_pbfree( pb );			}					/* the response(s) will be handled in auth_rx */			kfree_s( f, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN);		}	}	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mgr_authen_stop**	Clear the auth pending state.**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen_stop( am930mgr_t *mgr ){	mgr->mac->state = AM930_MACSTATE_NOAUTH;}/*----------------------------------------------------------------*	am930mgr_authen_rx**	Handle incoming authentication frames**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){	wlan_fr_authen_t	f;	DBFENTER;	/* we better be an AP or a STA in AUTHPENDING otherwise ignore */	if ( !(mgr->mac->mode == AM930_MACMODE_ESS_AP ||			mgr->mac->state == AM930_MACSTATE_AUTHPENDING) )	{		return;	}	/* OK, we're in an OK mode and state, if it's encrypted, decrypt */	if ( rxpb->wep_iscrypt )	{		if ( (rxpb = am930mac_wep_decrypt( mgr->mac, rxpb)) == NULL )		{			WLAN_LOG_NOTICE0("authen_rx: rx'd undecryptable frame\n");			return;		}	}	/* decode the frame */	f.len = rxpb->p80211buflen - WLAN_CRC_LEN;	f.buf = rxpb->p80211buf;	wlan_mgmt_decode_authen(&f);	switch ( ieee2host16(*(f.auth_seq )) )	{		case 1:			am930mgr_authen1_rx( mgr, &f);			break;		case 2:			am930mgr_authen2_rx( mgr, &f);			break;		case 3:			am930mgr_authen3_rx( mgr, &f);			break;		case 4:			am930mgr_authen4_rx( mgr, &f);			break;		default:			WLAN_LOG_WARNING1("f.auth_seq not in [1234], seq = %d\n", 				ieee2host16(*(f.auth_seq)));			break;	}	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mgr_authen1_rx**	Handles incoming authen frames with sequence 1.  Currently *	assumes we're an AP.  So far, no one appears to use authentication*	in Ad-Hoc mode.**	returns: nothing.----------------------------------------------------------------*/void am930mgr_authen1_rx( am930mgr_t *mgr, wlan_fr_authen_t *f ){	wlan_stable_item_t	*sta;	wlan_pb_t			*pb;	DBFENTER;	/* Check to make  sure we support the requested alg */	if ( ((ieee2host16(*(f->auth_alg)) == WLAN_AUTH_ALG_SHAREDKEY) && 		 (mgr->mac->privacy_invoked == 0)) ||		 ((ieee2host16(*(f->auth_alg)) != WLAN_AUTH_ALG_SHAREDKEY) &&		 (ieee2host16(*(f->auth_alg)) != WLAN_AUTH_ALG_OPENSYSTEM)) )	{		/* we haven't any wep keys and can't do SHAREDKEY _or_ */		/* the STA has asked for an alg we know nothing about  */		pb = am930mgr_mkfrm_auth( mgr, 				f->hdr->a3.a2, 				ieee2host16(*(f->auth_alg)),				2,				WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG,				NULL );		if ( pb != NULL )		{			am930mac_txmac( mgr->mac, pb);		}		return;	}	/* Check for the sender station in our stable */	sta = am930mgr_stable_lookup( mgr, f->hdr->a3.a2);	if ( sta != NULL )	{		/* Change it's state to PENDING and mark authenticated */		sta->sta.state = WLAN_STA_STATE_PENDING_ACTIVE;		sta->sta.info |= WLAN_STA_INFO_AUTH;		sta->sta.timeout = jiffies + mgr->mgmt_trans_timeout;		sta->sta.timer_state = WLAN_STA_TSTATE_AUTH;	}	else	{		/* It's a new one, allocate and add to stable */		sta = kmalloc( sizeof(wlan_stable_item_t), GFP_ATOMIC);		if ( sta != NULL )		{			memset( sta, 0, sizeof(wlan_stable_item_t));			memcpy( sta->sta.addr, f->hdr->a3.a2, WLAN_ADDR_LEN);			sta->sta.state = WLAN_STA_STATE_PENDING_ACTIVE;			sta->sta.info |= WLAN_STA_INFO_AUTH;			sta->sta.timeout = jiffies + mgr->mgmt_trans_timeout;			if ( (sta->sta.aid = am930mgr_stable_alloc_aid(mgr, sta)) > 0 )			{				am930mgr_stable_insert( mgr, sta);			}			else			{				/* Can't alloc an AID, tell the STA it can't authenticate */				pb = am930mgr_mkfrm_auth( mgr, 						f->hdr->a3.a2, 						ieee2host16(*(f->auth_alg)),						2,						WLAN_MGMT_STATUS_UNSPEC_FAILURE,						NULL );				if ( pb != NULL )				{					am930mac_txmac( mgr->mac, pb);				}				am930shim_free(sta, sizeof(wlan_stable_item_t));				return;			}		}	}	/* At this point, we've got a sta in the stable and we support the alg */	/*  time to send a SUCCESS response */	if (ieee2host16(*(f->auth_alg)) == WLAN_AUTH_ALG_OPENSYSTEM )	{		pb = am930mgr_mkfrm_auth( mgr, 				f->hdr->a3.a2, 				ieee2host16(*(f->auth_alg)),				2,				WLAN_MGMT_STATUS_SUCCESS,				NULL );		if ( pb != NULL )		{			am930mac_txmac( mgr->mac, pb);		}		/* No more pending, this guy's authenticated */		sta->sta.state = WLAN_STA_STATE_ACTIVE;		sta->sta.timeout = jiffies;		sta->sta.timer_state = 0;	}	else	{		UINT8	ctext[WLAN_CHALLENGE_LEN];		/* Shared key (alg num validated previously) */		am930mgr_mkchallengetext( mgr, 			ctext, 			WLAN_CHALLENGE_LEN, 			mgr->challengekey,			sizeof(mgr->challengekey));		pb = am930mgr_mkfrm_auth( mgr, 				f->hdr->a3.a2, 				ieee2host16(*(f->auth_alg)),				2,				WLAN_MGMT_STATUS_SUCCESS,				ctext );		if ( pb != NULL )		{			am930mac_txmac( mgr->mac, pb);		}	}	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mgr_authen2_rx**	Handles incoming auth frames with sequence number 2.  Currently*	assumes we're a station.**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen2_rx( am930mgr_t *mgr, wlan_fr_authen_t *f ){	DBFENTER;	switch (ieee2host16(*(f->auth_alg)))	{		case WLAN_AUTH_ALG_OPENSYSTEM:			if ( ieee2host16(*(f->status)) == WLAN_MGMT_STATUS_SUCCESS )			{				WLAN_LOG_NOTICE0("802.11 Authen (OPEN) Successful.\n");				mgr->mac->state = AM930_MACSTATE_AUTH;				am930llc_cmdcomplete(mgr->mac->llc, ieee2host16(*(f->status)));			}			else			{				WLAN_LOG_NOTICE0("802.11 Authen (OPEN) Failed.\n");				am930mgr_prstatus(mgr, ieee2host16(*(f->status)) );				mgr->mac->state = AM930_MACSTATE_NOAUTH;				am930llc_cmdcomplete(mgr->mac->llc, ieee2host16(*(f->status)));			}			break;#ifdef TODO_WEP		case WLAN_AUTH_ALG_SHAREDKEY:		{			wlan_fr_authen_t	*reply;			wlan_pb_t			*pb;			/* Initial setup of response frame */			pb = am930shim_pballoc();			if (pb != NULL )			{				reply = kmalloc( sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN, GFP_ATOMIC );				if ( reply != NULL )				{					memset( reply, 0, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN);						/* Set up the reply frame */					reply->buf = ((UINT8*)reply) + sizeof(wlan_fr_authen_t);					reply->len = WLAN_AUTHEN_FR_MAXLEN;					wlan_mgmt_encode_authen(reply);								/* insert values */					reply->hdr->a3.fc = host2ieee16(						WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | 						WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN));					memcpy( reply->hdr->a3.a1, f->hdr->a3.a2, WLAN_BSSID_LEN);					memcpy( reply->hdr->a3.a2, mgr->hw->addr, WLAN_ADDR_LEN);					memcpy( reply->hdr->a3.a3, mgr->curr_bssid, WLAN_BSSID_LEN);					*(reply->auth_alg) = *(f->auth_alg);					*(reply->auth_seq) = host2ieee16(3);					*(reply->status) = host2ieee16(WLAN_MGMT_STATUS_SUCCESS);					reply->challenge = (wlan_ie_challenge_t*)reply->buf + reply->len;					reply->len += WLAN_CHALLENGE_IE_LEN;					reply->challenge->eid = WLAN_EID_CHALLENGE;					reply->challenge->len = WLAN_CHALLENGE_LEN;					memcpy( reply->challenge->challenge, f->challenge->challenge, WLAN_CHALLENGE_LEN);					/* now copy the constructed frame to a pb and tx */					am930shim_pballoc_p80211( pb, reply->len);							if ( pb->p80211hostbuf != NULL )  /* note silent failure */					{							memcpy( pb->p80211buf, reply->buf, reply->len);						am930mac_wep_encrypt( mgr->mac, pb );						/* send the frame */						am930mac_txmac( mgr->mac, pb);					}						else					{						am930shim_pbfree( pb );					}							/* discard the buffer */					kfree_s( reply, sizeof(wlan_fr_authen_t) + WLAN_AUTHEN_FR_MAXLEN);				}			}			break;		}#endif /* TODO_WEP */		default:			WLAN_LOG_WARNING1("rx'd auth.seq = 2 unknown auth_alg=%d\n", ieee2host16(*(f->auth_alg)) );			break;	}	DBFEXIT;}/*----------------------------------------------------------------*	am930mgr_authen3_rx**	Handles incoming authen frames with sequence 3.  Currently *	assumes we're an AP.  This function assumes the frame has*	already been successfully decrypted.**	returns: nothing for now----------------------------------------------------------------*/void am930mgr_authen3_rx( am930mgr_t *mgr, wlan_fr_authen_t *f ){	UINT8				ctext[WLAN_CHALLENGE_LEN];	wlan_pb_t			*pb;	wlan_stable_item_t	*sta;		DBFENTER;	/* First, find out if we're in a auth exchange w/ sender */

⌨️ 快捷键说明

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