IPv6基础知识总结
最近在做IPv6的工作,基于Linux平台,主要内容涉及IPv6协议栈处理、报文转发相关的内容,做之前对IPv6的了解基本为零,平常基本不用。各方面收集了很多资料,取其精华笔记一下。内容简单,分为三个部分。
1. IPv6首部格式
2. IPv6地址分类
3. IPv6地址格式
一. IPv6首部格式
图1. IPv6首部格式
首部固定长度40字节,包含8个字段。
1. version : 版本号,值固定为6,4个比特位。
2. Traffic Class : 通信量类,与IPv4 首部ToS字段等效。由于从来没被广泛使用,因此最终这个8位长的字段被分为两个部分。前6位被称为区分服务字段(DS字段),后2位是显示拥塞通知(ECN)字段或指示位。这些字段被用于数据报转发时的特殊处理。
3. Flow Label : 流标识。标识这个数据包属于源节点和目标节点之间的一个特定数据包序列,该字段长度为20位。举个栗子,同一个连接IPv6数据流流标识应相同。
4. Payload Length : 负载长度。不包含IPv6首部长度。这个长度就是扩展首部和数据长度和。
5 . Next Header : 指出下一个扩展首部的类型,如果没有扩展首部的话,这个字段指的是传输层的协议类型,例如TCP/UDP。关于扩展首部可参考之前的几篇博客。
6. Hop Limit : 跳数限制,这个字段和IPv4首部中TTL类似,传输过程中,每经过一个节点,该字段递减1,为0时丢弃。
7. Source Address : 128位 16字节长度 源地址。
8. Destination Address : 128位 16字节长 目的地址。
IPv4首部定义了11个字段,而IPv6首部只有8个字段,这样做能够加快路由器处理报文速度。其次,关于扩展首部的实现,IPv6也支持的相当好,扩展首部与IPv6固定首部构成级联的方式,如下图:
扩展首部包括逐跳首部、目的地首部、路由首部、分片首部等,扩展首部之间有一定的顺序并且数量上有限制。这部分内容属于扩展内容,前几篇博客专门讲了扩展头部,这篇只讲基础部分。
二. IPv6地址分类
IPv4地址分为单播地址、组播地址和广播地址。IPv6中去掉了广播地址,增加了任播地址,也就是说,IPv6地址被分为单播地址、组播地址和任播地址。
单播地址用于标识一个接口,发往该目的地址的报文会被送到被标识的接口。
组播地址用于标识多个接口,发往该目的地址的报文会被送到被标识的所有接口。
任播地址用于标识多个接口,发往该目的地址的报文会被送到被标识的所有接口中最近的一个接口上。这里关于最近的理解,可以理解为从下标数起,最小的那个。任播地址与单播地址使用同一个地址空间,也就是说,由路由器决定该数据包是做任播转发还是单播转发。
单播地址可分为下面几类:
1. 未指定地址: ::/128,即地址全为0。
2. 环回地址 : ::1/128,相当与IPv4中的127.0.0.1。
3. 全球单播地址,类似于IPv4中的公网地址。
4. 内嵌IPv4地址的IPv6地址 如 :::ffff:192.168.10.1。当需要将IPv4单播地址与IPv6全球单播地址建立联系的时候一般使用这种地址,分为两种。一种是IPv4兼容IPv6地址,另一种是IPv4映射IPv6地址。
IPv4兼容IPv6地址构成形式是96位0加上32位IPv4地址,如 ::192.168.1.1,这种地址最初用于IPv4和IPv6之间的过渡计划,但现在已经不再需要。
IPv4映射IPv6地址构成形式是80位0加上16位1,再加上IPv4地址,如::ffff:192.168.1.1。
5. 本地链路地址,前缀固定fe80::/64,如 fe80::e0:f726:4e68。凡是源地址或目的地址包含由本地链路地址的报文,路由器不应当转发它。这样的报文只能在LAN中互通。
6. 本地站点地址,前缀fec0::/10,紧接着54位子网ID,作用相当于IPv4中的私网地址,如fec0::e0:f726:4e68。只能在本站内使用,不能在公网上使用。
组播地址如下图:
最重要的字段要属于最后的组ID(Group-ID)字段了。该字段长度为112位,用以标识组播组,我们知道112位最多可以生成2112个组ID。目前,RFC2373并没有将所有的112位都定义成组标识,而是建议仅使用该112位的最低32位组ID,将剩余的80位都置0。
任播地址:
这是IPv6特有的地址类型,它用来标识一组网络接口(通常属于不同的节点)。目标地址是任播地址的数据包将发送给其中路由意义上最近的一个网络接口。适合于“One-to-One-of-Many”(一对组中的一个)的通讯场合。接收方只需要是一组接口中的一个即可,如移动用户上网就需要因地理位置的不同,而接入离用户最近的一个接收站,这样才可以使移动用户在地理位置上不受太多的限制。
任播地址从单播地址空间中进行分配,使用单播地址的任何格式。因而,从语法上,任播地址与单播地址没有区别。被分配具有任播地址的节点必须得到明确的配置,从而知道它是一个任播地址。目前,任播地址仅被用做目标地址,且仅分配给路由器。
3. IPv6地址格式
IPv6地址由3种格式。首选格式、压缩格式和内嵌IPv4地址的IPv6地址格式。
1. 首选格式:
IPv6的128位地址是按照每16位划分为一段,每段被转换为一个4位十六进制数,并用冒号隔开。这种表示方法就是首选格式,在首选格式后面加上前缀长度就是一个完整的IPv6地址格式:2001:0410:0000:0001:0000:0000:0000:45ff / 64。
2. 压缩格式:
一个或多个连续的16比特为0字符时,为了缩短地址长度,用::(两个冒号)表示,但一个IPv6地址中只允许一个::(如果出现超过一个的::,就无法判断每个::到底省略了多少个全0段),所以2001:0410:0000:0001:0000:0000:0000:45ff又可以表示为:2001:410:0:1::45ff。在某些情况下(例如表示一个包含地址的URL时),IPv6地址中的冒号分隔符可能与其它分隔符混淆,例如IP地址和端口号之间使用的冒号。在这种情况下,用括号字符[和]包围IPv6地址。例如URL:http://[2001:0db8:85a3::7344]:443/ 此外的一些规则如下:
a. 前导的零必须压缩(例如,2001:0db8::0022变成2001:db8::22)
b. ::只能用于影响最大的地方(压缩最多的零),但并不是针对16位的块,如果多个块中包含等长度的零,则顺序靠前的将被替换为::
c .a到f的十六进制数字应该用小写表示。
3. 内嵌IPv4地址的IPv6地址格式分为如下两种:
IPv4兼容的IPv6地址: 0:0:0:0:0:0:192.168.1.2或者::192.168.1.2
IPv4映射的IPv6地址: 0:0:0:0:0:ffff:192.168.1.2或者::ffff:192.168.1.2
IPv6的基本内容就是上面这些,还有一点就是48位MAC地址转换64位IPv6网络ID的方式如下:
一、将48位的MAC地址从中间分开,插入一个固定数值FFFE
0050:3EE4:4C00-->0050:3EFF:FEE4:4C00
二、将首字节第7个比特位取反,如果原来是0,就变为1,如果原来是1,就变为0
0050:3EFF:FEE4:4C00-->0250:3EFF:FEE4:4C00
关于IPv6扩展报文请参考:
1. IPv6扩展头部 (一) 扩展头部格式、类型与扩展选项
2. IPv6扩展头部 (三) 路由头部 Routing Header for IPv6
3. IPv6扩展头部 (四) 分片头部 Fragment Header for IPv6
参考资料:
1. 《TCP/IP详解-卷一:协议》W.Richard Stevens。原书第二版。5.3.3节。
2. RFC2460 : https://tools.ietf.org/html/rfc2460