ba_wang_mao 发表于 2008-12-17 11:31:53

嵌入式TCP/IP学习笔记-ICMP协议【恢复】

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 

armok 发表于 2010-2-14 21:21:43

页: [1]
查看完整版本: 嵌入式TCP/IP学习笔记-ICMP协议【恢复】