TCP/IP详解卷:协议 第八章简要总结

第八章 ICMPv4和ICMPv6: Internet控制报文协议

8.1 引言

IP协议本身并没有为终端系统提供直接的方法来发现那些发往目的地址失败的IP数据
包。此外,IP没有提供直接的方式来获取诊断信息,为了解决这些不足之处,将一个特殊的Internet控制报文协议(Internet Control Message Protocol, ICMP) [RFCO792][RFC4443]与IP结合使用,以便提供与IP协议层配置和IP数据包处置相关的诊断和控制信息。ICMP通常被认为是IP层的一部分,它需要在所有IP实现中存在。它使用IP协议进行传输。因此,确切地说,它既不是一个网络层协议,也不是一个传输层协议,而是位于两者之间。
ICMP负责传递可能需要注意的差错和控制报文。ICMP报文通常是由IP层本身、上层
的传输协议(例如TCP或者UDP),甚至某些情况下是用户应用触发执行的。请注意, ICMP并不为IP网络提供可靠性。相反,它表明了某些类别的故障和配置信息。最常见的丢包(路由器缓冲区溢出)并不会触发任何的ICMP信息。由其他协议如TCP来处理这种情况。当讨论ICMP时,我们用术语ICMP指一般的ICMP,ICMPv4和ICMPv6分别指专门用于IPv4和IPv6的ICMP版本,在IPv6中, ICMPv6不仅用于一些简单的错误报告和信令,它也用于邻居发现(Neighbor Discovery, ND) [RFC4861],与IPv4中的ARP (见第4章)起着同样的作用。它还包括用于配置主机(见第6章)和管理组播地址(见第9章)的路由器发现(Router Discovery)功能。最后,它也被用来帮助管理移动IPv6中的切换。

8.1.1 1在IPv4和IPv6中的封装

ICMP报文是在IP数据报内被封装传输的,如下图所示
图片描述

在IPv4中,协议(Protocol)字段值为1表示该报文携带了ICMPv4。在IPv6中,ICMPv6报文可能开始于0个或者多个扩展头部之后。位于ICMPv6头部之前的最后一个扩展头部包含了一个值为58的下一个头部(Next Header)字段。ICMP报文可能会像其他IP数据报那样被分片(参见第10章),尽管这并不常见。
下图显示了ICMPv4和ICMPv6报文的格式开头的4个字节在所有的报文中都是一样的,但是其余部分在不同的报文中不同。
图片描述

在ICMPv4中,为类型字段保留了42个不同的值[ICMPTYPES],用于确定特定的报
文。但是,大概只有8个是经常使用的。许多类型的ICMP报文也使用不同的代码字段值进一步指定报文的含义。校验和字段覆盖整个ICMPv4报文;在ICMPv6中,它将涵盖一个来自IPv6头部的伪头部(pseudo-header)。用于计算校验和的算法和第5章中用于计算IP头校验和的算法相同。请注意,这是我们第一个端到端(end-to-end)的校验和例子。该校验和从发送方的ICMP报文被一路携带到最终的接收方。相比之下,第5章中讨论的IPv4头校验和在路由器的每一跳中都会改变。如果一个ICMP实现收到一个校验和错误的ICMP报文,该报文将被丢弃;没有ICMP报文可以表示收到的ICMP报文中的校验和是错误的。回想一下,IP层不能对数据报的有效载荷部分进行保护。如果ICMP不包括校验和,ICMP报文的内容就可能不正确,进而导致错误的系统行为。

8.2 ICMP报文

我们先对ICMP报文做一般介绍,然后对其中最为常用的部分做详细介绍。ICMP报文可分为两大类:有关IP数据报传递的ICMP报文(称为差错报文(error message)),以及有关信息采集和配置的ICMP报文(称为查询(query)或者信息类报文(informational message) )

8.2.1 ICMP4报文

对于ICMPv4,信息类报文包括回显请求和回显应答(分别为类型8和0),以及路由器通告和路由器请求(分别为类型9和10,统一被称为路由器发现)。最常见的差错报文类型包括目的不可达(类型3)、重定向(类型5)、超时(类型11)和参数问题(类型12)。(参见课本)

8.2.2 ICMPv6报文

在ICMPv6中,与ICMPv4一样,报文也被分组为
信息类的和差错类的。然而,所有ICMPv6的差错报文的类型(Type)字段的高位比特为0。因此, ICMPv6类型从0到127的都是差错报文,类型从128到255的都是信息类报文。许多信息类报文都是请求/应答对。注意ICMPv6负责的不仅是差错和信息类报文,也负责大量IPv6路由器和主机的配置。(参见课本)
除了定义ICMPv6基本功能的类型和代码字段外,还支持了大量的标准选项,其中一
些是必需的。这将ICMPv6与ICMPv4中区别开来(ICMPv4没有选项)。当前,标准的
ICMPv6选项只为ICMPv6 ND报文(类型为135和136)定义使用,使用了[RFC4861]中讨
论的选项格式(Option Format)。

