《TCP/IP详解,卷2:实现》读书笔记-IP分片和重组

 
IP具有一种重要功能,就是当分组过大而不适合在所选硬件接口上发送时,能够对分组进行分片。过大的分组被分成两个或多个大小适合在所选定网络上发送的IP分片。而在去目的主机的路途中,分片还可能被中间的路由器继续分片。在目的主机上,一个IP数据报可能放在一个IP分组内或者多个IP分组内。因为各个分片可能以不同的路径到达目的主机,所以只有目的主机才有机会看到所有分片。因此,也只有目的主机才能把所有分片重装成一个完整的数据报,提交给合适的运输层协议。
IP首部内有三个字段实现分片和重装:标识字段(ip_id)、标志字段(ip_off的3个高位比特)和偏移字段(ip_off的13个低位比特)。标志字段由三个1bit标志组成。
1) 比特0是保留的,必须为0;
2) 比特1是“不分片”(DF)标志 ,如果将这一比特置1,IP将不对数据报进行分片 ,这时如果有需要进行分片的数据报到来,会丢弃此数据报并发送一个ICMP差错报文给起始端。
3) 比特2是“更多分片”(MF)标志。 除了最后一片外,其他每个组成数据报的片都要把该比特置 1
片偏移字段指的是该片偏移原始数据报开始处的位置。另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。
BSD中,标志和偏移字段结合起来,由ip_off访问。ip_id标识了特定数据报的分片,ip_off确定了分片在原始数据报内的位置,除最后一个分片外,MF标识每个分片。
 
 
下面先简单讲一下IP分片的流程:
1 )当IP需要分片时,会 从原来的分组中把 IP 首部和 IP 选项复制到新的分组中,IP首部复制在一个结构中,只复制那些将被复制到每个分片中的选项。
2 )设置分片包括 MF 比特的偏移字段 ( ip_off ) 。如果原来分组中已设置了 MF 比特,则在所有分片中都把 MF 置位。如果原来分组中没有设置 MF 比特,则除了最后一个分片外,其他所有分片中的 MF 都置位。
3 为分片设置长度,以网络字节序存储长度。
4 )从原始分组中把数据复制到分片中。调整新创建的分片的 mbuf 分组首部,使其具有正确的全长。把新分片的接口指针清零,把 ip_off 转换成网络字节序,计算新分片的检验和。通过 m_nextpkt 把该分片与前面的分片链接起来。
 
在讲 IP重组之前,先介绍一下ipq的结构:
struct  ipq {
    
struct  ipq  * next, * prev;     /*  to other reass headers  */
    u_char ipq_ttl;        
/*  time for reass q to live  */
    u_char ipq_p;          
/*  protocol of this fragment  */
    u_short ipq_id;         
/*  sequence id for reassembly  */
    
struct  ipasfrag  * ipq_next, * ipq_prev;
                    
/*  to ip headers of fragments  */
    
struct  in_addr ipq_src,ipq_dst;
};
 
struct  ipasfrag {
#if  BYTE_ORDER == LITTLE_ENDIAN 
    u_char ip_hl:
4 ,
        ip_v:
4 ;
#endif
#if  BYTE_ORDER == BIG_ENDIAN 
    u_char ip_v:
4 ,
        ip_hl:
4 ;
#endif
    u_char ipf_mff;        
/*  XXX overlays ip_tos: use low bit
                     * to avoid destroying tos;
                     * copied from (ip_off&IP_MF) 
*/
    
short    ip_len;
    u_short ip_id;
    
short    ip_off;
    u_char ip_ttl;
    u_char ip_p;
    u_short ip_sum;
    
struct  ipasfrag  * ipf_next;  /*  next fragment  */
    
struct  ipasfrag  * ipf_prev;  /*  previous fragment  */
};
具体结构的组织信息如下下图所示:
1)所有结构都放在一个 mbuf的数据区内。
2) ipq链表由next和prev链接起来的ipq结构组成。每个ipq结构保存了唯一标识一个IP数据报的四个字段。
3)当作为分片链表的头访问时,每个 ipq结构被看成是一个ipasfrag结构。这些分片由ipf_next和ipf_prev链接起来,分别覆盖了ipq结构的ipq_next和ipq_prev成员。
4)每个 ipasfrag结构都覆盖了到达分片的ip结构,与分片一起到达的数据在缓存中跟在该结构之后。ipasfrag结构中的字段ipf_mff,ipf_next,ipf_prev的含义与其在ip结构中不太相同。
 
IP重组的流程:
1)由于ip_off包含DF比特、MF比特以及分片偏移,如果MF比特或分片偏移非零,则DF就被掩盖掉了,分组就是一个必须被重装的分片。如果两者都为零,则分组就是一个完整的数据报,不需要进行重组。
2 )在一个全局双向链表i p q上记录不完整的数据报。分片是由4元组{ip_id、ip_src、ip_dst和ip_p}唯一标识的,利用这个 4元组作为匹配项对表ipq进行线性搜索,为当前分片找到合适的数据报。
3)修改 ip_len,从中减去标准IP首部和任何选项,把MF标志复制到ipf_mff的低位,把ip_tos覆盖掉。用8乘ip_off,把它从以8字节为单元转换成以1字节为单元。ipf_mff和ip_off决定ipintr是否应该重组。
4 )通过把当前分片与以前收到的分片组合在一起,能重装成一个完整的数据报,它就返回指向该重装好的数据报的指针。如果没有重装好,则保存该分片,跳到next去处理下一个分片。如果重装处理产生一个完整的数据报,就把这个完整的数据报上传给合适的运输层协议。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值