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

📄 ge_arp.c

📁 程序是一个vxworks下对PMC公司3386千兆MAC芯片的驱动和配置
💻 C
📖 第 1 页 / 共 3 页
字号:
		{
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM,"GE_ReadOutfpgaReqfifo:sem take failed!\n");
			return ERROR;
		}
              	pEntry->liveTime=0;
              	if(semGive(GE_ArpSemId)==ERROR)
		{
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM,"GE_ReadOutfpgaReqfifo:sem Give failed!\n");
			return ERROR;
		}
		if(GE_EventReport(2,SYS_UNKNOWN_PORT,WARN_CAM_ERROR,SYS_UNKNOWN_RESULT)	==ERROR)
		{
			return ERROR;
		}              	
              	cam_add(addrCount,nextIp,*(ULONG*)&pEntry->PhyAddr[0],(ULONG)(*(unsigned short*)&pEntry->PhyAddr[4]));
	}
        return OK;
}

/*****************************************************************************
* receive all the data which INFPGA/OUTFPA send to CPU
* input FPGA send ARP packet to CPU for process
* output FPGA send IP address to CPU for CPU send ARP REQ for it.
* return:OK;ERROR;
*/

STATUS  GE_Arp_packet_receive(unsigned char unit,ULONG * arpInBuf)
{
	ARP_PKT_STRUCTURE  		*pArpPkt;
	IP_MAC_BAND      		*pNewEntry;
	IP_MAC_BAND       		*pEntry;
        ULONG                            macHigh;
        ULONG                            macLow;
	
	pArpPkt=(ARP_PKT_STRUCTURE*)(arpInBuf+1);
	if( (netIf[unit].ipAddr & netIf[unit].ipMask) != (*(ULONG *)(pArpPkt->arSpa) & netIf[unit].ipMask) )
	{
		/*if(GE_ARP_DEBUG)
		        GE_printf(GE_ALARM,"GE_Arp_packet_receive:this ip is not belong this net!\n");*/
		return  ERROR;
	}
	if(GE_Check_valid_for_arp_packet(unit,pArpPkt) == ERROR)
  	{ 
           	if(GE_ARP_DEBUG)
           	        GE_printf(GE_ALARM,"GE_Arp_packet_receive:The packet received is invalid!\n");
   		return   ERROR;        
  	}
	pEntry =(IP_MAC_BAND*)GE_Arp_entry_lookup( unit, *(ULONG *)(pArpPkt->arSpa));
        if(pEntry!=NULL) 	/*if find the entry, refresh it */
        {
		taskSafe();
		if(semTake(GE_ArpSemId,WAIT_FOREVER)==OK)
		{
			pEntry->liveTime =0;
		}
		else
		{
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM,"GE_Arp_packet_receive;sem take failed!\n");
			return ERROR;
		}
		if(semGive(GE_ArpSemId)==ERROR)
		{
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM,"GE_Arp_packet_receive:sem give failed!\n");
			return ERROR;
		}
		taskUnsafe();
		/*if MAC address not same, refresh CAM*/
		
		if (bcmp(pEntry->PhyAddr, pArpPkt->arSha, MAC_ADD_SIZ) != 0) 
			/* if it is same, return 0 */
		{
			taskSafe();
			if(semTake(GE_ArpSemId,WAIT_FOREVER)==OK)
			{
				bcopy(pArpPkt->arSha, pEntry->PhyAddr,  MAC_ADD_SIZ);
			}
			else
			{
				if(GE_ARP_DEBUG)
				        GE_printf(GE_ALARM,"GE_Arp_packet_receive;sem take failed!\n");
				return ERROR;
			}
			if(semGive(GE_ArpSemId)==ERROR)
			{
				if(GE_ARP_DEBUG)
				        GE_printf(GE_ALARM,"GE_Arp_packet_receive:sem give failed!\n");
				return ERROR;
			}
			taskUnsafe();
                	cam_del(pEntry->addrCount);
                	cam_add(pEntry->addrCount,(*(ULONG*)pArpPkt->arSpa),*(ULONG*)&pEntry->PhyAddr[0],(ULONG)(*(unsigned short*)&pEntry->PhyAddr[4]) );
			/*merge_flag=TRUE; */
		}
	}

        else if(pEntry==NULL)	/*not find this entry,add it.*/
        {
        	pNewEntry = (IP_MAC_BAND* )SBSL_MemAlloc (GE_ARP_TASK_CODE,sizeof(IP_MAC_BAND));
        	assert (pNewEntry != NULL);
        	taskSafe();  
        	if(semTake(GE_ArpSemId,WAIT_FOREVER)==OK)
        	{
        		            	
			pNewEntry->liveTime = 0;	
			bcopy(pArpPkt->arSha, pNewEntry->PhyAddr, MAC_ADD_SIZ);
			pNewEntry->proAddr = *(ULONG*)(pArpPkt->arSpa);
			pNewEntry->addrCount=addrCount;
		}
		else
		{
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM,"GE_Arp_packet_receive:sem take failed!\n");
			return ERROR;
		}
		if(semGive(GE_ArpSemId)==ERROR)
		{
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM,"GE_Arp_packet_receive:sem give failed!\n");
			return ERROR;
		}
		taskUnsafe();
		if(GE_ArpTableAdd (unit, pNewEntry)!=OK)
		{
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM, "GE_Arp_packet_receive:Add this entry into table failed!\n");
			SBSL_MemFree(GE_ARP_TASK_CODE,(void*)pNewEntry);
			return ERROR;
        	}  
        	macHigh=*(ULONG*)&pNewEntry->PhyAddr[0];
        	macLow = ((*(ULONG*)&pNewEntry->PhyAddr[2]) & 0x0000ffff)<<16;
        	if(cam_add(pNewEntry->addrCount,pNewEntry->proAddr,macHigh,macLow))
		{								
			if(GE_ARP_DEBUG)
			        GE_printf(GE_ALARM,"\n--------- GE_Arp_packet_receive: cam_add error! -------\n");
        		return  ERROR;
		}
        }
        
        
	if(pArpPkt->arOp == ARP_REQ)   
	{
        	arpInfo[unit].requestIn++;            /* count these */
		if((netIf[unit].ipAddr) != (*(ULONG *)(pArpPkt->arTpa)))
  		{
        		/*if(GE_ARP_DEBUG)
                		GE_printf(GE_ALARM,"GE_Arp_packet_receive:This arp packet from %lu is not my ipaddress!\n",*(ULONG*)&(pArpPkt->arSpa[0]));*/
        		return  ERROR;
        	}
		GE_Arp_send_reply (unit, arpInBuf);
		arpInfo[unit].replyOut++;	   
        	return  OK;
       	}
	else  
	{
		if (pArpPkt->arOp == ARP_REP)  /* ARP reply, count and fall thru to logic to update table */
        	{
			arpInfo[unit].replyIn++;		  
			return  OK;
		}
		else
		{
      	  		arpInfo[unit].err++;	
			return  OK;
		}
	}

	
}

/*****************************************************************************************/
STATUS GE_Check_valid_for_arp_packet (unsigned char  unit,ARP_PKT_STRUCTURE * pArpPkt)
{
    	/* hardware Type error!*/    	    
    	if (pArpPkt->arHd != ETH_HW)
        {
	    	arpInfo[unit].err++;
    		return ERROR;
    	}
	/* proto type error */
     	if (pArpPkt->arPro!= IP_PROTO )
    	{
	    	arpInfo[unit].err++;
	    	return ERROR;
    	}
     	/* hardware address length error */
     	if (pArpPkt->arHln != MAC_ADD_SIZ)
    	{
    		arpInfo[unit].err++;
    		return ERROR;
        }
	/* proto address length error */
     	if (pArpPkt->arPln != IP_ADD_SIZ)
    	{
    		arpInfo[unit].err++;
    		return ERROR;
    	}
   	return OK;
}
/*****************************************************************************************/
STATUS GE_Arp_request_packet_generation (unsigned char unit,ULONG ipAddr)
{
	TASK_MSG	        TaskMsg;		
    	ARP_PKT_STRUCTURE * 	pBuf;
        unsigned char           DMAC[MAC_ADD_SIZ];
        unsigned char           SMAC[MAC_ADD_SIZ];
           	
    	pBuf=(ARP_PKT_STRUCTURE *)SBSL_MemAlloc (GE_ARP_TASK_CODE, sizeof(ARP_PKT_STRUCTURE));	
    	assert (pBuf != NULL);
     
	/* fill arp req packet */	
	bfill (&DMAC[0], MAC_ADD_SIZ, 0xFF);
	bcopy (arpInfo[unit].selfPhyAddress, SMAC, MAC_ADD_SIZ); 

	pBuf->arHd 	= ETH_HW;
	pBuf->arPro 	= IP_PROTO;
	pBuf->arHln 	= MAC_ADD_SIZ;
	pBuf->arPln 	= IP_ADD_SIZ;
	pBuf->arOp 	= ARP_REQ;

	bcopy (arpInfo[unit].selfPhyAddress, pBuf->arSha, MAC_ADD_SIZ); 
	*(ULONG *)(pBuf->arSpa) = netIf[unit].ipAddr;
	bfill (pBuf->arTha, MAC_ADD_SIZ, 0xFF);
	*(ULONG*)(&pBuf->arTpa[0])=ipAddr;
	TaskMsg.taskCode = GE_ARP_TASK_CODE;
	TaskMsg.type = ARP_PROTO;
	TaskMsg.length = sizeof(ARP_PKT_STRUCTURE)+18;
	memset(TaskMsg.msgBuf,0,128);
	*(ULONG*)&TaskMsg.msgBuf[0]=(ULONG)unit;
	bcopy(&DMAC[0],&TaskMsg.msgBuf[4],MAC_ADD_SIZ);
	bcopy(&SMAC[0],&TaskMsg.msgBuf[10],MAC_ADD_SIZ);
	*(USHORT*)&TaskMsg.msgBuf[16]=ARP_PROTO;		 	
	memcpy((void *)(&(TaskMsg.msgBuf[18])), (void *)pBuf, sizeof(ARP_PKT_STRUCTURE));

	if(SBSL_TaskIdGet(GE_PROTO_SEND_TASK_CODE)==NULL)
	{
		if(GE_ARP_DEBUG)
		        GE_printf(GE_ALARM,"GE_Arp_request_packet_generation:ALARM!PROTO_SEND_TASK has not register!\n");
		return ERROR;
	}	
        if (msgQSend (SBSL_TaskMsgIdGet(GE_PROTO_SEND_TASK_CODE),
			(char *)(&TaskMsg),
			140,
			NO_WAIT,
			MSG_PRI_NORMAL )== ERROR)
	{
             	if(GE_ARP_DEBUG)
             	        GE_printf(GE_ALARM,"GE_Arp_request_packet_generation:send arp packet to TprotoSend failed!\n");
             	SBSL_MemFree(GE_ARP_TASK_CODE,pBuf);
             	return ERROR;
             
	}
        else 
        {
          	if(GE_ARP_DEBUG)
          	        GE_printf(GE_EVENT,"GE_Arp_request_packet_generation:send arp packet to TprotoSend succeed!\n");
		arpInfo[unit].requestOut++;
         	SBSL_MemFree(GE_ARP_TASK_CODE,pBuf);
        } 
            
  	return OK;
} 
/*****************************************************************************************/
unsigned char hashFun(ULONG ipAddr)
{	
	unsigned char IP[4];
	int i;
	
	IP[0]=(unsigned char)((ipAddr&0xFF000000)>>24);
	IP[1]=(unsigned char)((ipAddr&0x00FF0000)>>16);
	IP[2]=(unsigned char)((ipAddr&0x0000FF00)>>8);
	IP[3]=(unsigned char)((ipAddr&0x000000FF));	
	i=(IP[0]+IP[1]+IP[2]+IP[3])/4;
	return(i);
}
/**********************************************************************************
* for given ipAddr lookupentry.
*/
IP_MAC_BAND *GE_Arp_entry_lookup(unsigned char unit, ULONG ipAddr)
{
	unsigned int i,j,k;
	IP_MAC_BAND *pEntry;
	IP_MAC_BAND   	TmpEntry;
	i=hashFun(ipAddr);
	j=unit;	

	for(k=0;k<static_table_sums;k++)
	{
		if(ipAddr == static_next_ip[k])
		{
			bcopy( (char*)(static_mac+k*6) , TmpEntry.PhyAddr , MAC_ADD_SIZ );
			pEntry = &TmpEntry;	
			return pEntry;		
		}		
	}
	taskSafe();
	if(semTake(GE_ArpSemId,WAIT_FOREVER)==OK)
	{
		if ((IP_MAC_BAND* )(hashValue[i].ArpList[j].next)==NULL)
  		{
  			if(semGive(GE_ArpSemId)==ERROR)
			{
				if(GE_ARP_DEBUG)
				        GE_printf(GE_ALARM,"GE_Arp_entry_lookup:sem Take failed!\n");
			}		
			taskUnsafe();
  			return NULL;
  		} 
		else
 		{
    	    		for ( 	pEntry = (IP_MAC_BAND* )(hashValue[i].ArpList[j].next);
	  			pEntry != NULL; 
				pEntry = (IP_MAC_BAND* )(pEntry->next) )
            		{
    	      			if ( pEntry->proAddr == ipAddr )
				{                        
  					if(semGive(GE_ArpSemId)==ERROR)
					{
						if(GE_ARP_DEBUG)
						        GE_printf(GE_ALARM,"GE_Arp_entry_lookup:sem give failed!\n");
					}		
					taskUnsafe();					
                			return pEntry;
				}
     	    		}   
		}
	}
	else 
	{
		if(GE_ARP_DEBUG)
		        GE_printf(GE_ALARM,"GE_Arp_entry_lookup:sem Take failed!\n");
		return NULL ;
	}
	if(semGive(GE_ArpSemId)==ERROR)
	{
		if(GE_ARP_DEBUG)
		        GE_printf(GE_ALARM,"GE_Arp_entry_lookup:sem Give failed!\n");
		return NULL;
	}		
	taskUnsafe();
	return NULL;
}  

/*****************************************************************************************/
 STATUS  GE_Arp_send_reply (unsigned char unit, ULONG * arpInBuf)                                  
{                                                                                                  
                                                                                                   
	ARP_PKT_STRUCTURE 		*pArpPkt; 
 	unsigned char			SIP[IP_ADD_SIZ];
	unsigned char                   ARP_PKT[44]; 

        (ULONG*)pArpPkt= arpInBuf+1; 
        bcopy(pArpPkt->arSha,(char*)&ARP_PKT,MAC_ADD_SIZ);
	bcopy (arpInfo[unit].selfPhyAddress,(char*)&ARP_PKT[6], MAC_ADD_SIZ);
	*(ULONG*)&ARP_PKT[12]=0x08060001;
	*(ULONG*)&ARP_PKT[16]=0x08000604;
	*(unsigned short int*)&ARP_PKT[20]=0x0002;
	bcopy(arpInfo[unit].selfPhyAddress,(char*)&ARP_PKT[22], MAC_ADD_SIZ);
	bcopy(pArpPkt->arTpa,(char*)&ARP_PKT[28],IP_ADD_SIZ);
	bcopy(pArpPkt->arSha,(char*)&ARP_PKT[32],MAC_ADD_SIZ);
	bcopy(pArpPkt->arSpa,(char*)&ARP_PKT[38],IP_ADD_SIZ);
            
   	GE_WritePktToOutfpga((ULONG*)&ARP_PKT[0],44,unit);
 
	return OK;	                                                                           
}   

/*****************************************************************************************/
STATUS GE_ArpTableAdd(unsigned char unit,IP_MAC_BAND * pNewEntry)
{
    	unsigned char 	i,j;
        ULONG		ipAddr;	  
	ULONG		macHigh;
	ULONG		macLow;
	IP_MAC_BAND*	pEntry;
	IP_MAC_BAND*	pHead=NULL;
               
    	ipAddr=pNewEntry->proAddr;
	i=hashFun(ipAddr);
	j=unit;	
	if(semTake(GE_ArpSemId,WAIT_FOREVER)==ERROR)
	{
		if(GE_ARP_DEBUG)
		        GE_printf(GE_ALARM,"GE_ArpTableAdd:sem take failed!\n");
		return ERROR;
	}
    	if( (IP_MAC_BAND* )(hashValue[i].ArpList[j].next)==NULL )
    	{
   		(IP_MAC_BAND* )hashValue[i].ArpList[j].next=(IP_MAC_BAND*)pNewEntry;
    		pHead=(IP_MAC_BAND* )hashValue[i].ArpList[j].next; 
   		pHead->next=NULL;
    	}    
    	else 
    	{
    		for ( 	pEntry = (IP_MAC_BAND* )(hashValue[i].ArpList[j].next);;
			pEntry = (IP_MAC_BAND* )(pEntry->next) )
		{
			if( (pEntry->next) == NULL )
			break; 	
		}
		pNewEntry->next=NULL;
		(pEntry->next)=(IP_MAC_BAND*)pNewEntry;
    	}	

⌨️ 快捷键说明

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