8.2.3 处理ICMP报文

在ICMP中,对传入报文的处理随着系统的不同而不同。一般说来,传入的信息类请求将被操作系统自动处理,而差错类报文传递给用户进程或传输层协议,如TCP[RFC5461]。进程可以选择对它们采取行动或忽略它们。这个一般规则的例外情况包括重定向报文和目的不可达——需要分片报文。前者将导致主机路由表中的自动更新,而后者用于路径MTU发现(PMTUD)机制,这一般是由传输层协议来实现的,如TCP。
在ICMPv6中对报文的处理在一定程度上将更为严格。处理传入的ICMPv6报文[RFC4443]时将应用以下规则:
1.未知的ICMPv6差错报文必须传递给上层产生差错报文的进程(如果可能的话)。
2.未知的ICMPv6信息类报文被丢弃。
3. 1CMPv6差错报文将会尽可能多地包含导致差错的原始( “违规” ) IPv6报文,当然最
终的差错报文大小不能超过最小的IPv6 MTU ( 1280字节)。
4.在处理ICMPv6差错报文时,需要提取原始(original)或者“违规”数据包(包含在ICMPv6差错报文体中)中的上层协议类型,用于选择适当的上层进程。如果这是不可能的,在任何IPv6层处理完后将无声地丢弃差错报文.
5.存在处理差错的特殊规则(见8.3节).
6. IPv6节点必须限制它发送ICMPv6差错报文的速率。有多种方法可以用来实现限速功能,包括8.3节中提到的令牌桶方法。

8.3 ICMP差错报文

ICMP差错报文和信息类报文之间的区别非常重要,因为在生成ICMPv4差错报文[RFC1812]和ICMPv6差错报文[RFC4443]时做了某些限制,但这不适用于查询。特别是,ICMP差错报文不会对以下报文进行响应:另一个ICMP差错报文,头部损坏的数
据报(例如,校验和错误),IP层的广播/组播数据报,封装在链路层广播或者组播帧中的数据报,无效或者网络为零的源地址的数据报,或除第一个之外的其他分片。限制生成ICMP差错报文的原因是限制生成所谓的广播风暴,在这种情况下生成少数的报文就会造成不想要的流量喷流(例如,无限地为响应差错报文而生成差错报文)。
以下情况下不会响应产生ICMPv4差错报文:

  • ICMPv4差错报文(但是,响应ICMPv4查询报文可能会产生ICMPv4差错报文)。
  • 目的地址是IPv4广播地址或IPv4组播地址(以前称为D类地址)的数据报。
  • 作为链路层广播的数据报。
  • 不是第一个分片的其他分片。
  • 源地址不是单个主机的数据报。这就是说,源地址不能为零地址、环回地址、广播地
    址或组播地址。

ICMPv6也类似。在下面几种情况不会响应产生ICMPv6差错报文:

  • ICMPv6差错报文。
  • ICMPv6重定向报文。
  • 目的地址是IPv6组播地址的数据包,以下情况除外:数据包太大(PTB)的报文;参
    数问题报文(代码2)。
  • 作为链路层组播(以及前面提到的例外情况)的数据包。
  • 作为链路层广播(以及前面提到的例外情况)的数据包。
  • 源地址不是唯一识别的单个节点的数据包。这意味着,源地址不能是未指定的地址、IPv6组播地址,或者任意为发送者所知的选播地址。

除了控制产生ICMP报文条件的规则,还有限制从单一发送者发出的ICMP总体流量
水平的规则。在[RFC4443],一种推荐的限制ICMP报文速率的方法是便用令牌桶(token
bucket)。采用令牌桶后,每个“桶”保存了最大数量(B)的“令牌”,每个“令牌”允许一
定数量的报文被发送。桶定期被新的令牌(速率为N)填充,并且每发送一个报文便减1。因此,令牌桶(通常也称为令牌桶过滤器(token bucket filter))可以由参数(B, N)刻画。对于小型或中型设备, [RFC4443]提供了一个使用参数( 10, 10)的令牌桶例子。令牌桶是在协议实现中为限制带宽利用率所采取的一个通用机制,在许多情况下B和N的单位是字节,而不是报文个数。
当发送一个ICMP差错报文,它包含了一个完整的源自“违规”或者“原始”数据报的IP头部副本(即生成导致错误的数据报的IP头部,包括任何IP选项),再加上原始数据报的IP有效载荷区中的任何其他数据,同时要确保生成的IP/ICMP的数据报的大小不会超过一个特定的值。对于IPv4,这个值是576字节,对于IPv6就是IPv6的最小MTU,至少
是1280字节。包含原始IP数据报的有效载荷使接收的ICMP模块能够根据IP头部中的协议(Protocol)或者下一个头部(Next Header)字段将该报文和特定的协议(例如, TCP或
者UDP)及应用进程相关联(包含在IP数据报有效载荷区中前8个字节所包含的TCP或者
UDP头部中的TCP或者UDP端口号)。

