📄 ge_arp.c
字号:
{
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 + -