📄 arp.c
字号:
#include "main.h"
#include "ARP.h"
#include "ip.h"
/*************************************************************************************/
bit ARPFinishFlag; // ARP完成标志
bit IPConflitTestFlag; // IP冲突测试
bit IPOrMacConfiltFlag; // IP,MAC冲突标志
bit StartConfiltLedFlag; // 冲突时启动快闪
/************************************************************************/
xdata ST_ARP_FORMAT ArpRequestFormat; // ARP帧请求格式
xdata ST_ARP_FORMAT ArpAnswerFormat; // ARP应答格式
xdata ST_ARP_CACHE ArpCache_Buf[REMOTE_IP_NUM]; // ARP高速缓存
UWORK8 IpModeNum; // 在不同模式下IP数据不一样
UWORK8 ArpCachePoniter; // ARP高速缓存指针
xdata UWORK8 gucARPOddNum; // 老化后,ARP完不成的次数
xdata UWORK8 ArpPhases; //ARP阶段
/*********************************************************************
函数名: void ArpProcess(void)
功能: ARP应答,因为是接收一帧处理一帧,不用返回成功失败
输入: 接收的帧是ARP帧
输出: 回应ARP查询
返回: None
日期: 2004/12/11
*********************************************************************/
void ArpProcess(void)
{
xdata ST_ARP_FORMAT *pArpRcv;
UWORK8 ucLoop;
pArpRcv = (ST_ARP_FORMAT *)&gstaRevEthernet.ucaPacket[0]; // 指向ARP数据包内容
if((HTYPE == pArpRcv->usHTYPE) && (PTYPE == pArpRcv->usPTYPE) // 验证是否是以太网ARP
&&(HLEN == pArpRcv->ucHLEN) && (PLEN == pArpRcv->ucPLEN))
{
if((0 == memcmp(&pArpRcv->ucaSHA[0],&NetParameter.MAC_Local_buf[0],MAC_LEN)) //发送端的IP或MAC与本地IP或MAC相同则表示有冲突
|| (0 == memcmp(&pArpRcv->ucaSPA[0],&IPLocalAddress_buf[0],IP_LEN)))
{
IPOrMacConfiltFlag = TRUE;
ARPFinishFlag = FALSE; // 清ARP完成标志
StopArpCounter(); // 检测到冲突,停止ARP相关计数器
StartTimer(12,400); // 4秒种后再次检测
}
switch(pArpRcv->usOPER)
{
case OPER_REQUEST: // 收到ARP请求帧
memcpy(&ArpAnswerFormat.ucaTHA[0],&pArpRcv->ucaSHA[0],MAC_LEN); // ARP应答
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应答帧
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完成标志
if('r' != ArpCache_Buf[ucLoop].ucStatus)
{
ArpCache_Buf[ucLoop].ucStatus = 'r';
}
else // 此时应该是老化阶段,停止了定时器6,需要打开定时器4来启动定时器7
{
StopTimer(6);
gucARPOddNum = 0; // 有了回应,老化计数器清零
StartTimer(4,10); // 定时器4来启动定时器7
}
break;
}
}
break;
default:
break;
}
}
}
/*********************************************************************
函数名: void ArpStartRequest(UWORK8 *pucaIP)
功能: ARP请求
输入: ARP请求需要
输出: 组ARP请求包
返回: None
日期: 2004/12/19
修改: 2006/6/01
*********************************************************************/
void ArpStartRequest(UWORK8 *pucaIP)
{ // 以太网头
memset(&MAC_Remote_buf[0],0xff,MAC_LEN); // 发广播包
MAC_Remote_buf[12] = 0x08;
MAC_Remote_buf[13] = 0x06;
ArpRequestFormat.usOPER = OPER_REQUEST; // ARP请求
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冲突测试
{
StartTimer(5,501); // 启动IP冲突超时
}
}
/*********************************************************************
函数名: void StopArpCounter(void)
功能: 停止ARP相关的计数器
输入: 检测到了IP或MAC冲突
输出: 停止ARP
返回: None
日期: 2006/06/22
*********************************************************************/
void StopArpCounter(void)
{
StopTimer(5);
StopTimer(6);
StopTimer(7);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -