IPv4协议详解:头部结构、分片与重组、IP路由原理

IPv4,说白了就是互联网的“门牌号系统”。没有它,数据包就不知道往哪儿送。我做了十几年网络排障,见过太多因为IP协议理解不透彻导致的诡异问题。今天咱们就把IPv4从头到脚拆开看看。

IPv4头部结构:20字节的硬核设计

IPv4头部固定部分只有20字节,但每个字段都有讲究。我当年刚入行时,觉得这些字段就是背背而已,直到有一次抓包分析一个丢包问题,才发现是TTL字段搞的鬼。

字段 长度(bit) 说明
Version 4 固定为4,标识IPv4
IHL 4 头部长度,单位4字节,最小5
Type of Service 8 服务类型,现在常用DSCP
Total Length 16 整个IP包长度,含头部
Identification 16 标识符,用于分片重组
Flags 3 DF/MF位,控制分片
Fragment Offset 13 分片偏移量,单位8字节
Time to Live 8 生存时间,每跳减1
Protocol 8 上层协议,6=TCP,17=UDP
Header Checksum 16 头部校验和
Source Address 32 源IP地址
Destination Address 32 目的IP地址

关键点:IHL字段如果值为5,表示头部20字节无选项。如果大于5,说明有IP选项字段,但实际网络中很少用。我曾经见过一个厂商设备默认加了IP时间戳选项,导致MTU计算异常,排查了两天才找到根因。

分片与重组:MTU的博弈

为什么需要分片?因为链路层有MTU限制。以太网MTU是1500字节,如果IP包超过这个值,就必须拆开。嗯,这里要注意——分片是IPv4的特性,IPv6已经把这个机制改了。

分片流程其实不复杂:

  1. 发送端检查IP包总长度是否超过出口MTU
  2. 如果超过,将数据部分拆成多个分片
  3. 每个分片复制原IP头部的Identification字段
  4. 设置MF位(More Fragments)和Fragment Offset
  5. 接收端根据Identification、源IP、目的IP识别属于同一原始包的分片
  6. 按Fragment Offset重组,MF=0表示最后一个分片

避坑指南:我曾经遇到过一个案例——某防火墙默认丢弃了所有分片包,导致大包传输失败。更坑的是,有些应用会设置DF位(Don't Fragment),如果路径MTU小于包大小,路由器会直接丢弃并返回ICMP错误。很多网络设备默认屏蔽了ICMP,结果就是连接超时,用户一脸懵。

分片在Wireshark里怎么看?抓包后找到IP层,看Identification字段是否相同。如果看到多个包有相同的Identification,且Fragment Offset递增,那就是分片了。

# Wireshark显示过滤表达式
ip.frag_offset > 0          # 显示所有分片包
ip.flags.mf == 1            # 显示MF位为1的包
ip.id == 0x1234             # 按标识符过滤特定分片组

IP路由原理:逐跳转发

路由说白了就是“问路”。每个路由器只知道下一跳怎么走,不知道完整路径。我刚开始学路由时,总觉得这效率太低,后来才明白——这种设计让互联网具备了极强的扩展性。

路由决策的核心步骤:

  • 最长前缀匹配:路由器查找路由表时,选择掩码最长的匹配条目
  • 默认路由:0.0.0.0/0,所有未匹配的流量走这里
  • 直连路由:接口配置了IP后自动生成
  • 静态路由:管理员手动配置
  • 动态路由:通过OSPF、BGP等协议学习

实战技巧:用Wireshark抓路由协议包时,我习惯先过滤ospf或bgp。OSPF用IP协议号89,BGP用TCP端口179。抓BGP时记得抓在建立邻居的阶段,能看到完整的Open、Update、Keepalive、Notification消息。

你想想看,一个数据包从北京发到纽约,中间经过几十个路由器,每个路由器只查一下路由表就转发出去。这种设计是不是很巧妙?

Wireshark过滤与分析实战

IPv4相关的Wireshark过滤,我总结了几个最常用的:

# 基础过滤
ip.addr == 192.168.1.1      # 匹配源或目的IP
ip.src == 10.0.0.1          # 匹配源IP
ip.dst == 172.16.0.1        # 匹配目的IP
ip.ttl < 10                 # TTL小于10的包
ip.proto == 6               # TCP协议
ip.proto == 17              # UDP协议
ip.flags.df == 1            # 设置了DF位的包
ip.hdr_len > 20             # 有IP选项的包

我个人习惯在分析网络问题时,先用ip.addr == x.x.x.x过滤出所有相关流量,然后逐步缩小范围。比如先看有没有分片,再看TTL是否异常。

案例分析:有一次客户反馈跨地域传输大文件经常中断。我抓包后发现大量ip.flags.df == 1且icmp.type == 3的包。嗯,典型的PMTUD问题——路径上有设备MTU小于1500,但发送端设置了DF位,导致包被丢弃。解决方案是在应用层调整MSS,或者在路由器上配置TCP MSS clamping。

IPv4头部结构图

下面这张图是我自己画的IPv4头部结构,方便你对照理解:

IPv4头部结构图 IPv4头部结构(20字节固定部分) Version 4 bit IHL 4 bit Type of Service 8 bit Total Length 16 bit Identification 16 bit Flags 3 bit Fragment Offset 13 bit Time to Live 8 bit Protocol 8 bit Header Checksum 16 bit Source Address 32 bit Destination Address 32 bit 说明: • 固定头部20字节,每行32 bit(4字节) • 如果有IP选项,IHL字段值大于5,头部长度超过20字节 • 分片相关字段:Identification + Flags + Fragment Offset 协同工作

常见问题与排障思路

最后分享几个我实际工作中遇到的IPv4相关坑:

  • TTL耗尽:traceroute就是利用TTL=1、2、3...逐跳探测路径。如果某个节点TTL设置过小,会导致包无法到达目的地
  • IP分片性能问题:分片和重组消耗CPU资源,现在的网络设备都尽量规避分片。我建议应用层直接控制数据包大小不超过1460字节(1500-20-20)
  • IP地址冲突:DHCP分配不当或手动配置错误会导致两个设备用同一个IP。Wireshark里看到大量ARP请求和重复IP通告就要警惕了

我的习惯:每次排查网络问题,第一件事就是抓包看IP层的TTL和Identification。TTL异常说明路径有问题,Identification重复说明可能是分片重组失败。这两个字段能快速定位80%的IP层问题。