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

📄 arp.c

📁 RTL8019以太网开发板资料
💻 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 + -