IP数据报头
IP数据报头
IP报头如下所示,现在逐个分析一下各个字段。
4位版本字段表示IPv4或者IPv6。
4位部首长度表示IP部首的长度。
8位服务类型:服务类型(TOS)字段包括一个3 bit的优先权子字段(现在已被忽略),4 bit的TOS子字段和1 bit未用位但必须置0。4 bit的TOS分别代表:最小时延、最大吞吐量、最高可靠性和最小费用。4 bit中只能置其中1 bit。如果所有4 bit均为0,那么就意味着是一般服务。
16位总长度字段是指整个IP数据报的长度,以字节为单位。利用首部长度字段和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。由于该字段长16比特,所以IP数据报最长可达65535字节。当数据报被分片时,该字段的值也随着变化。
对于16位标识、3位标志、13位片偏移涉及IP数据报分片与重组的知识(下面分析)。
8位的生存时间(TTL)指的是数据包可以经过路由器传送的最大跳数。
8位协议指传输层协议(TCP、UDP)
16位检验和(CRC)用于数据包的校验
源目地址易于理解,这些是32位的IP地址。
IP数据报分片与重组
对于发送端发送的每份I P数据报来说,其标识字段都包含一个唯一值。该值在数据报分片时被复制到每个片中。
标志字段用其中一个比特来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置1。
片偏移字段指的是该片偏移原始数据报开始处的位置。
另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。
最后,标志字段中有一个比特称作“不分片”位。如果将这一比特置1,I P将不对数据报进行分片。相反把数据报丢弃并发送一个I C M P差错报文(“需要进行分片但设置了不分片比特”)给起始端。
当I P数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立。这样,当数据报的这些片到达目的端时有可能会失序,但是在I P首部中有足够的信息让接收端能正确组装这些数据报片。尽管I P分片过程看起来是透明的,但有一点让人不想使用它:即使只丢失一片数据也要重传整个数据报。为什么会发生这种情况呢?因为I P层本身没有超时重传的机制——由更高层来负责超时和重传(T C P有超时和重传机制,但U D P没有。
一些U D P应用程序本身也执行超时和重传)。当来自T C P报文段的某一片丢失后,T C P在超时后会重发整个T C P报文段,该报文段对应于一份I P数据报。没有办法只重传数据报中的一个数据报片。事实上,如果对数据报分片的是中间路由器,而不是起始端系统,那么起始端系统就无法知道数据报是如何被分片的。就这个原因,经常要避免分片。
例子:在一个以太网上,数据帧的最大长度是1500字节,
其中1427字节留给数据,假定IP首部为20字节,UDP首部为8字节。我们分别以数据长度为1471, 1472, 1473和1474字节运行s o c k程序。最后两次应该发生分片:相应的tcpdump输出如图所示。
前两份UDP数据报(第1行和第2行)能装入以太网数据帧,没有被分片。但是对应于写1 4 7 3字节的I P数据报长度为1 5 0 1,就必须进行分片(第3行和第4行)。同理,写1 4 7 4字节产生的数据报长度为1 5 0 2,它也需要进行分片(第5行和第6行)。
当I P数据报被分片后, t c p d u m p打印出其他的信息。首先,frag 26304(第3行和第4行)和frag 26313(第5行和第6行)指的是I P首部中标识字段的值。分片信息中的下一个数字,即第3行中位于冒号和@号之间的1 4 8 0,是除I P首部外的片长。两份数据报第一片的长度均为1 4 8 0:U D P首部占8字节,用户数据占1 4 7 2字节(加上I P首部的2 0字节分组长度正好为1 5 0 0字节)。第1份数据报的第2片(第4行)只包含1字节数据——剩下的用户数据。第2份数据报的第2片(第6行)包含剩下的2字节用户数据。在分片时,除最后一片外,其他每一片中的数据部分(除I P首部外的其余部分)必须是8字节的整数倍。
在本例中, 1 4 8 0是8的整数倍。位于@符号后的数字是从数据报开始处计算的片偏移值。两份数据报第1片的偏移值均为0(第3行和第5行),第2片的偏移值为1 4 8 0(第4行和第6行)。跟在偏移值后面的加号对应于I P首部中3 bit标志字段中的“更多片”比特。设置这一比特的目的是让接收端知道在什么时候完成所有的分片组装。最后,注意第4行和第6行(不是第1片)省略了协议名( U D P)、源端口号和目的端口号。协议名是可以打印出来的,因为它在I P首部并被复制到各个片中。但是,端口号在U D P首部,只能在第1片中被发现。发送的第3份数据报(用户数据为1 4 7 3字节)分片情况如下图所示。