IPv4
IPv4 的全称是 Internet Protocol version 4
,是 Internet 协议的第四版。IPv4 是一种无连接的协议,这个协议会尽最大努力交付数据包,也就是说它不能保证任何数据包能到达目的地,也不能保证所有的数据包都会按照正确的顺序到达目标主机,这些都是由上层比如传输控制协议控制的。也就是说,单从 IP 看来,这是一个不可靠的协议。
前面我们讲过网络层分组被称为
数据报
,所以我们接下来的叙述也会围绕着数据报展开。
IPv4 的数据报格式如下
IPv4 数据报中的关键字及其解释
版本字段(Version)
占用 4 bit,通信双方使用的版本必须一致,对于 IPv4 版本来说,字段值是 4。首部长度(Internet Header Length)
占用 4 bit,首部长度说明首部有多少 32 位(4 字节)。由于 IPv4 首部可能包含不确定的选项,因此这个字段被用来确定数据的偏移量。大多数 IP 不包含这个选项,所以一般首部长度设置为 5, 数据报为 20 字节 。服务类型(Differential Services Codepoint,DSCP)
占用 6 bit,以便使用不同的 IP 数据报,比如一些低时延、高吞吐量和可靠性的数据报。服务类型如下表所示
拥塞通告(Explicit Congestion Notification,ECN)
占用 2 bit,它允许在不丢弃报文的同时通知对方网络拥塞的发生。ECN 是一种可选的功能,仅当两端都支持并希望使用,且底层网络支持时才被使用。最开始 DSCP 和 ECN 统称为 TOS,也就是区分服务,但是后来被细化为了 DSCP 和 ECN。数据报长度(Total Length)
占用 16 bit,这 16 位是包括在数据在内的总长度,理论上数据报的总长度为 2 的 16 次幂 - 1,最大长度是 65535 字节,但是实际上数据报很少有超过 1500 字节的。IP 规定所有主机都必须支持最小 576 字节的报文,但大多数现代主机支持更大的报文。当下层的数据链路协议的最大传输单元(MTU)
字段的值小于 IP 报文长度时,报文就必须被分片。标识符(Identification)
占用 16 bit,这个字段用来标识所有的分片,因为分片不一定会按序到达,所以到达目标主机的所有分片会进行重组,每产生一个数据报,计数器加1,并赋值给此字段。标志(Flags)
占用 3 bit,标志用于控制和识别分片,这 3 位分别是- 0 位:保留,必须为0;
- 1 位:
禁止分片(Don’t Fragment,DF)
,当 DF = 0 时才允许分片; - 2 位:
更多分片(More Fragment,MF)
,MF = 1 代表后面还有分片,MF = 0 代表已经是最后一个分片。
如果 DF 标志被设置为 1 ,但是路由要求必须进行分片,那么这条数据报回丢弃 分片偏移(Fragment Offset)
占用 13 位,它指明了每个分片相对于原始报文开头的偏移量,以 8 字节作单位。存活时间(Time To Live,TTL)
占用 8 位,存活时间避免报文在互联网中迷失
,比如陷入路由环路。存活时间以秒为单位,但小于一秒的时间均向上取整到一秒。在现实中,这实际上成了一个跳数计数器:报文经过的每个路由器都将此字段减 1,当此字段等于 0 时,报文不再向下一跳传送并被丢弃,这个字段最大值是 255。协议(Protocol)
占用 8 位,这个字段定义了报文数据区使用的协议。协议内容可以在 https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml 官网上获取。首部校验和(Header Checksum)
占用 16 位,首部校验和会对字段进行纠错检查,在每一跳中,路由器都要重新计算出的首部检验和并与此字段进行比对,如果不一致,此报文将会被丢弃。源地址(Source address)
占用 32 位,它是 IPv4 地址的构成条件,源地址指的是数据报的发送方目的地址(Destination address)
占用 32 位,它是 IPv4 地址的构成条件,目标地址指的是数据报的接收方选项(Options)
是附加字段,选项字段占用 1 - 40 个字节不等,一般会跟在目的地址之后。如果首部长度 > 5,就应该考虑选项字段。数据
不是首部的一部分,因此并不被包含在首部检验和中。
在 IP 发送的过程中,每个数据报的大小是不同的,每个链路层协议能承载的网络层分组也不一样,有的协议能够承载大数据报,有的却只能承载很小的数据报,不同的链路层能够承载的数据报大小如下。
IPv4 分片
一个链路层帧能承载的最大数据量叫做最大传输单元(Maximum Transmission Unit, MTU)
,每个 IP 数据报封装在链路层帧中从一台路由器传到下一台路由器。因为每个链路层所支持的最大 MTU 不一样,当数据报的大小超过 MTU 后,会在链路层进行分片,每个数据报会在链路层单独封装,每个较小的片都被称为 片(fragement)
。
每个片在到达目的地后会进行重组,准确的来说是在运输层之前会进行重组,TCP 和 UDP 都会希望发送完整的、未分片的报文,出于性能的原因,分片重组不会在路由器中进行,而是会在目标主机中进行重组。
当目标主机收到从发送端发送过来的数据报后,它需要确定这些数据报中的分片是否是由源数据报分片传递过来的,如果是的话,还需要确定何时收到了分片中的最后一片
,并且这些片会如何拼接一起成为数据报。
针对这些潜在的问题,IPv4 设计者将 标识、标志和片偏移放在 IP 数据报首部中。当生成一个数据报时,发送主机会为该数据报设置源和目的地址的同时贴上标识号
。发送主机通常将它发送的每个数据报的标识 + 1。当某路由器需要对一个数据报分片时,形成的每个数据报具有初始数据报的源地址、目标地址和标识号。当目的地从同一发送主机收到一系列数据报时,它能够检查数据报的标识号以确定哪些数据是由源数据报发送过来的。由于 IP 是一种不可靠的服务,分片可能会在网路中丢失,鉴于这种情况,通常会把分片的最后一个比特设置为 0 ,其他分片设置为 1,同时使用偏移字段指定分片应该在数据报的哪个位置。
IPv4 寻址
IPv4 支持三种不同类型的寻址模式,分别是
- 单播寻址模式:在这种模式下,数据只发送到一个目的地的主机。
- 广播寻址模式:在此模式下,数据包将被寻址到网段中的所有主机。这里客户端发送一个数据包,由所有服务器接收:
- 组播寻址模式:此模式是前两种模式的混合,即发送的数据包既不指向单个主机也不指定段上的所有主机
IPv6
随着端系统接入的越来越多,IPv4 已经无法满足分配了,所以,IPv6 应运而生,IPv6 就是为了解决 IPv4 的地址耗尽问题而被标准化的网际协议。IPv4 的地址长度为 4 个 8 字节,即 32 比特, 而 IPv6 的地址长度是原来的四倍,也就是 128 比特,一般写成 8 个 16 位字节。
从 IPv4 切换到 IPv6 及其耗时,需要将网络中所有的主机和路由器的 IP 地址进行设置,在互联网不断普及的今天,替换所有的 IP 是一个工作量及其庞大的任务。我们后面会说。
我们先来看一下 IPv6 的地址是怎样的
版本
与 IPv4 一样,版本号由 4 bit 构成,IPv6 版本号的值为 6。流量类型(Traffic Class)
占用 8 bit,它就相当于 IPv4 中的服务类型(Type Of Service)。流标签(Flow Label)
占用 20 bit,这 20 比特用于标识一条数据报的流,能够对一条流中的某些数据报给出优先权,或者它能够用来对来自某些应用的数据报给出更高的优先权,只有流标签、源地址和目标地址一致时,才会被认为是一个流。有效载荷长度(Payload Length)
占用 16 bit,这 16 比特值作为一个无符号整数,它给出了在 IPv6 数据报中跟在鼎昌 40 字节数据报首部后面的字节数量。下一个首部(Next Header)
占用 8 bit,它用于标识数据报中的内容需要交付给哪个协议,是 TCP 协议还是 UDP 协议。跳限制(Hop Limit)
占用 8 bit,这个字段与 IPv4 的 TTL 意思相同。数据每经过一次路由就会减 1,减到 0 则会丢弃数据。源地址(Source Address)
占用 128 bit (8 个 16 位 ),表示发送端的 IP 地址。目标地址(Destination Address)
占用 128 bit (8 个 16 位 ),表示接收端 IP 地址。
可以看到,相较于 IPv4 ,IPv6 取消了下面几个字段
- 标识符、标志和比特偏移:IPv6 不允许在中间路由器上进行分片和重新组装。这种操作只能在端系统上进行,IPv6 将这个功能放在端系统中,加快了网络中的转发速度。
- 首部校验和:因为在运输层和数据链路执行了报文段完整性校验工作,IP 设计者大概觉得在网络层中有首部校验和比较多余,所以去掉了。IP 更多专注的是快速处理分组数据。
- 选项字段:选项字段不再是标准 IP 首部的一部分了,但是它并没有消失,而是可能出现在 IPv6 的扩展首部,也就是下一个首部中。