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

📄 icmp.c

📁 RTL8019以太网开发板资料
💻 C
字号:
#include "icmp.h"
#include "main.h"
#include "ip.h"
#include "tcp.h"
/*********************************************************************
函数名:       void IcmpReceive(UWORK16 usTotalLen)
功能:         Icmp处理,因为是接收一帧处理一帧,不用返回成功失败
输入:         IP包数据长度 
输出:         处理Icmp分组
返回:         None
日期:         2004/12/21
*********************************************************************/
void IcmpReceive(UWORK16 usTotalLen)
{
    ST_ICMP_HEAD_FORMAT *pIcmpHead;
    ST_IP_HEAD_FORMAT *pIpHeadBuff;
    UWORK16 usLoop,usRes,usCheckSum;
    UWORK8 ucNum;

    if(FALSE == gbHaveFragment)
    {
        pIcmpHead = (ST_ICMP_HEAD_FORMAT *)&gstaRevEthernet.ucaPacket[20];      // 指向ICMP头 
        usCheckSum = CheckSum((UWORK16 *)&gstaRevEthernet.ucaPacket[20],usTotalLen);
        pIpHeadBuff = (ST_IP_HEAD_FORMAT *)&gstaRevEthernet.ucaPacket[0];
    }
    else
    {
        pIcmpHead = (ST_ICMP_HEAD_FORMAT *)&gucaSegTemp[20];
        usCheckSum = CheckSum((UWORK16 *)&gucaSegTemp[20],usTotalLen);
        pIpHeadBuff = (ST_IP_HEAD_FORMAT *)&gucaSegTemp[0];
    }
    if(0x0000 != usCheckSum)
    {
        return;                                                                  // 校验和错误,返回 
    }
    
    switch(pIcmpHead->ucType)
    {   
        case ICMP_ECHO:                                                          // 目的端的回送请求 
            
                        // 组帧应答 
            pIcmpHead->ucType = ICMP_ECHO_REPLY;                                 // 应答 
            pIcmpHead->usCheckSum = 0x00;            
                        // IP头            
            gstIphead.usID = ++LocalIpID;
            gstIphead.ucprotocol = 0x01;                                         // ICMP协议            
            memcpy(&gstIphead.ucSourceIP[0],&IPLocalAddress_buf[0],IP_LEN);           // 原IP地址 
            memcpy(&gstIphead.ucDestIP[0],&pIpHeadBuff->ucSourceIP[0],IP_LEN);   // 目的IP地址
            memcpy(&MAC_Remote_buf[0],&gstaRevEthernet.ucaSourceNodID[0],NOD_ID_LENGTH);  // 目的MAC地址 
            
            if(FALSE == gbHaveFragment)                                        // 没有分片的数据 
            {                                  // 计算ICMP校验和 
                pIcmpHead->usCheckSum = CheckSum((UWORK16 *)&gstaRevEthernet.ucaPacket[20],usTotalLen);
                gstIphead.usSegOffset = 0;
                gstIphead.usTotalLen = 20 + usTotalLen;                
                memcpy(&NetSend_buf[20],&gstaRevEthernet.ucaPacket[20],usTotalLen);   // 拷贝数据到发送缓冲              
                IpSend();
            }
            else
            {                // 计算ICMP校验和 
                pIcmpHead->usCheckSum = CheckSum((UWORK16 *)&gucaSegTemp[20],usTotalLen);
                ucNum = (UWORK8)(usTotalLen / 1480);
                usRes = usTotalLen % 1480;
                
                gstIphead.usTotalLen = 20 + 1480;
                
                for(usLoop = 0; usLoop < ucNum; usLoop++)
                {
                    if((0 == usRes) && (ucNum == (usLoop + 1)))                 // 数据为1480的整数倍且是最后一帧数据
                    {
                        gstIphead.usSegOffset = usLoop * (1480 / 8);
                    }
                    else
                    {
                        gstIphead.usSegOffset = 0x2000 + usLoop * (1480 / 8);   // 不是最后一帧数据,需要将IP的more fragment位置1,所以要加上"0x2000" 
                    }                  
                    memcpy(&NetSend_buf[20],&gucaSegTemp[usLoop * 1480 + 20],1480);   // 拷贝数据到发送缓冲
                    IpSend();
                }
                if(0 != usRes)
                {
                    gstIphead.usTotalLen = 20 + usRes;
                    gstIphead.usSegOffset = usLoop * (1480 / 8);                    
                    memcpy(&NetSend_buf[20],&gucaSegTemp[usLoop * 1480 + 20],usRes);  // 拷贝数据到发送缓冲 
                    IpSend();
                }
            }
            break;

        default:
            break;
    }
}

⌨️ 快捷键说明

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