?? arp.c
字號(hào):
#include "main.h"
#include "ARP.h"
#include "ip.h"
/*************************************************************************************/
bit ARPFinishFlag; // ARP完成標(biāo)志
bit IPConflitTestFlag; // IP沖突測(cè)試
bit IPOrMacConfiltFlag; // IP,MAC沖突標(biāo)志
bit StartConfiltLedFlag; // 沖突時(shí)啟動(dòng)快閃
/************************************************************************/
xdata ST_ARP_FORMAT ArpRequestFormat; // ARP幀請(qǐng)求格式
xdata ST_ARP_FORMAT ArpAnswerFormat; // ARP應(yīng)答格式
xdata ST_ARP_CACHE ArpCache_Buf[REMOTE_IP_NUM]; // ARP高速緩存
UWORK8 IpModeNum; // 在不同模式下IP數(shù)據(jù)不一樣
UWORK8 ArpCachePoniter; // ARP高速緩存指針
xdata UWORK8 gucARPOddNum; // 老化后,ARP完不成的次數(shù)
xdata UWORK8 ArpPhases; //ARP階段
/*********************************************************************
函數(shù)名: void ArpProcess(void)
功能: ARP應(yīng)答,因?yàn)槭墙邮找粠幚硪粠?不用返回成功失敗
輸入: 接收的幀是ARP幀
輸出: 回應(yīng)ARP查詢
返回: None
日期: 2004/12/11
*********************************************************************/
void ArpProcess(void)
{
xdata ST_ARP_FORMAT *pArpRcv;
UWORK8 ucLoop;
pArpRcv = (ST_ARP_FORMAT *)&gstaRevEthernet.ucaPacket[0]; // 指向ARP數(shù)據(jù)包內(nèi)容
if((HTYPE == pArpRcv->usHTYPE) && (PTYPE == pArpRcv->usPTYPE) // 驗(yàn)證是否是以太網(wǎng)ARP
&&(HLEN == pArpRcv->ucHLEN) && (PLEN == pArpRcv->ucPLEN))
{
if((0 == memcmp(&pArpRcv->ucaSHA[0],&NetParameter.MAC_Local_buf[0],MAC_LEN)) //發(fā)送端的IP或MAC與本地IP或MAC相同則表示有沖突
|| (0 == memcmp(&pArpRcv->ucaSPA[0],&IPLocalAddress_buf[0],IP_LEN)))
{
IPOrMacConfiltFlag = TRUE;
ARPFinishFlag = FALSE; // 清ARP完成標(biāo)志
StopArpCounter(); // 檢測(cè)到?jīng)_突,停止ARP相關(guān)計(jì)數(shù)器
StartTimer(12,400); // 4秒種后再次檢測(cè)
}
switch(pArpRcv->usOPER)
{
case OPER_REQUEST: // 收到ARP請(qǐng)求幀
memcpy(&ArpAnswerFormat.ucaTHA[0],&pArpRcv->ucaSHA[0],MAC_LEN); // ARP應(yīng)答
memcpy(&ArpAnswerFormat.ucaTPA[0],&pArpRcv->ucaSPA[0],IP_LEN);
memcpy(&ArpAnswerFormat.ucaSPA[0],&IPLocalAddress_buf[0],IP_LEN);
memcpy(&NetSend_buf[0],&ArpAnswerFormat,sizeof(ArpAnswerFormat));
memcpy(&MAC_Remote_buf[0],&pArpRcv->ucaSHA[0],MAC_LEN);
MAC_Remote_buf[12] = 0x08;
MAC_Remote_buf[13] = 0x06;
SendEthernetPacket(28);
break;
case OPER_APLY: // 收到ARP應(yīng)答幀
for(ucLoop = 0; ucLoop < IpModeNum; ucLoop++)
{
if(0 == memcmp(&ArpCache_Buf[ucLoop].ucaArpIp[0],&pArpRcv->ucaSPA[0],IP_LEN))
{
memcpy(&ArpCache_Buf[ucLoop].ucaMAC[0],&pArpRcv->ucaSHA[0],MAC_LEN);
ARPFinishFlag = TRUE; // 置ARP完成標(biāo)志
if('r' != ArpCache_Buf[ucLoop].ucStatus)
{
ArpCache_Buf[ucLoop].ucStatus = 'r';
}
else // 此時(shí)應(yīng)該是老化階段,停止了定時(shí)器6,需要打開定時(shí)器4來啟動(dòng)定時(shí)器7
{
StopTimer(6);
gucARPOddNum = 0; // 有了回應(yīng),老化計(jì)數(shù)器清零
StartTimer(4,10); // 定時(shí)器4來啟動(dòng)定時(shí)器7
}
break;
}
}
break;
default:
break;
}
}
}
/*********************************************************************
函數(shù)名: void ArpStartRequest(UWORK8 *pucaIP)
功能: ARP請(qǐng)求
輸入: ARP請(qǐng)求需要
輸出: 組ARP請(qǐng)求包
返回: None
日期: 2004/12/19
修改: 2006/6/01
*********************************************************************/
void ArpStartRequest(UWORK8 *pucaIP)
{ // 以太網(wǎng)頭
memset(&MAC_Remote_buf[0],0xff,MAC_LEN); // 發(fā)廣播包
MAC_Remote_buf[12] = 0x08;
MAC_Remote_buf[13] = 0x06;
ArpRequestFormat.usOPER = OPER_REQUEST; // ARP請(qǐng)求
memcpy(&ArpRequestFormat.ucaTPA[0],pucaIP,IP_LEN); // 目的IP
memcpy(&ArpRequestFormat.ucaSPA[0],&IPLocalAddress_buf[0],IP_LEN); // 源IP
memcpy(&NetSend_buf[0],&ArpRequestFormat,sizeof(ArpRequestFormat));
SendEthernetPacket(28);
if(IPConflitTestFlag) // IP沖突測(cè)試
{
StartTimer(5,501); // 啟動(dòng)IP沖突超時(shí)
}
}
/*********************************************************************
函數(shù)名: void StopArpCounter(void)
功能: 停止ARP相關(guān)的計(jì)數(shù)器
輸入: 檢測(cè)到了IP或MAC沖突
輸出: 停止ARP
返回: None
日期: 2006/06/22
*********************************************************************/
void StopArpCounter(void)
{
StopTimer(5);
StopTimer(6);
StopTimer(7);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -