返回   cpper编程论坛 > 技术杂烩
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

技术杂烩 找不到地方的技术问题?这里!

回复
 
LinkBack 主题工具 显示模式
  #1 (permalink)  
旧 2004-10-18
zweily 的头像
版主
 
注册日期: 2002-09-24
帖子: 425
文章: 10
zweily 正向着好的方向发展
默认 IPv6学习笔记——RFC2463

RFC 2463 Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification

概述
这篇RFC描述了与IPv6协议相配套的ICMPv6协议的规范。由于IP协议提供的是一种不可靠的服务机制,并且在IP协议中没有关于差错处理和通告的定义。因此,对于IP协议而言,需要由ICMP协议来提供一些控制信息和差错信息的通告机制。在IPv4中,有相应的ICMPv4协议;对于IPv6而言,也有相应的ICMPv6协议。

ICMPv6
ICMP协议主要用于在IP处理报文的过程中产生一些错误报告,并且也可以用来进行一些网络问题的诊断。例如大家常用来检测网络连通性的“ping”命令,实现的原理就是基于ICMP协议的Echo Request/Echo Reply报文。并且,按照RFC的要求,对于每个实现了IPv6的节点(node)而言,都必须实现ICMPv6。

1.报文格式
ICMPv6报文总体上分为两种类型:差错报文和信息报文。差错报文的Type字段的最高位为0,信息报文的Type字段的最高位为1。由于Type字段的大小为1个字节,因此,差错报文的Type范围为0到127,信息报文的Type范围为128到255。
ICMPv6的报文是封装在IPv6的报文中的,因此在ICMPv6报文之前有IPv6头部,及0个或多个扩展头部(extension header)。在IPv6头部以及每个扩展头部都包含一个“下一个头部”(Next Header)字段,以此来表示该头部之后的头部类型。对于ICMPv6而言,该值为58。
代码:
ICMPv6头部定义如下: Type: 8bits —— ICMPv6报文类型 Code: 8bits —— ICMPv6报文子类型 Checksum: 16bits —— 校验和 Message body: —— ICMPv6报文信息
2.报文源地址的确定
如果某个IPv6节点的单播地址大于1个的话,那么在发送ICMPv6报文之前,应该按照下列规则来确定发送报文的源地址。
(1)如果要发送的报文是对某个收到的报文的回复,而且收到的这个报文的目的地址是该节点的某个单播地址,那么发送的回复报文的源地址就必须使用相同的这个地址。
(2)如果要发送的报文是对某个收到的报文的回复,而且收到的这个报文的目的地址时该节点所属的某个多播或任意播(anycast)组的地址,那么回复报文的源地址必须使用收到该报文的接口上的单播地址。
(3)如果要发送的报文是对某个收到的报文的回复,而且收到的这个报文的目的地址不是该节点的地址,那么回复报文的源地址应该是属于该节点的,并且能够帮助诊断错误的地址。这里用一个例子来说明这个问题。例如一台路由器在转发报文的时候,转发失败,那么可能需要对源站发送一个ICMPv6差错报文,那么这个报文的源地址应该是该路由器上转发失败的那个接口的单播地址。
(4)在其他情况下,就需要先检查该节点的路由表,判断应该从哪个接口发送该报文,然后将该接口的单播地址作为该报文的源地址。

3.报文校验和的计算
TCP/IP协议栈中关于校验和的计算都是采用反码和的反码的方式。这种算法是将内容看作一组一组的16位数据,将每组16位数据求反,然后求和,再将和求反。对于ICMPv6协议而言,其计算校验和的数据范围包括整个ICMPv6报文,并且还要在这个报文前加上一个IPv6的伪头,这个伪头的定义应该在RFC2460里由具体描述,等介绍RFC2460的时候再说。
将ICMPv6与ICMPv4相比较,ICMPv4的校验和计算是不包括IPv4的伪头的,只包括ICMPv4本身的头部和数据。

