/**
 * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE
 * @p2p_ie: Address of P2P IE to search
 * @p2p_ielen: Length limit from p2p_ie
 * @target_attr_id: The attribute ID of P2P attribute to search
 * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr
 * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute
 *
 * Returns: the address of the specific WPS attribute found, or NULL
 */
u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr)
{
	u8 *attr_ptr = NULL;
	u8 *target_attr_ptr = NULL;
	u8 p2p_oui[4]={0x50,0x6F,0x9A,0x09};

	if(len_attr)
		*len_attr = 0;

	if ( !p2p_ie || ( p2p_ie[0] != _VENDOR_SPECIFIC_IE_ ) ||
		( _rtw_memcmp( p2p_ie + 2, p2p_oui , 4 ) != _TRUE ) )
	{
		return attr_ptr;
	}

	// 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type)
	attr_ptr = p2p_ie + 6; //goto first attr
	
	while(attr_ptr - p2p_ie < p2p_ielen)
	{
		// 3 = 1(Attribute ID) + 2(Length)
		u8 attr_id = *attr_ptr;
		u16 attr_data_len = RTW_GET_LE16(attr_ptr + 1);
		u16 attr_len = attr_data_len + 3;
		
		//DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __FUNCTION__, attr_ptr, attr_id, attr_data_len);
		if( attr_id == target_attr_id )
		{
			target_attr_ptr = attr_ptr;
		
			if(buf_attr)
				_rtw_memcpy(buf_attr, attr_ptr, attr_len);
			
			if(len_attr)
				*len_attr = attr_len;
			
			break;
		}
		else
		{
			attr_ptr += attr_len; //goto next
		}		
		
	}	

	return target_attr_ptr;
}
Exemple #2
0
//	attr_content: The output buffer, contains the "body field" of WFD attribute.
//	attr_contentlen: The data length of the "body field" of WFD attribute.
int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen)
{
	int match;
	uint cnt = 0;	
	u8 attr_id, wfd_oui[4]={0x50,0x6F,0x9A,0x0A};


	match=_FALSE;

	if ( ( wfd_ie[ 0 ] != _VENDOR_SPECIFIC_IE_ ) ||
		( _rtw_memcmp( wfd_ie + 2, wfd_oui , 4 ) != _TRUE ) )
	{
		return( match );
	}

	//	1 ( WFD IE ) + 1 ( Length ) + 3 ( OUI ) + 1 ( OUI Type )
	cnt = 6;
	while( cnt < wfd_ielen )
	{
		//u16	attrlen = le16_to_cpu(*(u16*)(p2p_ie + cnt + 1 ));
		u16 attrlen = RTW_GET_LE16(wfd_ie + cnt + 1);
		
		attr_id = wfd_ie[cnt];
		if( attr_id == target_attr_id )
		{
			//	2 -> 1 byte for attribute ID field, 1 bytes for length field
			if(attr_content)
			_rtw_memcpy( attr_content, &wfd_ie[ cnt + 2 ], attrlen );
			
			if(attr_contentlen)
			*attr_contentlen = attrlen;
			
			cnt += attrlen + 2;

			match = _TRUE;
			break;
		}
		else
		{
			cnt += attrlen + 2; //goto next	
		}		
		
	}	

	return match;

}
Exemple #3
0
//	attr_content: The output buffer, contains the "body field" of P2P attribute.
//	attr_contentlen: The data length of the "body field" of P2P attribute.
u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen)
{
	uint cnt = 0;
	u8 *p2p_attr_ptr = NULL;
	u8 attr_id, p2p_oui[4]={0x50,0x6F,0x9A,0x09};

	if(attr_contentlen)
		*attr_contentlen = 0;

	if ( ( p2p_ie[ 0 ] != _VENDOR_SPECIFIC_IE_ ) ||
		( _rtw_memcmp( p2p_ie + 2, p2p_oui , 4 ) != _TRUE ) )
	{
		return p2p_attr_ptr;
	}

	//	1 ( P2P IE ) + 1 ( Length ) + 3 ( OUI ) + 1 ( OUI Type )
	cnt = 6;
	while( cnt < p2p_ielen )
	{
		//u16	attrlen = le16_to_cpu(*(u16*)(p2p_ie + cnt + 1 ));
		u16 attrlen = RTW_GET_LE16(p2p_ie + cnt + 1);
		
		attr_id = p2p_ie[cnt];
		if( attr_id == target_attr_id )
		{
			p2p_attr_ptr = p2p_ie + cnt;
			
			//	3 -> 1 byte for attribute ID field, 2 bytes for length field
			if(attr_content)
				_rtw_memcpy( attr_content, &p2p_ie[ cnt + 3 ], attrlen );
			
			if(attr_contentlen)
				*attr_contentlen = attrlen;
			
			break;
		}
		else
		{
			cnt += attrlen + 3; //goto next	
		}		
		
	}	

	return p2p_attr_ptr;

}
Exemple #4
0
void dump_p2p_attr(u8 *ie, u32 ie_len) {
	u8* pos = (u8*)ie;
	u8 id;
	u16 len;

	uint is_p2p_ie;
	rtw_get_p2p_ie(ie, ie_len, NULL, &is_p2p_ie);
	if(!is_p2p_ie)
		return;

	pos+=6;
	while(pos-ie<=ie_len){
		id = *pos;
		len = RTW_GET_LE16(pos+1);

		DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len);

		pos+=(3+len);
	}	
}
void dump_p2p_ie(u8 *ie, u32 ie_len) {
	u8* pos = (u8*)ie;
	u8 id;
	u16 len;

	u8 *p2p_ie;
	uint p2p_ielen;
	
	p2p_ie = rtw_get_p2p_ie(ie, ie_len, NULL, &p2p_ielen);
	if(p2p_ie != ie || p2p_ielen == 0)
		return;

	pos+=6;
	while(pos-ie < ie_len){
		id = *pos;
		len = RTW_GET_LE16(pos+1);

		DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len);

		pos+=(3+len);
	}	
}
Exemple #6
0
int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
{
	int i, ret = _SUCCESS;
	int left, count;
	u8 *pos;
	u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01};

	if (rsn_ie_len <= 0) {
		/* No RSN IE - fail silently */
		return _FAIL;
	}


	if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2)))
	{
		return _FAIL;
	}

	pos = rsn_ie;
	pos += 4;
	left = rsn_ie_len - 4;

	/* group_cipher */
	if (left >= RSN_SELECTOR_LEN) {

		*group_cipher = rtw_get_wpa2_cipher_suite(pos);

		pos += RSN_SELECTOR_LEN;
		left -= RSN_SELECTOR_LEN;

	} else if (left > 0) {
		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie length mismatch, %u too much", __func__, left));
		return _FAIL;
	}

	/* pairwise_cipher */
	if (left >= 2)
	{
	        /* count = le16_to_cpu(*(u16*)pos); */
		count = RTW_GET_LE16(pos);
		pos += 2;
		left -= 2;

		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
			RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie count botch (pairwise), "
						 "count %u left %u", __func__, count, left));
			return _FAIL;
		}

		for (i = 0; i < count; i++)
		{
			*pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);

			pos += RSN_SELECTOR_LEN;
			left -= RSN_SELECTOR_LEN;
		}

	}
	else if (left == 1)
	{
		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s: ie too short (for key mgmt)",  __func__));

		return _FAIL;
	}

	if (is_8021x) {
		if (left >= 6) {
			pos += 2;
			if (!memcmp(pos, SUITE_1X, 4)) {
				RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s (): there has 802.1x auth\n", __func__));
				*is_8021x = 1;
			}
		}
	}

	return ret;

}
int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
{
	int i, ret=_SUCCESS;
	int left, count;
	u8 *pos;
	u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1};

	if (wpa_ie_len <= 0) {
		/* No WPA IE - fail silently */
		return _FAIL;
	}

	
	if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) ||
	   (_rtw_memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != _TRUE) )
	{		
		return _FAIL;
	}

	pos = wpa_ie;

	pos += 8;
	left = wpa_ie_len - 8;	


	//group_cipher
	if (left >= WPA_SELECTOR_LEN) {

		*group_cipher = rtw_get_wpa_cipher_suite(pos);
		
		pos += WPA_SELECTOR_LEN;
		left -= WPA_SELECTOR_LEN;
		
	} 
	else if (left > 0)
	{
		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left));
		
		return _FAIL;
	}


	//pairwise_cipher
	if (left >= 2)
	{		
                //count = le16_to_cpu(*(u16*)pos);	
		count = RTW_GET_LE16(pos);
		pos += 2;
		left -= 2;
		
		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), "
				   		"count %u left %u", __FUNCTION__, count, left));
			return _FAIL;
		}
		
		for (i = 0; i < count; i++)
		{
			*pairwise_cipher |= rtw_get_wpa_cipher_suite(pos);
			
			pos += WPA_SELECTOR_LEN;
			left -= WPA_SELECTOR_LEN;
		}
		
	} 
	else if (left == 1)
	{
		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)",   __FUNCTION__));
		return _FAIL;
	}

	if (is_8021x) {
		if (left >= 6) {
			pos += 2;
			if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) {
				RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s : there has 802.1x auth\n", __FUNCTION__));
				*is_8021x = 1;
			}
		}
	}
	
	return ret;
	
}
Exemple #8
0
int rtw_parse_wpa2_ie(u8* rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher)
{
	int i, ret=_SUCCESS;
	int left, count;
	u8 *pos;

	if (rsn_ie_len <= 0) {
		/* No RSN IE - fail silently */
		return _FAIL;
	}


	if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2)))
	{		
		return _FAIL;
	}
	
	pos = rsn_ie;
	pos += 4;
	left = rsn_ie_len - 4;	

	//group_cipher
	if (left >= RSN_SELECTOR_LEN) {

		*group_cipher = rtw_get_wpa2_cipher_suite(pos);
		
		pos += RSN_SELECTOR_LEN;
		left -= RSN_SELECTOR_LEN;
		
	} else if (left > 0) {
		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left));
		return _FAIL;
	}

	//pairwise_cipher
	if (left >= 2)
	{		
	        //count = le16_to_cpu(*(u16*)pos);
		count = RTW_GET_LE16(pos);
		pos += 2;
		left -= 2;

		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), "
				  		 "count %u left %u", __FUNCTION__, count, left));
			return _FAIL;
		}
		
		for (i = 0; i < count; i++)
		{			
			*pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);
			
			pos += RSN_SELECTOR_LEN;
			left -= RSN_SELECTOR_LEN;
		}

	} 
	else if (left == 1)
	{
		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)",  __FUNCTION__));
		
		return _FAIL;
	}


	return ret;
	
}
Exemple #9
0
int rtw_parse_wpa2_ie(uint8_t * rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
{
	int i, ret=_SUCCESS;
	int left, count;
	uint8_t *pos;
	uint8_t SUITE_1X[4] = {0x00,0x0f, 0xac, 0x01};

	if (rsn_ie_len <= 0) {
		/* No RSN IE - fail silently */
		return _FAIL;
	}


	if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (uint8_t)(rsn_ie_len - 2)))
	{
		return _FAIL;
	}

	pos = rsn_ie;
	pos += 4;
	left = rsn_ie_len - 4;

	//group_cipher
	if (left >= RSN_SELECTOR_LEN) {

		*group_cipher = rtw_get_wpa2_cipher_suite(pos);

		pos += RSN_SELECTOR_LEN;
		left -= RSN_SELECTOR_LEN;

	} else if (left > 0) {
		return _FAIL;
	}

	//pairwise_cipher
	if (left >= 2)
	{
	        //count = le16_to_cpu(*(u16 *)pos);
		count = RTW_GET_LE16(pos);
		pos += 2;
		left -= 2;

		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
			return _FAIL;
		}

		for (i = 0; i < count; i++)
		{
			*pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);

			pos += RSN_SELECTOR_LEN;
			left -= RSN_SELECTOR_LEN;
		}

	}
	else if (left == 1)
	{
		return _FAIL;
	}

	if (is_8021x) {
		if (left >= 6) {
			pos += 2;
			if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) {
				*is_8021x = 1;
			}
		}
	}

	return ret;

}
Exemple #10
0
int rtw_parse_wpa_ie(uint8_t * wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
{
	int i, ret=_SUCCESS;
	int left, count;
	uint8_t *pos;
	uint8_t SUITE_1X[4] = {0x00, 0x50, 0xf2, 1};

	if (wpa_ie_len <= 0) {
		/* No WPA IE - fail silently */
		return _FAIL;
	}


	if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (uint8_t)(wpa_ie_len - 2)) ||
	   (_rtw_memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != true) )
	{
		return _FAIL;
	}

	pos = wpa_ie;

	pos += 8;
	left = wpa_ie_len - 8;


	//group_cipher
	if (left >= WPA_SELECTOR_LEN) {

		*group_cipher = rtw_get_wpa_cipher_suite(pos);

		pos += WPA_SELECTOR_LEN;
		left -= WPA_SELECTOR_LEN;

	}
	else if (left > 0)
	{
		return _FAIL;
	}


	//pairwise_cipher
	if (left >= 2)
	{
                //count = le16_to_cpu(*(u16 *)pos);
		count = RTW_GET_LE16(pos);
		pos += 2;
		left -= 2;

		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
			return _FAIL;
		}

		for (i = 0; i < count; i++)
		{
			*pairwise_cipher |= rtw_get_wpa_cipher_suite(pos);

			pos += WPA_SELECTOR_LEN;
			left -= WPA_SELECTOR_LEN;
		}

	}
	else if (left == 1)
	{
		return _FAIL;
	}

	if (is_8021x) {
		if (left >= 6) {
			pos += 2;
			if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) {
				*is_8021x = 1;
			}
		}
	}

	return ret;

}