【lwip】09-IPv4协议&超全源码实现分析( 三 )


第二个bit是不分片标志位:

  • 0:则表示 IP 层在必要的时候可以对其进行分片处理 。
  • 1:则表示 IP 数据报在发送的过程中不允许进行分片,如果这个 IP 数据报的大小超过链路层能承载的大小,这个 IP 数据报将被丢弃 。
第三个bit是更多分片标志位:
  • 0:后续没有更多分片 。即是当前分片的IP数据报是最后一个分片 。
  • 1:表示后续还有分片 。即是当前分片的IP数据报不是最后一个分片 。
9.3.7 分片偏移量字段占用13 bit 。
表示当前分片所携带的数据在整个 IP 数据报中的相对偏移位置 。
单位,8字节(2个字) 。
目标主机要接收到从0分片偏移量到最高分片偏移量的所有分片才能进行组装出完整的IP数据报 。
9.3.8 生存时间(Time-To-Live,TTL)字段占用8 bit 。
该字段用来确保数据报不会永远在网络中循环 。
IP数据报没经过一台路由器处理,该值-1 。
如果TTL字段下降到0,则路由器会丢弃该数据报,且会返回一个 ICMP 差错报文给源主机 。
9.3.9 协议字段占用8 bit 。
表示上层协议类型 。即是表示数据区的数据是哪个协议的数据报 。如:
  • 6:表示TCP协议 。
  • 17:表示UDP协议 。
  • 其它值可以自行度娘 。
9.3.10 首部校验和字段占用16 bit 。
只针对IP首部做校验,并不关系数据区在传输过程中是否出错,所以对于数据区的校验需要由上层协议负责 。
路由器要对每个收到的 IP 数据报计算其首部检验和,如果数据报首部中携带的检验和与计算得到的检验和不一致,则表示出现错误,路由器一般会丢弃检测出错误的 IP 数据报 。
需要注意的是,由于IP数据报首部的TTL字段每结果应该路由器都会-1,所以IP数据报首部检验和字段每经过一个路由器都要重新计算赋值 。
参考:关于wireshark的Header checksum出问题解决方案:https://www.it610.com/article/1290714377560858624.htm
检验和计算可能由网络网络驱动,协议驱动,甚至是硬件完成 。
高层校验通常是由协议执行,并将完成后的包转交给硬件 。
比较新的网络硬件可以执行一些高级功能,如IP检验和计算,这被成为checksum offloading 。网络驱动不会计算校验和,只是简单将校验和字段留空或填入无效信息,交给硬件计算 。
发送数据时,首部校验和计算:二进制反码求和 。
  • 把IP数据包的校验和字段置为全0 。
  • 将首部中的每 2 个字节当作一个数,依次求和 。
  • 把结果取反码 。
  • 把得到的结果存入校验和字段中 。
接收数据时,首部校验和验证过程:
  • 首部中的每 2 个字节当作一个数,依次进行求和,包括校验和字段 。
  • 检查计算出的校验和的结果是否全为1(反码应为16个0) 。
  • 如果等于零,说明被整除,校验和正确 。否则,校验和就是错误的,协议栈要抛弃这个数据包 。
为什么计算出的校验和结果全为1?
因为如果校验依时次求和,不包含校验和字段的话,得出的值就是校验和字段的反码 。
校验和的反码和校验和求和,当然是全1啦 。
9.3.11 二进制反码求和IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的 。
二进制反码求和:(求和再反码,结果一致)
  • 对两个二进制数进行加法运算 。
  • 加法规则:0+0=0,0+1=1,1+1=10(进位1加到下一bit) 。
  • 若最高两位相加仍然有进位,则在最后的结果中+1即可 。
  • 对最终结果取反码 。
相关源码参考LwIP\core\inet_chksum.c中的lwip_standard_chksum()

经验总结扩展阅读