8.3.1 1扩展的IcMP和多部报文

[RFC4884]通过在ICMP报文的尾部追加扩展数据结构( extension data structure)的方
法来指定一个扩展的方法。扩展结构包括一个扩展头部和可能包含可变数量数据的扩展对象,如下图所示。
图片描述
ICMPv4头部的第6个字节和ICMPv6头部的第5个字节被改为用于表示长度( Length)
字段(这些字节此前已预留0值)。在ICMPv4中,它表示以32位字为单位的违规数据报的大小。在ICMPv6中,它是以64位为单位的。为了使32位和64位对齐,这些数据报中有一部分将分别用零来填充。当使用扩展时,包含原始数据报的ICMP有效负载区至少为128字节长。
扩展结构可用于ICMPv4目的不可达、超时、参数问题报文,以及ICMPv6目的不可达
和超时报文。

8.3.2 目的不可达(ICMPv4类型3, ICMPv6类型1 )和数据包太大(ICMPv6类型2)

这种类型的报文用来表示数据报无法送达目的地,可能是因为传输过程中出了问题或接收者缺乏兴趣接收它。虽然ICMPv4为此报文定义了16个不同的代码,但其中只有4个是最常用的。这包括主机不可达(代码1)、端口不可达(代码3)、需要分片/指定不用分片(代码4)、管理禁止通信(代码13)。在ICMPv6中,目的不可达报文类型值是1,并有7个不同的代码值。与IPv4相比,ICMPv6中需要分片报文已经被一个完全不同的类型取代(类型2),但是其用法和对应的ICMP目的不可达非常相似,所以我们在这里讨论。在ICMPv6中,这就是所谓的数据包太大(PTB)报文。
具体细节参考课本

8.3.3 重定向(ICMPv4类型5, ICMPv6类型137)

假如一个路由器收到一个来自主机的数据报,并确定自身并不是主机将数据报投递到目的地的对应下一跳,则该路由器发送一个重定向报文到主机并将该报文发送到正确的路由器(或者主机)。也就是说,如果它能够确定给定的数据报存在一个比自已更好的下一跳路由,它就向主机发送重定向报文使其更新转发表,这样以后目的地一样的流量就会被定向到新的节点中。这项功能通过向IP转发功能指示向哪里发送数据包提供了一种路由协议的原始形式。在第5章详细讨论了IP转发过程。
具体考课本

8.3.4 IcMP超时(lcMPv4类型11, lCMPv6类型3)

每个IPv4数据报在头部中都有一个生存周期( Time-to-Live, TTL)字段,而每个IPv6数据报在其头部中都有一个跳数限制(Hop Limit)字段(参见第5章)。接照最初的设想,8
位TTL字段保存了一个数据报被强制丢弃之前允许活跃在网络中的秒数(如果存在转发环路,这将是一件好事)。因为另外一个规则表明,任何一个路由器对TTL字段至少减1,考虑到数据报的实际转发时间远小于1秒这个事实,在实际中TTL字段被用于限定一个IPv4数据报在被路由器丢弃之前所允许的跳数限制。这种用法最终在IPv6中被正式采用。当由于TTL或跳数限制字段值太小(即到达值0或1,且必须转发)致使路由器丢弃报文时,会产生ICMP超时(代码0)报文。细节参考课本

8.3.5 参数问题(ICMPv4类型12, ICMPv6类型4)

当一个主机或者路由器接收到一个IP数据报,其IP头部存在不可修复的间题时便会产
生一个ICMP参数问题报文。当一个数据报不能够被处理,且没有其他的ICMP报文来描述这个问题时,这个报文充当了一个“包罗万象”的错误状态指示器。在ICMPv4和ICMPv6中,当头部中某个字段超过可接受范围导致了一个错误时,一个特殊的ICMP差错报文指针(Pointer)字段指示了错误字段相对于出错IP头部的偏移值。细节参考课本。

8.4 ICMP查询/信息类报文

