RFC 8200:Internet Protocol, Version 6 (IPv6) Specification在上个月(七月份)刚刚发布,趁热打铁来学习一下IPv6。你可能会问IPv6不是早就有了吗?没错,IPv6最早在1995年的时候发布于RFC 1883。但标准就是这样,旧的RFC不符合实践的地方不断被更新,于是有新的RFC出来替换旧的RFC,这是一个取其精华去其糟粕的过程。
IPv4
先来看看IPv4的协议头(在RFC 791中定义):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
我们可以根据功能对协议头部字段进行分类,下面的几类跟跟IP报文自身相关:
版本和校验相关
- Version:IP版本,为固定值4
- Header Checksum:用于校验IP报文的完整性
长度相关
- Total Length:报文长度,因为链路层可能会有填充,所以IP报文需要知道自己的长度
- IHL:Internet Header Length,为协议头+扩展项(Options)的长度,单位为32bit
分片相关
- Identification:用于标识报文分片
- Flags:跟报文分片相关的控制位
- Fragment Offset:分片在报文的位置偏移
生命周期相关
- Time to Live:报文的最大生存时间,按秒计数;经过每个路由器都要至少减去一秒
下面的字段则跟上层服务相关:
上层服务相关
- Protocol:指示次IP报文承载的上层协议类型,已TCP为例,该值是7
- Source Address:源地址
- Destination Address:目的地址
- Type of Service:这个字段简称TOS,需要特别注意;一开始它的含义被RFC 795所定义,后来被RFC 2417重新定义,被当成Differentiated Services也就是DS字段使用,后来RFC 3168又增加了和Explicit Congestion Notification相关的定义。
IPv6
IPv6最早由RFC 2460定义,后来又被许许多多的RFC更新。RFC 8200相当于是对IPv6的一次总结性修订。
IPv6对IPv4做了多方面的修改,最明显的改动是把IP地址从32位增加到128位,其他修改有:
- 简化协议头格式
- 更弹性的扩展方式
- 增加一些新功能
先看看IPv6的头:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class | Flow Label |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Length | Next Header | Hop Limit |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Source Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Destination Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
除了两个大大的128位的Source Address和Destination Address,其他部分看起来是不是简化多了?
其他从IPv4升级而来的字段:
- Version,现在这个值为6。
- Traffic Class,和IPv4的Type of Service一样,不过换了一个名字。
- Hop Limit:其实就是IPv4的Time to Live字段,因为没有网络真正去计算报文的生存时间,所以这个字段就改成Hop Limit了,意思是路由器的转发跳数限制。
和IPv4不尽相同的字段:
- Flow Label:新增的字段,用于标记一系列的报文,以至于网络能对这些报文做相似的处理。
- Payload Length:负载长度,相当于IPv4的 Total Length减去(IHL*4)
- Next Header:扩展头部,下面着重介绍
IPv6的扩展机制
IPv4虽然支持使用Options来扩展,但是Options的个数和长度是有限制的。因为IHL能表示的最大值为60字节,再减去固定的20字节,只有40个字节能用来做扩展。
IPv6的固定头部虽然有40个字节,但是它可以通过Next Header以类似链表的形式来扩展,显得更有灵活性,下面是个例子:
+---------------+------------------------
| IPv6 header | TCP header + data
| |
| Next Header = |
| TCP |
+---------------+------------------------
+---------------+-----------------+-----------------
| IPv6 header | Fragment header | fragment of TCP
| | | header + data
| Next Header = | Next Header = |
| Routing | TCP |
+---------------+-----------------+-----------------
跟IPv4相比,IPv6有两个地方需要特别指出:
- 报文的分片现在放在扩展中做了,而且必须由主机来分片,中间的路由器不能分片,相当于简化了路由器
- 原先的Checksum现在取消了,规定由TCP或者UDP这种传输层协议来计算,路由器这种三层的设备就不需要计算Checksum,省去了工作量。
另外还通过扩展头的形式增加了一些新功能,比如通过其扩展头来支持IPSec所需要的协议字段。
IPv6明确定义了哪些扩展头由主机负责,哪些扩展头中间的路由器可以更改,责任更明确了。
报文大小相关的
最后要说的一点是和网络所能报文大小相关的:
- IPv4要求网络最小能够支持68字节的报文,而进行分片
- IPv4要求主机能够处理最小576字节的报文
- IPv6要求网络和主机能够处理的最小报文是1280字节
这些数字怎么来的不得而知,更多详细信息可以参考WikiPedia的Maximum Transmission Unit。
(完)