📄 icmp.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 + -