4. IP协议基础:IPv4头部结构、分片与重组、TTL分析、IP选项字段

IP协议是整个TCP/IP栈的“腰杆子”。你想想看,没有IP,数据包连去哪都不知道。这一章我们就把IPv4的底裤扒干净——头部每个字节干什么用、包太大怎么切、TTL怎么防环路、还有那些几乎没人用的选项字段。

本章核心:抓包时你看到的每一个IP头部字段,背后都有故事。理解它们,你才能读懂Wireshark里那些“奇怪”的现象。

4.1 IPv4头部结构——20字节的“身份证”

IPv4头部标准长度是20字节,不含选项。我刚开始学的时候觉得这20字节好复杂,后来抓包抓多了,闭着眼都能背出来。

先看一张完整的头部结构图:

IPv4头部结构(20字节标准) 版本(4bit) 首部长度(4bit) 服务类型(ToS) 8bit 总长度 16bit 标识 16bit 标志 3bit 片偏移 13bit TTL 8bit 协议 8bit 首部校验和 16bit 源IP地址 32bit 目的IP地址 32bit 选项(可选,可变长度) 关键字段速记 • 版本:IPv4固定为4 • 首部长度:单位4字节 • 总长度:包含头部+数据 • 标识+标志+片偏移:分片三件套 抓包重点关注 • TTL:看跳数,判断距离 • 协议:6=TCP, 17=UDP • 校验和:路由器会重新计算

每个字段我都给你拆开讲:

字段长度作用抓包时怎么看
版本4bitIPv4固定为4Wireshark直接显示"Version: 4"
首部长度4bit单位4字节,最小5(20B),最大15(60B)看"Header Length"字段
服务类型(ToS)8bitQoS标记,现在多用DSCP大部分场景为0
总长度16bitIP包总字节数,最大65535减去头部长度=数据长度
标识16bit分片时同一组包的ID分片包标识相同
标志3bitDF(不分片)、MF(更多分片)DF=1时路由器不能分片
片偏移13bit分片在原始包中的位置单位8字节
TTL8bit最大跳数,防环路每经过一个路由器减1
协议8bit上层协议类型6=TCP, 17=UDP, 1=ICMP
首部校验和16bit只校验头部路由器会重新计算
源/目的IP各32bitIPv4地址抓包最直观的字段

我的习惯:抓包时先看"总长度"和"首部长度"。如果总长度远大于MTU(1500),那这个包大概率被分片了。另外,首部长度如果大于5,说明有选项字段——这种情况现在很少见了。

4.2 分片与重组——包太大?切了再说

以太网MTU是1500字节。如果IP包超过这个值,路由器就得把它切开。我遇到过最头疼的问题就是分片导致的性能故障——有些防火墙会丢弃分片包,导致大文件传输卡死。

分片的核心逻辑就三个字段:标识(Identification)、标志(Flags)、片偏移(Fragment Offset)。

看一个分片流程:

IP分片与重组流程 原始IP包(4000字节) IP头部20B + 数据3980B 分片1:偏移0,MF=1 头部20B + 数据1480B 分片2:偏移185,MF=1 头部20B + 数据1480B 分片3:偏移370,MF=0 头部20B + 数据1020B 分片计算规则 MTU=1500,IP头部20B 每片最大数据=1480B 片偏移单位=8字节 偏移值=数据起始位置/8 分片1:偏移0 分片2:偏移1480/8=185 分片3:偏移2960/8=370 MF=0表示最后一个分片

分片的关键点:

  • DF标志=1:路由器不能分片,包太大直接丢弃,返回ICMP错误。我遇到过VPN隧道MTU问题,就是DF=1导致的。
  • MF标志=1:后面还有分片。MF=0表示这是最后一个分片。
  • 片偏移:单位是8字节。比如偏移185,表示数据从1480字节开始。

我曾经踩过的坑:有一次客户说文件上传到某台服务器总是卡在99%。抓包一看,所有大包都设置了DF=1,中间有个链路的MTU只有1400。服务器返回ICMP"需要分片但DF已设置"的报文,但客户防火墙把ICMP给过滤了。结果就是——TCP永远无法完成三次握手之外的数据传输。解决方案:要么改MTU,要么放行ICMP。

