IP数据报格式
各个字段的分析:
- 版本 4位
指IP协议的版本,通信双方使用的IP协议版本必须保持一致。主要用两个版本IPV4、IPV6 - 首部长度 4位
4位表示的最大十进制数是15。注意,首部长度字段所表示数的单位是32位(也就是4个字节)!
Q 为什么单位是4个字节?
A 首先IP首部固定长度最少为20字节。那么假设单位表示的是1位,那么首部长度最多能表示15位,显然不符合首部长度要求;假设单位表示的是1个字节,那么首部长度最多能表示15个字节,显然也不符合首部长度要求!
因为IP首部固定长度是20字节,因此首部长度字段的最小值是5(二进制表示为0101)。而当首部长度达到最大值1111时(十进制时15),首部长度达到最大值15个32位字长,也就是60字节。
那么如果IP分组的首部长度不是4字节(32位)的整数倍时,必须利用最后的填充字段进行填充!
-
区分服务 8位
一般情况并不使用。
-
总长度 16位
总长度指首部和数据之和得到长度,单位为字节。总长度字段为16位,因此数据报最大长度为
2 16 − 1 = 65535 ( 单 位 : 字 节 ) 2^{16}-1 = 65535(单位:字节) 216−1=65535(单位:字节)
但是!最小IP分组首部长度为20字节,那么最大封装数据报长度为65515字节!
IP层下的数据链路层协议规定了一个数据字段的最大长度,称为最大传送单元MTU(Maximum Transfer Unit)。
当一个IP数据报封装成链路层的帧时,数据报的长度(首部加上数据部分)一定不能超过下面的数据链路层所规定的MTU值。
常见以太网规定其MTU值就是1500字节,如果所传送的数据报长度超过数据链路层的MTU值,就必须把过长的数据报进行分片处理。
虽然使用尽可能长度IP数据报会使传输效率得到提高(IP数据报首部长度站数据报总长度比例会更小);但是数据报更短也有好处,数据报越短路由器转发的速度就越快。
IP协议规定,所有主机和路由器,必须能够接收长度不超过576字节的数据报。
这是假定上层交下来的数据长度(不包括首部)有512字节,加上IP首部60字节,另外加上4字节的富余量,得到576字节。
那么,如果需要发送长度超过576字节的数据报时,则需要分片,分片前应当先了解目的主机能否接受所要发送的数据报长度。
分片后,数据报首部中的“总长度”字段是指**分片后的每一个分片**的首部长度与该分片的数据长度的总和。
-
标识 16位
它用于数据报各分片最终被重装成来原来的数据报。它是一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。目的主机将相同标识字段值的各分片数据报最后进行正确地重装(合片)。 -
标志 3位
只有两位有意义:- 最低位标志MF(More Fragment)。MF=1表示后面还有分片的数据报;MF=0表示这个数据报中的最后一片。
- 中间标志位DF(Don’t Fragment)。DF=1表示不允许分片,DF=0表示允许分片。为什么会不允许分片?因为要保持数据的完整性!
-
片偏移 13位
较长的分组分片后,某片在原分组中的相对位置是有片偏移来表示的。片偏移以8个字节为偏移单位,也就是说每个分片的长度一定是8字节(64位)的整数倍。Q 为什么每个分片的偏移单位是8字节(64位)?
A 因为片段偏移字段比总长度字段即16比特(并且2^3是8)短3比特。片偏移以8个字节为偏移单位,即每个分片的长度一定是8字节的整数倍。
设IP数据报分组总长(包括首部和数据报)为L,待转发链路的MTU位M。如果L>M并且DF=0,则可以进行分片。因为一个最大分片可封装的数据(字节)大小应该是8的倍数。
所以一个分片中最多能包含数据长度d为
d
=
r
o
u
n
d
[
(
M
−
20
)
/
8
]
∗
8
d=round[(M-20)/8] * 8
d=round[(M−20)/8]∗8
那么需要总片(分组)数n为:
n
=
c
e
i
l
[
(
L
−
20
)
/
d
]
n=ceil[(L-20)/d]
n=ceil[(L−20)/d]
那么每片的片偏移字段值(注意这是分组后当前分组第一个字节的序号)Fi为:
F
i
=
d
/
8
∗
(
i
−
1
)
(
1
<
=
i
<
=
n
)
F_i = d/8 * (i-1)\quad \quad (1<=i<=n)
Fi=d/8∗(i−1)(1<=i<=n)
每片的总长则需要分开讨论,最后一块和前面的可能不一样:
L
i
=
d
+
20
(
1
<
=
i
<
n
)
L_i = d + 20\quad \quad (1<=i<n)
Li=d+20(1<=i<n)
L i = L − ( n − 1 ) d ( i = n ) L_i=L-(n-1)d \quad \quad (i=n) Li=L−(n−1)d(i=n)
-
生存时间 8位
生存时间字段常用的英文缩写是TTL(Time to Live),表明数据报在网络中的寿命。
该字段目的是为了防止无法交付的数据报无限制地在互联网中兜圈圈!消耗互联网可用资源!!
每经过一个一个路由器时,就把TTL减去在路由器所消耗掉的一段时间。若数据报在路由器消耗的时间小于一秒,就把TTL减一,当TTL值减为0时,则丢弃这个数据报并且会送ICMP报文! -
协议 占8位
指出报文所携带的数据使用了什么协议,以便使目的主机的IP层直到应该将数据报交给哪个协议进行处理。 -
首部校验和 16位
这个字段只检验数据报的首部,不包括数据部分。每经过一个一个路由器,路由器都需要重新计算一下首部校验和(一些字段,如生存时间、标志、片偏移等都可能发生变化)。
为了进一步减少校验和的工作量,IP首部的校验和不采用复杂的CRC校验码,而采用下面的简单计算方法:-
发送方:
-
先把IP数据报首部划分为许多16位字的序列,并把校验和字段置为0
-
用反码算术运算把所有16位字相加
反码运算规则:从低位到高位逐位逐列进行计算,0和0相加得到0,0和1相加得到1,但1和1相加是0并且产生一个进位1,加到下一列。若最高位相加后产生进位,则最后得到的结果要加1。
-
将得到的==和的反码写入校验和字段==。
-
-
接收方
- 将首部的所有16位字(包括校验和)使用反码算术运算相加一次
- 将得到的和取反码,得到的就是结果。如果结果是0,那么就可以保留这个数据报;否则即认为出现差错,并将数据报丢弃。
校验和计算得到结果位0也不一定说明数据报是对的!应该要交给上层进一步确定报文是否有误。
-
-
源地址 32位
-
目的地址 32位
-
IP数据报首部可变部分
- 选项字段用来支持排错、测量以及安全等措施,内容很丰富。
- 此字段的长度可变,从1~40个字节不等,取决于所选择的项目。
- 某些选项项目只需要1个字节,它只包括1个字节的选项代码。但还有些选项需要多个字节,这些选项一个个拼接起来,中间不需要有分隔符,最后用全0的填充字段补齐成为4字节的整数倍。
Q 为什么要填充成4字节的整数倍?
A 这是由首部长度字段所决定的!因为首部长度字段的单位是32个字(也就是4个字节)!