4.报文处理规则
对于ICMPv6的实现而言,应该遵循以下规则:
(1)如果收到未知类型的差错报文,必须将该报文传递给上层。
(2)如果收到未知类型的信息报文,那么应该在本层丢弃,并且不产生任何其他信息。
(3)对于每个ICMPv6差错报文而言,必须将引起差错的原始IP报文作为该差错报文的数据,并且只要不超过IPv6定义的最小MTU(1280字节,具体参见RFC2460)的长度,应该包含尽可能完整的原始报文。
(4)对于需要将差错报文递交给上层的情况,ICMP应该从其报文的数据(即原始报文)中读出原始报文的上层协议类型,然后将该差错报文递交给相应的上层。如果原始报文中有较多的IPv6扩展头部,这样如果保留全部报文内容的话,可能超过最小MTU,那么差错报文中包含的原始报文就找不出对应的上层协议类型。对于这种情况,IPv6层处理完该报文后就直接丢弃该报文,不再递交给上层。
(5)对于接收到以下几种报文的情况下,不发送ICMPv6差错报文:
(5.1)一个ICMPv6差错报文。
(5.2)该报文的目的地址是一个多播地址。(但有2种例外情况:一种是“Packet Too Big”报文,这种报文为了对IPv6多播进行Path MTU Discovery算法(这个在RFC1981里讨论,等介绍该RFC的时候将具体介绍)。另一种情况是“Parameter Problem”报文,该报文用于报告报文中有不可识别的Option,而且该Option的类型字段的最高两位值为10)。
(5.3)链路层多播报文。(同样有(5.2)中的两种例外)
(5.4)链路层广播报文。(同样有(5.2)中的两种例外)
(5.5)报文的源地址不表示一个唯一的IPv6节点。例如多播地址、任意播地址等等。
(6)最后一条规则是,应该限制ICMPv6差错报文的发送速度。这样做是为了避免ICMP差错报文过多得占用通信链路上的带宽,也可以减少转发的开销。在实现上可能有多种限制方法,下面是两个例子:
(6.1)基于时钟的方法:限制ICMP差错报文的发送速度,比如每T毫秒发送一个差错报文。
(6.2)基于带宽的方法:使用一个比例因子F,然后将发送速率限制为该接口的F%。
这些限制参数(比如T和F应该是可以配置修改的,并且默认值应该是比较保守的值,比如T为1秒,而不是0,F为2,而不是100)

5.ICMPv6差错报文
(1)Destination Unreachable
报文格式(这里介绍的报文格式是除去通用的Type、Code和Checksum字段之后的内容,并且下面介绍的各种类型都将用这种方式来介绍):
代码:
Unused:16bits —— 未使用,该字段必须设置为全0,并且在接收方应该忽略该字段。 Data:原IP报文,包含尽可能完整的报文。
子类型(code):
0 —— 没有通往目的地址的路由
1 —— 管理上禁止与目的地址的通信
2 —— 未定义
3 —— 地址不可达
4 —— 端口不可达
说明:该报文应该由路由器或者报文发送者的IP层发送。只要不是由于网络拥塞的原因而导致报文无法发送到目的端的情况下,就应该发送该报文。而对于由于网络拥塞而无法发送该报文,ICMPv6的实现应该不发送该报文。
当由于路由表中没有匹配项而导致无法发送报文的时候,应该将该报文的Code设为0。因此,只有当该节点的路由表中没有默认路由项的时候,才可能发送这一类型的报文。
如果是由于防火墙过滤之类的管理禁止原因导致无法发送报文,那么就应该发送Code为1的报文。
如果是其他原因造成无法发送该报文的时候,例如无法将IPv6地址解析为相应的链路层地址,或者由于链路层的某些错误导致报文无法发送,这些情况下都应该发送Code为3的报文。
当由于传输层没有对某个端口Listen而造成报文无法由IP递交到传输层,并且传输层也没有其他机制来通告发送端发生了错误的时候,就应该发送Code为4的报文。例如对UDP而言就有这个可能。而对于TCP,当收到错误端口号的报文时,TCP会发送RST报文,因此不需要使用该ICMPv6报文来传送差错信息。

(2)Packet Too Big
报文格式:
代码:
MTU:16bits —— 下一跳(next hop)链路的MTU。 Data:原IP报文,包含尽可能完整的报文。
子类型(code):必须设置为0。
说明:当要转发的报文的长度大于输出口链路的MTU时,发送该报文。该报文主要用在“Path MTU Discovery”(RFC1981)。