重组是在接收端完成的。接收端根据标识字段把属于同一组的分片找出来,再按片偏移排序拼接。如果某个分片丢了,整个包都重组失败——TCP会重传整个数据段,而不是只重传丢失的分片。

4.3 TTL分析——你的包能走多远?

TTL(Time To Live)虽然名字叫"生存时间",但实际是最大跳数。每经过一个路由器,TTL减1。减到0时,路由器丢弃这个包,并给源IP发一个ICMP超时报文。

默认值因操作系统而异:

操作系统默认TTL说明
Linux64大多数发行版
Windows128Win7/10/11都是128
macOS/iOS64和Linux一样
Android64基于Linux内核
Cisco路由器255设备间通信常用

抓包时看TTL能判断什么?

  • 判断源端系统:TTL=128大概率是Windows,TTL=64大概率是Linux/macOS。
  • 估算跳数:比如抓到TTL=56,初始64,说明经过了8跳。
  • 检测环路:如果TTL在多个包中持续递减到0,说明有路由环路。

我常用的traceroute原理:就是利用TTL。先发TTL=1的包,第一个路由器返回ICMP超时;再发TTL=2,第二个路由器返回...以此类推,就能画出整条路径。Windows的tracert用ICMP,Linux的traceroute默认用UDP。

看一个Wireshark抓包示例:

# 抓包过滤:icmp
# 一个ping包的IP头部
Internet Protocol Version 4, Src: 192.168.1.100, Dst: 8.8.8.8
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 60
    Identification: 0x1a2b (6699)
    Flags: 0x40, Don't fragment
    Fragment Offset: 0
    Time to Live: 64          ← 初始值64,Linux系统
    Protocol: ICMP (1)
    Header Checksum: 0x3c4d [validation disabled]
    Source Address: 192.168.1.100
    Destination Address: 8.8.8.8

注意看Flags字段显示"Don't fragment"——很多现代系统默认设置DF=1,因为分片会降低性能。

4.4 IP选项字段——几乎没人用的“古董”

IP选项字段让头部长度从20字节扩展到最多60字节。但说实话,我在生产环境几乎没见过。为什么?因为大多数路由器和防火墙会直接丢弃带选项的包——安全风险太高。

常见的IP选项:

选项类型编号作用现状
NOP(无操作)1填充对齐偶尔见到
EOOL(选项结束)0标记选项结束偶尔见到
记录路由7记录经过的路由器IP几乎不用,空间有限
时间戳68记录每跳时间几乎不用
严格源路由137强制指定路径安全风险,被禁用
松散源路由131指定部分路径安全风险,被禁用

安全提醒:源路由选项(严格/松散)曾经被黑客用来绕过防火墙。攻击者可以伪造路径,让流量绕过安全设备。现在几乎所有网络设备都默认丢弃带源路由选项的包。如果你在抓包中看到这些选项,大概率是有人在搞事情。

我个人建议:抓包时如果看到IP头部长度大于20字节,先警惕一下。用Wireshark的"Expert Info"功能看看有没有异常标记。正常流量中,IP选项几乎绝迹。

4.5 实战:用Wireshark分析IP头部

打开Wireshark,抓一个ping包,看看IP头部:

  1. 过滤条件输入 icmp 或 ip.addr == 你的目标IP
  2. 展开"Internet Protocol Version 4"那一行
  3. 观察每个字段的值
  4. 重点关注:TTL、标识、标志、总长度

试试这个实验:

  • ping一个本地地址,看TTL是多少
  • ping一个远程地址(比如8.8.8.8),看TTL减少了多少
  • 用 ping -f -l 2000 目标IP(Windows)强制发送大包且设置DF=1,看会不会收到ICMP错误

总结一下:IPv4头部就20字节,但每个字节都有意义。分片靠标识+标志+偏移三件套,TTL帮你判断距离和系统类型,选项字段基本是历史遗迹。抓包时多看看这些字段,你能发现很多网络问题的根因。