zoukankan      html  css  js  c++  java
  • 008-ICMP协议(网络控制文协议)

    一、概述

      ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议簇的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。

      它是TCP/IP协议族的一个子协议,属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。ICMP报文在IP帧结构的首部协议类型字段(Protocol 8bit)的值=1.

      在IP通信中,经常有数据包到达不了对方的情况。原因是,在通信途中的某处的一个路由器由于不能处理所有的数据包,就将数据包一个一个丢弃了。或者,虽然到达了对方,但是由于搞错了端口号,服务器软件可能不能接受它。在IP 网络上,由于数据包被丢弃等原因,为了控制将必要的信息传递给发信方。ICMP 协议是为了辅助IP 协议,交换各种各样的控制信息而被制造出来的。

      RFC792 的开头部分里写着“ICMP 是IP 的不可缺少的部分,所有的IP 软件必须实现ICMP协议。也是,ICMP 是为了分担IP 一部分功能而被制定出来的。

      

    1.1、功能

      在RFC,将ICMP 大致分成两种功能:差错通知和信息查询。

      1. 确认IP包是否成功到达目标地址 

      2. 通知在发送过程中IP包被丢弃的原因 

    注意点

    1、ICMP是基于IP协议工作的,但是它并不是传输层的功能,因此仍然把它归结为网络层协议 

    2、ICMP只能搭配IPv4使用,如果是IPv6的情况下, 需要是用ICMPv6  

    1.2、ICMP作为IP的上层协议在工作 

      ICMP 的内容是放在IP 数据包的数据部分里来互相交流的。也就是,从ICMP的报文格式来说,ICMP 是IP 的上层协议。但是,正如RFC 所记载的,ICMP 是分担了IP 的一部分功能。所以,被认为是与IP 同层的协议。看一下RFC 规定的数据包格式和报文内容吧。

      ICMP报文包含在IP数据报中,IP报头在ICMP报文的最前面。一个ICMP报文包括IP报头(至少20字节)、ICMP报头(至少八字节)和ICMP报文(属于ICMP报文的数据部分)。当IP报头中的协议字段值为1时,就说明这是一个ICMP报文。ICMP报头如下图所示。 
    如下图:

      

      上图包含了IP首部以及ICMP,以下是ICMP部分

      

    详细地看一下数据包的格式吧。用来传送ICMP 报文的IP 数据包上实际上有不少字段。但是实际上与ICMP 协议相关的只有7 个子段。

    1)协议;2)源IP 地址;3)目的IP 地址;4)生存时间;这四个包含在IP 首部的字段。

    5)类型;6)代码;7)选项数据;这三个包含在ICMP数据部分的字段。

    这里面,1)协议字段值是1。2)和3)是用来交流ICMP 报文的地址信息,没有特殊意义。对于理解ICMP 本身,重要的是5),6),7)三个字段。这里面的可以称为核心的重要字段是5)类型,6)代码这两个字段。所有ICMP 用来交流错误通知和信息询问的报文,都是由类型和代码的组合来表示的。RFC 定义了15种类型。“报文不可到达”这样的错误通知和“回送请求”这样的信息查询是由类型字段来区分的。ICMP报文由类型来表达它的大概意义,需要传递细小的信息时由代码来分类。进一步,需要向对方传送数据的时候,用7)选项数据字段来放置。

    可能的消息列表:

      

    二、ICMP实现

    2.1、MTU探索

      所谓路径MTU 探索,是探索与通信对方之间不用分片IP 数据包,就能交流的MTU 大小的功能。MTU大小是指计算机一次能够送出去的数据的最大长度,基本上由网路的种类来决定。例如,以太网的话通常是1500 字节,使用PPPoE 的ADSL 通常是1492 字节。为了实现这个路径MTU 探索,ICMP 被使用着。

      

      路径MTU 探索的原理本身是非常简单的。首先,Windows 向通信对方送IP 数据包时,先设置IP 首部的分片禁止标志然后再送。这是路径MTU 探索的基本。假如,Windows 将大于1000 字节的数据包送了出去,通信路径上有MTU 从1500 字节变成1000 字节的地方。因此,那个路由器将不允许超过1000 字节的数据包通过,而进入MTU 是1000 字节的网路。路由器尝试着将IP 数据包分片。但是因为数据包的分片禁止标志是有效的,所以不能分片。该路由器就将该IP 数据包丢弃,并用ICMP 通知送信方“想分片,但不能分片”。这时路由器发送的ICMP的类型字段是3,代码字段为4。这是“需要分片但不能分片,不能送至终点”的意思。而且,大多数路由器将在数据选项部里填入不分片就能通过的MTU 大小。Windows 收到该ICMP 报文后就知道了不分片就能够传送的数据大小,并暂时将MTU 大小更换掉,然后继续通信。

    2.2、改变路由

      改变路由是指路由器向送信方计算机指示路径改变这个功能。计算机根据自己的路由信息(路由表)来决定传送目标。不知道发给谁好的时候,就将数据包发给设为默认网关的路由器。被指定为默认网关的路由器接收到数据包,发现将数据包发给局域网内的其它路由器会比较快的时候,将这一信息通过ICMP 通知发送方。这时使用的是,类型是5,代码是1 的ICMP 改变路由报文。在选项数据部分里写着应该发送给的路由器IP 地址。Windows 收到这个报文后,重写自己的路由表,与对方的通信将在一段时间里经由被指定的路由器来实行。

      

    2.3、源点抑制

      数据包集中到达某一路由器后,数据包因为来不及被处理,有可能被丢弃的情况。这时候,向送信方发送的是ICMP 源点抑制报文,用来使送行方减慢发送速度。

      

    2.4、ping命令

      ping 命令用来在IP 层次上调查与指定机器是否连通,调查数据包往复需要多少时间。为了实现这个功能,ping 命令使用了两个ICMP 报文。  

      

      注意, 此处 ping 的是域名,不是url,域名可以通过DNS解析成IP地址 

    ping命令的功能

    (1)能验证网络的连通性 
    (2)会统计响应时间和TTL(IP包中的Time To Live,生存周期) 
    那么如何验证的呢? 
    (1)ping命令会先发送一个 ICMP Echo Request给对端 
    (2)对端接收到之后, 会返回一个ICMP Echo Reply 
    (3)若没有返回,就是超时了,会认为指定的网络地址不存在。

    问题:

      telnet是23端口,ssh是22端口,那么ping是什么端口? 
      答:ping命令是基于ICMP,是在网络层。 
      而端口号,是传输层的内容。所以在ICMP中根本就不关注端口号这样的信息。

    用ping 命令不能确定与对方连通的原因大致有三个。

      1)目标服务器不存在;

      2)  花在数据包交流上的时间太长ping 命令认为超时;

      3)目标服务器不回答ping 命令。

      如果是原因2),通过ping 命令的选项来延长到超时的等待时间,就能正确显示结果了。如果原因是1)或3)的话,仅凭ping 命令的结果就不能判断是哪方了。正如这样,ping 命令不一定一定能判断对方是否存在。

    2.5、traceroute命令[trace]

      功能:打印出可执行程序主机,一直到目标主机之前经历多少路由器。

      

      linux、mac:traceroute www.baidu.com

      windows:tracert www.baidu.com

    2.6、端口扫描  

      端口扫描就是检查服务器不需要的端口是否开着。服务器管理者用来检查有没有安全上有问题的漏洞开着。不是象ping 和traceroute 那样是操作系统自带的工具,需要利用网络工具才行。

      端口扫描大致分为“UDP 的端口扫描”和“TCP 的端口扫描”两种。这里面,与ICMP 相关的是UDP一边。使用TCP 的通信,通信之前必定要先遵循三向握手的程序。因此,只要边错开端口号边尝试TCP连接就能调查端口的开闭。不特别需要ICMP。与此相对,UDP 没有这样的连接程序。因此,调查端口是否打开需要想点办法。这样,被使用的是ICMP。根据ICMP 规格,UDP 数据包到达不存在的端口时,服务器需要返回ICMP 的“终点不可达”之一的“端口不可达”报文。

        

  • 相关阅读:
    C++primer拾遗(第五章:语句)
    每日编程-20170315
    C++primer拾遗(第四章:表达式)
    C++primer拾遗(第三章:字符串、向量和数组)
    每日编程-20170314
    C++primer拾遗(第二章:变量和基本类型)
    每日编程-20170313
    每日编程-20170310
    每日编程-20170309
    C++primer拾遗(第一章:开始)
  • 原文地址:https://www.cnblogs.com/bjlhx/p/10985384.html
Copyright © 2011-2022 走看看