尽管ICMP定义了一定数量的查询报文,例如地址掩码请求/应答(类型17/18)、时间
戳请求/应答(类型13/14)、信息请求/应答(类型15/16),但是这些功能已经被其他特殊
目的的协议替代(包括DHCP,参见第6章)。唯一保存下来的广泛使用的ICMP查询/信息
类报文是回显请求/应答报文,通常称为ping,以及路由器发现报文
。虽然路由器发现机制在IPv4中并未广泛使用,但是与之类似的功能(邻居发现中的一部分)在IPv6中却是基本的。此外, ICMPv6已经被扩展用于支持移动IPv6和具备组播能力的路由器发现。

8.4.1回显请求/应答(ping)(ICMPv4类型0/8, ICMPv6类型129/128)

一种最为常用的ICMP报文对就是回显请求和回显应答(或者回复)。在ICMPv4中,
它们的类型分别是8和0,在ICMPv6中它们的类型分别是128和129。ICMP的回显请求
报文大小几乎是任意的(受限于最终封装的IP数据报的大小)。收到ICMP回显请求报文后,ICMP的实现要求将任何接收到的数据返回给发送者,即使涉及多个IP分片。具体细节参考课本。

8.4.2 路由器发现:路由器请求和通告(ICMPv4类型9, 10)

在第6章,我们看到了DHCP是如何被一个主机用于获取IP地址和学习到附近存在的
路由器的。我们提到的另外一种学习路由器的方式是路由器发现(Router Discovery, RD)。尽管可以指定为IPv4和IPv6主机配置,但是由于DHCP的普及,它在IPv4中并没有被广泛使用。但是,目前它被指定与移动IP一起使用,因此我们简要描述一下。
IPv4的路由器发现是通过采用一对ICMPv4信息类报文实现的[RFC1256]:路由器请求
(RS,类型10)和路由器通告(RA,类型9)。通告由路由器通过两种方法发送。首先,它们定期对本地网络(使用TTL= 1 )的所有主机组播地址(224.0.0.1 )进行组播,并提供给有需要的主机,它们通常使用RS报文进行请求。使用组播将RS报文发送到所有路由器组播地址上(224.0.0.2)。路由器发现的主要目的是让一台主机学习到它所在的本地子网中的所有路由器,因此它能够从中选择一台作为默认路由。具体细节参考课本

ICMPv6类型的查询报文参看课本

8.5 IPv6中的邻居发现

IPv6中的邻居发现协议(有时简称为NDP或者ND) [RFC4861]将路由器发现和由ARP提供的带有地址映射功能的ICMPv4重定向机制结合在一起。它也被指定用于支持移动IPv6.与ARP和IPv4普遍使用广播地址(除了路由器发现)不同,ICMPv6广泛使用组播地址,在网络层和链路层中都使用。
ND被设计允许在同一个链路或者网段的节点(路由器和主机)找到彼此,确定它们之间是否有双向连通性,确定一个邻居是否变得不合作或者不可用。它也支持无状态的地址自动配置(参见第6章)。所有的ND功能都是由网络层或者之上的ICMPv6提供的,致使它最大限度地独立于底层所采用的链路层技术。但是,ND并不倾向于采用链路层组播功能(参见第9章),也正是这个原因在非广播和非组播链路层(称为非广播多路访问或者NBMA链路)上的操作可能会有一些差别。
ND中两个主要部分是: 邻居请求/通告(NS/NA),在网络和链路层地址之间提供类似
于ARP的映射功能;还有路由器请求和通告(RS/RA),提供的功能包括路由器发现、移动IP代理发现、重定向,以及对一些自动配置的支持
。ND的一个安全变体SEND[RFC3971]通过引入额外的ND选项增加了认证和特殊形式的寻址。
ND报文就是ICMPv6报文,只是发送时IPv6的跳数限制字段值被设置为255。接收者通过验证进来的ND报文有这个值,以防止被非本链路上的发送者尝试发送假冒本地ICMPv6报文(这样的报文到达时其值会小于255 )欺骗。ND报文可以携带丰富的选项。具体细节参考课本

8.6 ICMPv4和ICMPv6转换

在第7章,我们讨论了基于[RFC6144]和[RFC6145]来转换IPv4/IPv6的一个框架,并
讨论了如何转换IP头部。 [RFC6145]描述了从ICMPv4转换到ICMPv6的方法,以及相反方向的转换方法。当转换ICMP时,IP和ICMP头部都要被转换(即,被修改和被替换)。除此之外,包含了一个内部违规数据包头部及数据的ICMP差错报文,也会转换内部(违规)数据报的头部。除了映射适当的类型和代码号之外,还有需要额外考虑的分片、 MTU大小以及校验和计算。具体细节参考课本

8.7 总结

posted @ 2021-01-30 11:45  buguoliujibugaiming  阅读(215)  评论(0编辑  收藏  举报