?? icmp.c
字號:
#include "icmp.h"
#include "main.h"
#include "ip.h"
#include "tcp.h"
/*********************************************************************
函數(shù)名: void IcmpReceive(UWORK16 usTotalLen)
功能: Icmp處理,因為是接收一幀處理一幀,不用返回成功失敗
輸入: IP包數(shù)據(jù)長度
輸出: 處理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: // 目的端的回送請求
// 組幀應(yīng)答
pIcmpHead->ucType = ICMP_ECHO_REPLY; // 應(yīng)答
pIcmpHead->usCheckSum = 0x00;
// IP頭
gstIphead.usID = ++LocalIpID;
gstIphead.ucprotocol = 0x01; // ICMP協(xié)議
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) // 沒有分片的數(shù)據(jù)
{ // 計算ICMP校驗和
pIcmpHead->usCheckSum = CheckSum((UWORK16 *)&gstaRevEthernet.ucaPacket[20],usTotalLen);
gstIphead.usSegOffset = 0;
gstIphead.usTotalLen = 20 + usTotalLen;
memcpy(&NetSend_buf[20],&gstaRevEthernet.ucaPacket[20],usTotalLen); // 拷貝數(shù)據(jù)到發(fā)送緩沖
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))) // 數(shù)據(jù)為1480的整數(shù)倍且是最后一幀數(shù)據(jù)
{
gstIphead.usSegOffset = usLoop * (1480 / 8);
}
else
{
gstIphead.usSegOffset = 0x2000 + usLoop * (1480 / 8); // 不是最后一幀數(shù)據(jù),需要將IP的more fragment位置1,所以要加上"0x2000"
}
memcpy(&NetSend_buf[20],&gucaSegTemp[usLoop * 1480 + 20],1480); // 拷貝數(shù)據(jù)到發(fā)送緩沖
IpSend();
}
if(0 != usRes)
{
gstIphead.usTotalLen = 20 + usRes;
gstIphead.usSegOffset = usLoop * (1480 / 8);
memcpy(&NetSend_buf[20],&gucaSegTemp[usLoop * 1480 + 20],usRes); // 拷貝數(shù)據(jù)到發(fā)送緩沖
IpSend();
}
}
break;
default:
break;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -