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

📄 dot1xauth.c

📁 dot1x认证源码,包括dot1x数据包的收发,认证的配置,MIB的设计等
💻 C
📖 第 1 页 / 共 5 页
字号:
void dot1xHandleDot1xPkt(Dot1xMessage_t *pMsg)
{
	STATUS rc;
	Dot1xAuthUserNode_t *pUserNode = NULL;
	struct Eap_Private_Field *pPrivate_Field = NULL;
	struct Eapol_Header *pEapol_Hdr = NULL;
	struct Eap_Type_Header *pEap_Hdr = NULL;
	int index;
	u_long reason = MSG_NO_MESSAGE;
	u_short vlan;

	Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_DEBUG, RECV_EVENT_HANDLE, "into dot1xHandleDot1xPkt");

	TotalDot1xStat.dot1xAuthEapolFramesRx++;
	memcpy((char *)&vlan, (char *)&pMsg->UserKey[6], 2);
	Dot1xStat[vlan].dot1xAuthEapolFramesRx++;

	if (pMsg->buf == NULL)
	{	
  		Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "receive NULL dot1x Pkt!");
		return ;
	}

	/*-------verify packet------*/
	rc = dot1xFilterRecvPkt(pMsg);
	if (rc != OK )
	{
  		Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "Eapol packet verify invalid!");
		return ;
	}

	rc = dot1xFindUserNode(pMsg->UserKey, &pUserNode);
	if (rc != OK)
		pUserNode = NULL;
	
	/* pointer to eapol packet header */
	pEapol_Hdr = (struct Eapol_Header *)pMsg->buf;
	if (pEapol_Hdr->eap_type == EAP_Packet)
	{
		pEap_Hdr = (struct Eap_Type_Header *)((char *)pEapol_Hdr + EAPOL_HEADER_LEN );
		pPrivate_Field = (struct Eap_Private_Field *)((char *)pEap_Hdr + pEap_Hdr->len);
	}
	else 
		pPrivate_Field = (struct Eap_Private_Field *)((char *)pEapol_Hdr + EAPOL_HEADER_LEN);

	if (pUserNode != NULL)
	{
		pPrivate_Field->version = htons(pPrivate_Field->version);
		pPrivate_Field->build = htons(pPrivate_Field->build);
		pPrivate_Field->msgType = htonl(pPrivate_Field->msgType);
		
		index = pUserNode->user_config.UserManTemIndex;
		if (UsrManTem[index].CheckFactroy == TRUE)
		{
			if (strcmp(pPrivate_Field->linkageId, MSG_LINKAGE_FACTORY_FLAG) != 0)
			{
  				Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "CheckFactory failure!");
				return;
			}
		}
		reason = pPrivate_Field->msgType;

		if ((UsrManTem[index].CheckClientVersion == TRUE) && (LimitVersion > pPrivate_Field->version))
		{	
			char ErrMsg[100] = {0};
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "CheckVersion failure!");
			sprintf(ErrMsg, "#urgent#%s : %lu.%02lu", "目前系统支持的最低版本为", LimitVersion / 100, LimitVersion % 100);		
			dot1xSend(pUserNode->userInfo.UserMac, pUserNode->userInfo.UserVid, 
				pUserNode->userInfo.PortNum-1, dot1xMsg_Req_Notify, ErrMsg, strlen(ErrMsg), 0, MSG_NO_MESSAGE);
			return;
		}		
	}


	switch (pEapol_Hdr->eap_type)
	{
		case EAPOL_Start:
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDot1xPkt", "receive a start packet!");
			TotalDot1xStat.dot1xAuthEapolStartFramesRx++;
			Dot1xStat[vlan].dot1xAuthEapolStartFramesRx++;
			dot1xStartPktHandler(pUserNode, pMsg->UserKey);
			break;

		case EAPOL_Logoff:
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDot1xPkt", "receive a logoff packet!");
			TotalDot1xStat.dot1xAuthEapolLogoffFramesRx++;
			Dot1xStat[vlan].dot1xAuthEapolLogoffFramesRx++;
	/*		if (pUserNode == NULL)
			{		
				Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "cannot find user!");
				return;
			}
	*/		dot1xLogoffPktHandler(pUserNode, reason);
			break;

		case EAP_Packet:	
			TotalDot1xStat.dot1xAuthEapolRespFramesRx++;
			Dot1xStat[vlan].dot1xAuthEapolRespFramesRx++;
	/*		if (pUserNode == NULL)
			{
				Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "cannot find user!");
				return;
			}
		*/			
			switch (pEap_Hdr->type)
			{
				case EAP_Type_Id:
					Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDot1xPkt", "receive a response Id packet!");
					if ((pEap_Hdr->len - EAP_TYPE_HEADER_LEN) > MAX_USER_NAME_LENGTH
						|| (pEap_Hdr->len - EAP_TYPE_HEADER_LEN) < 0)
					{
						Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "length of user name invalid!");
						TotalDot1xStat.dot1xAuthEapLengthErrorFramesRx++;
						Dot1xStat[vlan].dot1xAuthEapLengthErrorFramesRx++;
						break;
					}
					else 
					{	TotalDot1xStat.dot1xAuthEapolRespIdFramesRx++;
						Dot1xStat[vlan].dot1xAuthEapolRespIdFramesRx++;
						dot1xIDPktHandler(pUserNode, pEap_Hdr);						
					}
					break;

				case EAP_Type_PAP:
					Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDot1xPkt", "receive a response PAP packet!");
					if ((pEap_Hdr->len - EAP_TYPE_HEADER_LEN) > MAX_USER_PASS_LENGTH
						|| (pEap_Hdr->len - EAP_TYPE_HEADER_LEN) < 0)
					{
						Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "length of user password invalid!");
						TotalDot1xStat.dot1xAuthEapLengthErrorFramesRx++;
						Dot1xStat[vlan].dot1xAuthEapLengthErrorFramesRx++;
						break;
					}
					else 
						dot1xPWPktHandler(pUserNode, pEap_Hdr);						
					break;

				case EAP_Type_LCBAP:
					Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDot1xPkt", "receive a response LCBAP packet!");
					if (pEap_Hdr->len - EAP_TYPE_HEADER_LEN < 0)
					{
						Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDot1xPkt", "length of user password invalid!");
						TotalDot1xStat.dot1xAuthEapLengthErrorFramesRx++;
						Dot1xStat[vlan].dot1xAuthEapLengthErrorFramesRx++;
						break;
					}
					dot1xLCPWPktHandler(pUserNode, pEap_Hdr);						
					break;

				case EAP_Type_MD5:
					Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDot1xPkt", "receive a response MD5 packet!");
					dot1xEAPPktHandler(pUserNode, pEap_Hdr);
					break;

				default:
					TotalDot1xStat.dot1xAuthInvalidEapolFramesRx++;
					Dot1xStat[vlan].dot1xAuthInvalidEapolFramesRx++;
			}
			break;

		default:
			TotalDot1xStat.dot1xAuthInvalidEapolFramesRx++;
			Dot1xStat[vlan].dot1xAuthInvalidEapolFramesRx++;
	}

}