(3)Time Exceeded
报文格式:
代码:
Unused:16bits —— 未使用,该字段必须设置为全0,并且在接收方应该忽略该字段。 Data:原IP报文,包含尽可能完整的报文。
子类型(code):
0 —— 传输过程中超出了跳数限制(hop limit)。
1 —— 重装超时。
说明:当路由器接收到一个Hop Limit为0的报文,或者在该路由器上将Hop Limit值减到了0,那么就应该丢弃该报文,并且发送Code为0的该报文。这种情况意味着存在环状路由或者初始的Hop Limit值过小。

(4)Parameter Problem
报文格式:
代码:
Pointer:16bits —— 表示报文中错误所在的偏移,如果该错误已经超出了ICMPv6报文的长度范围,那么该值也将超出这个长度范围。 Data:原IP报文,包含尽可能完整的报文。
子类型(code):
0 —— 错误的头部字段。
1 —— 无法识别的下一个头部类型。
2 —— 无法识别的IPv6 Option。
说明:在IP报文处理的过程中,如果遇到了IP头部问题或者扩展头部的问题,那么就应该丢弃该报文,并且发送Parameter Problem报文,通告问题类型和问题的具体位置。

6.ICMPv6信息报文
(1)Echo Request & Echo Reply
报文格式:
代码:
Identifier:8bits —— 用于匹配Echo Request和Echo Reply的标识信息。 Sequence Number:8bits —— 同上。 Data:任意数据。
子类型(code):必须为0。
说明:我想将Echo Request和Echo Reply报文放在一起说明,因为这两个报文是配对出现的。对于每一个ICMPv6的实现而言,必须实现这一对报文。Echo报文对于大家来说应该是最常用的。当发现网络有问题的时候,可能大家做的第一件事情就是用ping来确定某段网络的连通性。而ping的原理就是基于Echo报文的。Echo报文的Identifier和Sequence Number用来匹配相对应的Request和Reply对,当发送一个Request之后,如果收到了对应的Reply,那么就认为成功ping通了。该报文还有一个Data数据段,该数据段也是为了测试网络的正确性而设计的。对于每个Echo Request报文而言,会在其Data字段中放入相应的数据,然后等待相应的Reply回来,如果收到Reply,先检查Identifier和Sequence Number是否匹配,然后检查Data中的内容是否正确(也就是和发送的Request中的Data字段的内容完全相同),如果检查都通过,那么就认为Reply是有效的。

在Windows中,ping程序有一些很有用的参数,比如-t可以不断地进行ping操作,比如-l可以设置发送的Request的Data长度。另外,Windows下的IPv6中,相应的ping程序是ping6,其参数和ping是一样的。有兴趣详细了解的,可以用Ethereal之类的抓包软件来观察一下整个ping或者ping6过程中的报文是什么样子的。
另外,不知道大家有没有注意过,Windows xp和Windows 2k下对于ping程序的实现是有一点区别的,xp下的ping能够较为精确计算整个来回的时间,而2k下,一般小于10ms的它都显示为<10ms,而xp可以精确到1ms。当然,如果是局域网内相邻的2台机器互相ping的话,只要网络不是非常拥塞,那么一般在xp下可以看到的结果是<1ms。这些也可以通过Ethereal抓包的结果来验证。

7.安全考虑
(1)关于ICMP报文的认证和加密
ICMP报文可以通过使用IP Authentication Header来实现认证机制,
(2)ICMP攻击
这篇RFC中还简单描述了几种ICMP报文攻击的情况。由于IPv6加强了安全性方面的规范,因此这些攻击可以通过某些手段和方法来避免。具体的在其他几篇描述IPv6安全性的RFC中有详细介绍,这里就不介绍了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #2 (permalink)  
旧 2004-10-18
zweily 的头像
版主
 
注册日期: 2002-09-24
帖子: 425
文章: 10
zweily 正向着好的方向发展
默认

RFC原文。
上传的附件
文件类型: txt rfc2463.txt (33.4 KB, 1 次查看)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用



所有时间均为格林尼治时间 +9。现在的时间是 07:55 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2009,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0