|
ICMP.C
//=====================================================================
// 嵌入式 TCP/IP 协议栈 MSC51 专用版
// ICMP.C
// 作 者:南开大学-李章林
// 注 释:李清林
// 日 期:2008 年3 月
// 声 明:英文注释由作者李章林添加,中文注释由■李清林添加。
// 转载时请保留上述信息。
// 成都理工学院/应用数字系/应用数字专业
//=====================================================================
#include "..\GloblDef\GloblDef.h"
#include "..\TCPIP\TCPIPmem.h"
#include "..\TCPIP\IP.h"
#include "..\TCPIP\icmp.h"
#if ICMP_EN
//===========================================================================
/* MemHead->pStart is point to ICMP head */
// 作 者:南开大学-李章林
// 注 释:李清林
// 日 期:2008 年3 月
// 声 明:英文注释由作者李章林添加,中文注释由■李清林添加。
// 转载时请保留上述信息。
// 成都理工学院/应用数字系/应用数字专业
//---------------------------------------------------------------------------
// 程序名称:ICMPInput=ICMP 接收子程序
// 功 能:接收到回显请求报文后发送 ICMP 回显应答报文
// 入口参数:
// *MemHead=缓存控制块指针
// 其中缓存控制块.pStart 域指针已指向ICMP 首部
// 出口参数:
// 无
//===========================================================================
void ICMPInput(struct SMemHead DT_XDATA *MemHead) REENTRANT_MUL
{
IP_ADDR ipaddr; // IP 地址
struct SIPHead DT_XDATA *pIPHead; // IP 结构体首部指针
struct SICMPEchoHead *pICMPHead; // ICMP 回显结构体指针
/* which type of icmp */
// 检查缓存控制块中 ICMP 回显结构体类型码
switch (((struct SICMPEchoHead DT_XDATA *)(MemHead->pStart))->type)
{
case ICMP_TYPE_QUERY: // 回显请求 ICMP.C
//--------------------------------------------------------------
// 填写 ICMP 报文
//--------------------------------------------------------------
/* change type */
// 填写 ICMP 回显报文类型码=回显应答
((struct SICMPEchoHead DT_XDATA *)(MemHead->pStart))->type =ICMP_TYPE_REPLY;
/* adjust checksum. refer to lwip: if change type from 8 to 0,
for checksum, that is increasing 0x8000 and add flowed hight bit
to bit 0.*/
// 填写 ICMP 回显报文检验码
if (((struct SICMPEchoHead DT_XDATA *)(MemHead->pStart))->CheckSum
>= htons(0xffff - (((WORD)ICMP_TYPE_QUERY) << 8)))
((struct SICMPEchoHead DT_XDATA *)(MemHead->pStart))->CheckSum
+= htons(((WORD)ICMP_TYPE_QUERY) << 8) + 1;
else
((struct SICMPEchoHead DT_XDATA *)(MemHead->pStart))->CheckSum
+= htons(((WORD)ICMP_TYPE_QUERY) << 8);
/*send this packet back, first fill some of IPHead field*/
/* dec pStart and get ip head */
// pIPHead 指针指向报文 IP 首部
pIPHead = (struct SIPHead DT_XDATA *)(MemHead->pStart -=IP_HEAD_MIN_LEN);
/* exchange ipdest and ipscr */
// 填写 IP 地址(交换源地址和目的地址)
ipaddr = pIPHead->IPDest;
pIPHead->IPDest = pIPHead->IPScr;
pIPHead->IPScr = ipaddr;
/* ip total length not change */
/* protocol */
// 填写 IP 报文协议类型=ICMP 数据包
pIPHead->Protocol = IP_PROTOCOL_ICMP;
// 调用 IP 数据包输出子程序
IPOutput(MemHead);
/* whether send success or not free this packet */
MemFree(MemHead);
break;
case ICMP_TYPE_REPLY: // 回显应答
// ICMP 回显指针指向ICMP 报文
pICMPHead = (struct SICMPEchoHead *)(MemHead->pStart);
// ICMP 检验和只覆盖ICMP 报文
if (CheckSum((WORD *)pICMPHead,MemHead->pEnd - MemHead->pStart,0)!=0)
{ // 如果检验和错误,则显示调试信息"检验和错误"
#ifdef DEBUG_ICMP
UART_Printf("ICMP:RCV A REPLY FRAME BUT CHECKSUM IS ERROR!\n");
#endif
} ICMP.C
else
{
#ifdef DEBUG_ICMP
UART_Printf("ICMP:RCV A REPLY FRAME BUT CHECKSUM IS ERROR!\n");
#endif
}
break;
//--------------------------------------------------------------
// 嵌入式 TCP/IP 协议栈只支持ICMP 回显请求报文和 ICMP 回显应答报文
// 用于 Ping 程序,测试网络物理上是否相通。
//--------------------------------------------------------------
default:
MemFree(MemHead);
break;
}
}
BOOL PINGOut(IP_ADDR IPScr,IP_ADDR IPDest,WORD len)
{
struct SMemHead *MemHead;
}
#endif |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|