ICMP

编辑
ICMP是“Internet Control Message Protocol”的缩写互,中文称“互联网控制消息协议”,是用于在 TCP/IP 网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,令管理者可以对所发生的问题作出诊断,然后采取适当的措施去解决它。ICMP 依靠IP来完成它的任务,它是IP的主要部分。

ICMP概述

  ICMP协议是一种面向连接的协议,用于传输出错报告控制信息。它是一个非常重要的协议,它对于网络安全具有极其重要的意义。

  它是TCP/IP协议族的一个子协议,属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息ICMP提供一致易懂的出错报告信息。发送的出错报文返回到发送原数据的设备,因为只有发送设备才是出错报文的逻辑接受者。发送设备随后可根据ICMP报文确定发生错误的类型,并确定如何才能更好地重发失败的数据报。但是ICMP唯一的功能是报告问题而不是纠正错误,纠正错误的任务由发送方完成。

  每个ICMP消息都是直接封装在一个IP数据报中的,因此,和UDP一样,ICMP是不可靠的。虽然ICMP是包含在IP数据报中的,但是对ICMP消息通常会特殊处理,会和一般IP数据报的处理不同,而不是作为IP的一个子协议来处理。在很多时候,需要去查看ICMP消息的内容,然后发送适当的错误消息到那个原来产生IP数据包的程序,即那个导致ICMP讯息被传送的IP数据包。

  我们在网络中经常会使用到ICMP协议,比如我们经常使用的用于检查网络通不通的Ping命令(Linux和Windows中均有),这个“Ping”的过程实际上就是ICMP协议工作的过程。还有其他的网络命令如跟踪路由的Tracert命令也是基于ICMP协议的。

ICMP的重要性

  ICMP协议对于网络安全具有极其重要的意义。ICMP协议本身的特点决定了它非常容易被用于攻击网络上的路由器和主机。例如,在1999年8月海信集团“悬赏”50万元人民币测试防火墙的过程中,其防火墙遭受到的ICMP攻击达334050次之多,占整个攻击总数的90%以上!可见,ICMP的重要性绝不可以忽视!

  比如,可以利用操作系统规定的ICMP数据包最大尺寸不超过64KB这一规定,向主机发起“Ping of Death”(死亡之Ping)攻击。“Ping of Death” 攻击的原理是:如果ICMP数据包的尺寸超过64KB上限时,主机就会出现内存分配错误,导致TCP/IP堆栈崩溃,致使主机死机。

  此外,向目标主机长时间、连续、大量地发送ICMP数据包,也会最终使系统瘫痪。大量的ICMP数据包会形成“ICMP风暴”,使得目标主机耗费大量的CPU资源处理,疲于奔命。

ICMP功能

  从技术角度来说,ICMP就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性﹐其功能主要有:

  · 侦测远端主机是否存在。

  · 建立及维护路由资料。

  · 重导资料传送路径。

  ·资料流量控制。

ICMP结构

ICMP协议结构

  Type ― 错误消息或信息消息。错误消息可能是不可获得目标文件,数据包太大,超时,参数问题等。可能的信息消息有:Echo Request、Echo Reply、Group Membership Query、Group Membership Report、Group Membership Reduction。

  Code ― 每种消息类型具有多种不同代码。不可获得目标文件正式这样一个例子,即其中可能的消息是:目标文件没有路由,禁止与目标文件的通信,非邻居,不可获得地址,不可获得端口。具体细节请参照相关标准。

  Checksum ― 计算校验和时,Checksum 字段设置为0。

  Identifier ― 帮助匹配 Requests/Replies 的标识符,值可能为0。

  Sequence Number ― 帮助匹配 Requests/Replies 的序列号,值可能为0。

  Address Mask ― 32位掩码地址。

ICMP校验和算法

  unsignedshortchksum(addr,len)

  unsignedshort*addr;/*校验数据开始地址(注意是以2字节为单位)*/

  intlen;/*校验数据的长度大小,以字节为单位*/

  {

  intsum=0;/*校验和*/

  intnleft=len;/*未累加的数据长度*/

  unsignedshort*p;/*走动的临时指针,2字节为单位*/

  unsignedshorttmp=0;/*奇数字节长度时用到*/

  while(nleft>1)

  {

  sum+=*p++;/*累加*/

  nleft-=2;

  }

  if(nleft==1)/*奇数字节长度*/

  {

  *(unsignedchar*)&tmp=*(&(unsignedchar*)p);/*将最后字节压如2字节的高位*/

  sum+=tmp;

  }

  sum+=(sum>>16)+(sum&0xffff);/*高位低位相加*/

  sum+=sum>>16;/*上一步溢出时,将溢出位也加到sum中*/

  tmp=~sum;/*注意类型转换,现在的校验和为16位*/

  returntmp;

  }

 
0
本词条对我有帮助
 
 
词条标签