IPv4协议数据报格式
IPv4协议
IP协议是TCP/IP协议中最核心的部分,所有TCP、UDP、ICMP等协议的数据都要通过IP协议封装过后才能传输。
这里我们先来看一下IP协议数据报的格式。
详细的IP协议文档可以直接查看RFC791。
这篇文章的结构也是基于RFC791来写的,后续的IP协议是有更新的,比如RFC2474,它将TOS这个字段修改成了DS field。
我们这里先以最初的RFC791来讲解,因为关键的字段变化不大。
IPv4数据报格式
各字段代表的意义
-
Version/版本,4个bit位。我们常用的就是IPv4和IPv6,相对应的版本号就是4和6,转化成4位bit分别是0100和0110。
-
Header Length/首部长度,4个bit位。该值包含了固定字段和可选字段的长度,以4字节为一个单位。计算公式为:HeaderLength = (固定字段字节数 + 可选字段字节数)/ 4。当你的首部只有固定字段的话,那么HeaderLength=20/4=5。当这个值小于5的时候,就表示IP数据报出现错误了。因为该字段只有4个bit位,那最大值就是1111,也就是15,那15*4=60,即首部最长只能有60个字节。
-
TOS/服务类型,8个bit位。bit0-2可以设置该数据报的优先级,分为从低到高0-7个优先级。这个值通常由上层的应用协议来设置,不过现在几乎不使用了。因为谁都不想把自己的优先级降低,而如果大家都把自己的优先级设置到最高,最终的结果就是大家都没有优先级。bit3-5用来标志自己是什么样的服务,这三个bit位同一时间只能设置1个为1,bit3表示低延迟,bit4表示高吞吐量,bit5表示高可靠性。bit6-7是保留位,需要设置为0.
-
Total Length/总长度,16个bit位。该值是数据报首部加上数据部分的总长度,以字节为一个单位。由于是16bit,最大值是65535,但实际上不会一次发送这么长的数据报,大多数的链路层都会将其进行分别在转发。
-
Identification/标识,16个bit位。表示一个数据报的唯一ID。通常情况下,每发送一个IP数据报,该值就加1。同一个数据报的不同分片,使用同一个ID。
-
Flags/标志,3个bit位。确切的来说,是分片标志位。bit0保留位,需要设置为0。bit1表示是否进行分片,0表示可以分片,1表示不可以分片。bit2表示是否是最后一个分片,0表示是最后一个分片,1表示不是最后一个分片,后续还有分片。
-
Fragment Offset/分片偏移,13个bit位。表示该分片在整个数据报中的位置。第一个分片的偏移为0。该值以8字节为一个单位,比如该值如果是10,那么表示该分片在整个数据报80字节的位置。如此,最大值为8192,8192*8=65536,正好可以覆盖IP数据报最大长度65535。
-
TTL/生存时间,8个bit位。RFC文档里最初的意思是以秒为单位纪录当前数据报在网络中生存的期限。不过,众所周知,现实中,我们一直把它表示为可以在路由器中跳转的次数,每经过一个路由器该值就减1。当该值等于0的时候,当前数据报将被丢弃。
-
Protocol/协议,8个bit位。表示IP的上一层是什么协议,如TCP、UDP等。目前我们常用的协议号可以从这个协议列表中查询获得。
-
Header Checksum/校验和,16个bit位。该字段只对IP数据报的首部进行校验。
-
Source Address/源IP地址,32个比特位。
-
Destination Address/目的IP地址,32个比特位。这两个地址就是我们常说的192.168.1.1这种地址。
-
Option/可选项。这个字段很少用,通常只会给实验或军事领域使用。因为此字段是变长的,所以在此字段后面加上Padding字段,将其填充为32bit的整数倍。
-
Data/数据。这里就存放着上层协议的数据。