当前位置:   article > 正文

深入理解TCP/IP协议的实现之ip分片重组(基于linux1.2.13)_tcp 重组

tcp 重组

我们都知道数据链路层有mtu的限制,如果我们上层发的包太大,那就要分片,那么对端就需要重组分片,组装好再通知上层。我们看一下分片重组的过程。我们看一下分片重组中用到的数据结构。ipq结构体是代表一个完整的传输层包,他被ip层分成了多个分片。ipfrag结构体是代表一个ip分片。他是传输层包的一个部分。

再看一下ip报文的格式。

我们开始分析组片之前,先看一下一些基础函数。 1 创建一个用于重组传输层数据包的结构体ipq。这个是第一个ip分配到达时调用的。他维护了属于同一个分片组(同一个传输层数据包)的多个分片。

  1. // 创建一个队列用于重组分片,iphdr 即ip报文头
  2. static struct ipq *ip_create(struct sk_buff *skb, struct iphdr *iph, struct device *dev)
  3. {
  4. struct ipq *qp;
  5. int maclen;
  6. int ihlen;
  7. // 申请一个新ipq的表示分片队列
  8. qp = (struct ipq *) kmalloc(sizeof(struct ipq), GFP_ATOMIC);
  9. // 初始化内存
  10. memset(qp, 0, sizeof(struct ipq));
  11. // skb->data指向mac头首地址,mac头长度等于ip头减去mac头首地址
  12. maclen = ((unsigned long) iph) - ((unsigned long) skb->data);
  13. // 分配内存保存mac头
  14. qp->mac = (unsigned char *) kmalloc(maclen, GFP_ATOMIC);
  15. // ip头长度由ip头字段*4得出,多分配8个字节给icmp
  16. ihlen = (iph->ihl * sizeof(unsigned long));
  17. qp->iph = (struct iphdr *) kmalloc(ihlen + 8, GFP_ATOMIC);
  18. // 把mac头内容复制到mac字段
  19. memcpy(qp->mac, skb->data, maclen);
  20. // 把ip头和传输层的8个字节复制到iph字段,8个字段的内容用于发送icmp报文时
  21. memcpy(qp->iph, iph, ihlen + 8);
  22. // 未分片的ip报文的总长度,未知,收到所有分片后重新赋值
  23. qp->len = 0;
  24. // 当前分片的ip头和mac头长度
  25. qp->ihlen = ihlen;
  26. qp->maclen = maclen;
  27. qp->fragments = NULL;
  28. // 关联的设备
  29. qp->dev = dev;
  30. // 开始计时,一定时间内还没收到所有分片则重组失败,发送icmp报文
  31. qp->timer.expires = IP_FRAG_TIME;
  32. qp->timer.data = (unsigned long) qp;
  33. qp->timer.function = ip_expire;
  34. // 开始计时,如果超时没有收到新的ip分片,则重组失败,如果收到一个新的,重置计时器
  35. add_timer(&qp->timer);
  36. qp->prev = NULL;
  37. cli();
  38. // 头插法插入分片重组的队列
  39. qp->next = ipqueue;
  40. /*
  41. 如果当前新增的节点不是第一个节点则把当前第一个
  42. 节点的prev指针指向新增的节点
  43. */
  44. if (qp->next != NULL)
  45. qp->next->prev = qp;
  46. //更新ipqueue指向新增的节点,新增节点是首节点
  47. ipqueue = qp;
  48. sti();
  49. return(qp);
  50. }

根据一开始的结构体,上面的代码不难理解。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号