1. 开发环境

 操作系统:SylixOS
 编程环境:RealEvo-IDE3.1
 硬件平台:AT9x25开发板


2. 技术实现

SylixOS系统使用的网络协议栈是Lwip协议栈。Lwip是Light Weight (轻型)IP协议,有无操作系统的支持都可以运行。Lwip实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用,它只需十几KB的RAM和40K左右的ROM就可以运行,这使Lwip协议栈适合在低端的嵌入式系统中使用。Lwip协议栈主要关注的是怎么样减少内存的使用和代码的大小,这样就可以让Lwip适用于资源有限的小型平台例如嵌入式系统。为了简化处理过程和内存要求,Lwip对API进行了裁减,可以不需要复制一些数据。网络协议栈是以层的结构来实现的。链路层具有最大传输单元MTU这个特性,它限制了数据帧的最大长度,不同的网络类型都有一个上限值。以太网的MTU是1500。如果IP层有数据包要传,而且数据包的长度超过了MTU,那么IP层就要对数据包进行分片(fragmentation)操作,使每一片的长度都小于或等于MTU。我们假设要传输一个UDP数据包,以太网的MTU为1500字节,一般IP首部为20字节,UDP首部为8字节,数据的净荷(payload)部分预留是1500-20-8=1472字节。如果数据部分大于1472字节,就会出现分片现象。本篇文章主要介绍Lwip里对收到的IP分片报文重组的实现。

2.1 IP报文重组宏观分析


图 2 1 IP包重组框图
IP包的重组的简单流程如图2-1所示。

首先,Lwip协议里会有一个单向链表,每个结点是一个ip_reassdata的结构体,reassdatagrams指向这个链表。

ip_reassdata结点用来进行分片包的重组,每个结点对应着一个完整的IP包。这个结构体里有一个指向pbuf的成员。当一个IP报文通过ip4_input向上层传输时,会检测是否属于分片包,如果是,则需要进行分片重组。

重组时,会从reassdatagrams链表里查找是否已经有ip_reassdata这个结构体了,如果有,就会改变每个分片包的报头,这里是通过一个ip_reass_helper结构体改变的。改变完之后,会把这个分片包根据偏移插入到ip_reassdata这个结构体后面对应的位置。如果在reassdatagrams链表里查找不到对应的ip_reassdata这个结构体,那么说明这个分片包是收到帧的第一个报文,因此会创建一个新的ip_reassdata结构体,然后再进行后续操作。插入完成后,协议栈会检测报文是否全部接收并重组完成。如果完成,就会从reassdatagrams链表中把ip_reassdata结构体删除并把重组好的报文返回给ip4_input。

2.2 代码分析

IP包的分片重组是通过ip4_reass 这个函数来完成的。判断需要重组时都会调用这个函数,这个函数的主要内容如下:
1. 对收到的IP报文的首部长度检测,Lwip目前是不支持IP报文头带填充位的。
2. 通过IP报文头,获得偏移和数据报文的长度。
3. lwip的一个特性:它对reassdatagrams链表上的pbuf的总数是有限制的,因此协议栈会判断加上收到的这些pbuf的个数后,会不会超过这个限制。
4. 如果超过了,会删除链表中存在时间最长的那个。
5. 从链表中寻找对当前的pbuf对应的ip_reassdata结构体。如果没有,则会新创建一个结构体。
6. 现在应该已经找到一个合适的 ip_reassdata结构体了,此时会做一个判断:如果当前的这个IP报文的偏移为0并且此时的 ip_reassdata结构体的偏移也不等于0,那么需要把当前的这个IP分片报文的头部拷贝到 ip_reassdata结构体中。
7. 检测当前收到的IP分片报文是不是最后一个,如果是最后一个,那么,就更新一下当前IP分片报文对应的 ip_reassdata结构体。
8. 上述两个检测完成之后,会调用ip_reass_chain_frag_into_datagram_and_validate,找到一个合适的地方,把IP分片包插进去。
9. 检测当前的报文是否组装完成,如果完成,返回一个非0的值。否则,返回0。
10. 上述检测结果如果是没有完成,则ip4_reass 直接返回。如果完成了,则会对 ip_reassdata结构体的iphdr字段做修改,包括报文总长度、校验和,并且把iphdr字段全部拷贝到第一个分片包的头部,这样,整个IP包的信息就出现在第一个分片包的信息里。
11. 接下来,把其他的IP分片包的的信息头删除,这样一个完整的IP包就重组完成了。
12. 最后,调用 ip_reass_dequeue_datagram 将ip_reassdata结构体从整个链表中删除。 代码执行到这里,整个重组基本完成。

3. 参考资料