void dot1xHandleDHCPMsg(Dot1xMessage_t *pMsg)
{
	STATUS rc;
	DHCPMsg_t *pDhcpMsg = NULL;
	Dot1xAuthUserNode_t *pUserNode;

	Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_DEBUG, RECV_EVENT_HANDLE, "into dot1xHandleDHCPMsg");
	rc = dot1xFindUserNode((void *)pMsg->UserKey, &pUserNode);
	if (pUserNode == NULL)
	{
		Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDHCPMsg", "cannot find user!");
		return ;
	}

	pDhcpMsg = (DHCPMsg_t *)pMsg->buf;
	if (pMsg->buf == NULL)
	{	
  		Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleDHCPMsg", "receive NULL dhcp message!");
		return ;
	}
	switch (pDhcpMsg->Type)
	{
		case DHCP_SUCCESSFUL:
			gRecvDHCPSuccMsgNum++;
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDHCPMsg", "receive dhcp-success message!");
			if (((pUserNode->user_state == USER_ON_LINE) || (pUserNode->user_state == ON_LINE_CONFIRM))
				&&pUserNode->AcctBeginTime == 0)
			{
				Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDHCPMsg", "handle dhcp-success message!");
				pUserNode->userInfo.UserIp = pDhcpMsg->userIP;
				if (pUserNode->AuthLocation == LocalAuthenticate)
					ToNewState(LET_NET_OPEN, 1, pUserNode, NULL);
				else
					ToNewState(REQUEST_ACCT_START, 1, pUserNode, NULL);
			}
			else
				Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_WARNING, "dot1xHandleDHCPMsg", "user state error!");
			break;

		case DHCP_FAILURE:
			gRecvDHCPFailMsgNum++;
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleDHCPMsg", "handle dhcp-failure message!");
			pUserNode->OffLineReason = MSG_DHCP_ERROR;
			switch (pDhcpMsg->Event)
			{
				case CHOOSE_ADDR_FAIL:	
					gRecvDHCPFailChooseAddrErr ++;
					break;
					
				case VLAN_USER_EXCEED:
					gRecvDHCPFailVlanUserExNum ++;					
					pUserNode->TerminateCause = NAS_ERROR;
					break;
					
				case VLAN_MISMATCH:
					gRecvDHCPFailVlanMismatch ++;
					break;
										
				case SELECT_REQUEST_FAIL:
					gRecvDHCPFailSelectQequest ++;
					break;
					
				case ADDR_COLLISION:
					gRecvDHCPFailAddrColl ++;
					pUserNode->TerminateCause = NAS_ERROR;
					break;
					
				case UPDATE_LEASE_FAIL:
					gRecvDHCPFailUpdateLeaseFail ++;
					pUserNode->TerminateCause = NAS_REQUEST;
					break;
						
				case LEASE_EXPIRE:
					gRecvDHCPFailLeaseExpire ++;
					pUserNode->TerminateCause = NAS_REQUEST;
					break;
						
				case CONFIG_DEL_ADDR:
					gRecvDHCPFailConDelAddr ++;
					pUserNode->TerminateCause = ADMIN_RESET;
					break;
					
				case ADDUSER_MSG_ERR:
					gRecvDHCPFailAddUserMsgErr ++;
					break;

				case UNIT_MISMATCH:
					gRecvDHCPFailUnitMismatch ++;
					break;
			}      
			ToNewState(USER_ABORT, 1, pUserNode, NULL);
			break;
	}
}