Lwip IP包分片重组相关推荐

  1. IP虚拟分片重组配置命令

    1.1.1  display ip virtual-reassembly [命令] display ip virtual-reassembly [ interface interface-type i ...

  2. ip virtual-reassembly:IP虚拟分片重组

    把分片的报文在自身组装起来,这样可以识别一些攻击之类的 FW功能. IP虚拟分片重组 为了避免每个业务模块(如:IPSec.NAT和防火墙)单独处理后片先到(报文分片后)这种情况而导致复杂度过高,设备 ...

  3. linux设置socket禁止IP包分片

    背景 UDP包在传输过程中,如果对端机器的MTU小于1500,结果你发出去的包其实加上乱七八糟的头,刚好1500,本来是能被对端机器收到的,结果好巧不巧,刚好这个机器发出去的包,默认不允许分包,结果包 ...

  4. IP数据包分片重叠部分的重组问题

    原作者:Haboob Team 翻译:李华峰(邪灵) 介绍 本文将介绍 IDS 的工作原理和讨论 IP 数据包分片的重组过程,并研究不同操作系统在实现重组时的差异性. IDS(入侵检测系统)简介 ID ...

  5. IP包的生成和发送接口(1)

    http://blog.sina.com.cn/s/indexlist_1657348185_2.html   IP包的生成和发送接口 ==================== (1) Linux内核 ...

  6. linux 内核 丢弃分片包,LINUX内核关于IP分片重组问题请教

    最近研究学习IP分片重组,也拜读了不少dx的阅读理解.可还是有疑问,请教xdm. 源代码:linux-2.4.26\linux-2.4.26\net\ipv4\ip_fragment.c IP分片的重 ...

  7. 数据包分片和重组 MTU与MSS

    前言 任何一台主机都有必要对IP分片进行相应的处理. 分片往往出现在网络上遇到比较大的报文无法一下子发送出去才会进行处理. 正文 比如说在前一个FDDI链路中的报文大小为4352字节,小于其MTU所以 ...

  8. 浅谈IP数据报分片与重组

    大多数TCP/IP通信都建立在IP协议之上,可以使用Wireshark抓取IP数据包.在IP数据报中,最大长度可以达到65535字节,但是很少有底层的物理层网络能够封装如此大的数据包,因此将IP数据报 ...

  9. 思科 IPv4 /IP fragmentation 分片抓包解析

    思科 IPv4 /IP fragmentation 分片抓包解析(MTU) Interface Serial1/0 on Router0 has been configured with an MTU ...

最新文章

  1. 2021年大数据ELK(五):Elasticsearch中的核心概念
  2. 基于切面和注解的Redis分布式实现
  3. php filter 文件包含,php://filter(文件包含漏洞利用)及php://input
  4. div嵌套div的居中问题
  5. Ubuntu 20.04 E:无法找到软件包python-pip 安装python2.7
  6. SAP Cloud for Customer 如何直接消费S/4HANA API
  7. 多模态语义分析_情感分析、多模态NLP、多语言翻译...这场NLP知识盛宴不可错过!...
  8. 第50课 书香阁的座位数
  9. 【STM32】【STM32CubeMX】STM32CubeMX的使用之一:工程建立之点亮你的LED
  10. android 动画之漂移,Android之自定义Drawable实现灵动的红鲤鱼动画(上篇)
  11. 【转】Monkey测试3——Monkey测试结果分析
  12. *第十五周*数据结构实践项目二【用哈希法组织关键字】
  13. Vue项目开发相关问题总结
  14. 安卓otg识别ntfs_你知道手机的OTG功能吗?学会用之后再也不担心内存不够了!...
  15. Android启动优化--异步优化
  16. RocketMQ独孤九剑-总纲
  17. 为什么爱奇艺会显示联通免流量服务器,联通爱奇艺流量定向包是怎么回事啊,是不是开通之后,这一个月里面看视讯免流量的...
  18. 用计算机亩换算成平方,平方换算亩计算器(农村土地面积计算公式)
  19. 解决oracle异常ORA-01012: not logged on
  20. python 条形图 负值_使用python matplotlib获取正负值的堆积条形图

热门文章

  1. 模型涨点的思路,深度学习训练的tricks-计算机视觉
  2. typeof数据类型
  3. drupal安装详解
  4. mustache模板技术简介
  5. 让IIS支持任意扩展名和未知扩展名的下载
  6. DS1302输出时间,在lcd上显示
  7. 计算机网络-HTTP代理服务器
  8. Discuz二次开发基本知识总结
  9. [tyvj2054] 四叶草魔杖 (最小生成树 状压dp)
  10. 毛哥的快乐生活(27) Servlet版新闻网站之接受用户页面请求