void dot1xHandleRadiusMsg(Dot1xMessage_t *pMsg)
{
	STATUS rc;
	Dot1xAuthUserNode_t *pUserNode;
	RadiusMsg_t *pRadiusMsg;

	Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_DEBUG, RECV_EVENT_HANDLE, "into dot1xHandleRadiusMsg");

	rc = dot1xFindUserNode((void *)pMsg->UserKey, &pUserNode);
	if (pUserNode == NULL)
	{
		Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleRadiusMsg", "cannot find user!");
		return ;
	}


	pRadiusMsg = (RadiusMsg_t *)pMsg->buf;
	if (pMsg->buf == NULL)
	{	
  		Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleRadiusMsg", "receive NULL radius message!");
		return ;
	}
	switch (pRadiusMsg->code)
	{
		case Access_Accept:
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleRadiusMsg", "receive radius-success message!");
			gRecvRadiusAuthSucc++;

			switch (pUserNode->user_state)
			{
				case WAIT_AUTH_RESPONSE:
				case WAIT_AUTH_RESULT:
					pUserNode->BandWidth = pRadiusMsg->BandWidth;
					pUserNode->LeftFlowUp = pRadiusMsg->LeftFlow;
					pUserNode->LeftTimeUp = pRadiusMsg->LeftTime;
					strcpy(pUserNode->RealName, pRadiusMsg->RealName);
					ToNewState(AUTH_SUCCESSFUL, 1, pUserNode, NULL);
					break;

				case WAIT_AUTH_RESPONSE_AT_REAUTH:
				case WAIT_AUTH_RESULT_AT_REAUTH:
					ToNewState(ON_LINE_CONFIRM, 1, pUserNode, NULL);
					break;

				default:
					Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_WARNING, "dot1xHandleRadiusMsg", "radius accept: user state error!");
			}
			break;

		case Access_Reject:
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleRadiusMsg", "receive radius-failure message!");
			gRecvRadiusAuthFail++;
			gFailAtWaitAuth++;

			if (pRadiusMsg->failure_Reason != 0)
				pUserNode->OffLineReason = pRadiusMsg->failure_Reason;
			else 
				pUserNode->OffLineReason = MSG_UNKNOWN_ERROR;

			switch (pUserNode->user_state)
			{
				case WAIT_AUTH_RESPONSE:
				case WAIT_AUTH_RESULT:
				case WAIT_CHALLENGE:
					ToNewState(AUTH_FAILURE, 1, pUserNode, NULL);
					break;

				case WAIT_AUTH_RESPONSE_AT_REAUTH:
				case WAIT_AUTH_RESULT_AT_REAUTH:
				case WAIT_EAP_RESPONSE_AT_REAUTH:
					pUserNode->TerminateCause = USER_ERROR;
					ToNewState(USER_ABORT, 1, pUserNode, NULL);
					break;

				default:
					Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_WARNING, "dot1xHandleRadiusMsg", "radius reject: user state error!");
			}
			break;

		case Access_Challenge:
			Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_NOTICE, "dot1xHandleRadiusMsg", "receive radius-challenge message!");
			if (pUserNode->user_state != WAIT_CHALLENGE)
			{
				Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_WARNING, "dot1xHandleRadiusMsg", "radius challenge: user state error!");
				return ;
			}
			/* unfinished */
			break;
	}
}

void dot1xHandleTimeoutMsg(Dot1xMessage_t *pMsg)
{
	STATUS rc;
	Dot1xAuthUserNode_t *pUserNode;

	Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_DEBUG, RECV_EVENT_HANDLE, "into dot1xHandleTimeoutMsg");
	rc = dot1xFindUserNode((void *)pMsg->UserKey, &pUserNode);
	if (pUserNode == NULL)
	{
		Dot1x_logMsgSend(DOT1X_MODULE, SYSLOG_SEVERITY_ERROR, "dot1xHandleTimeoutMsg", "cannot find user!");
		return ;
	}

	switch (pMsg->length)		/* length is replaced by timer type */
	{
		case Wait_ID_Timer:
		case Wait_Pass_Timer:
		case Wait_EAP_Timer:
			dot1xHandleClientTimeout(pUserNode, pMsg->length);
			break;
			
		case Wait_Auth_Timer:
		case Wait_Acct_Timer:
			dot1xHandleRadiusTimeout(pUserNode, pMsg->length);
			break;

		case Re_Auth_Timer:
			dot1xHandleReAuthTimeout(pUserNode);
			break;

		case Wait_DHCP_Timer:
			dot1xHandleDHCPTimeout(pUserNode);
			break;

		case De_Attack_Timer:
			dot1xHandleDeAttackTimeout(pUserNode);
			break;

		
	}
}

void dot1xHandleOtherMsg(Dot1xMessage_t *pMsg)
{
	STATUS rc;
	Dot1xAuthUserNode_t *pUserNode;
	Shutdown_Table_t shutUser;

⌨️ 快捷键说明

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