主菜开席。本节解剖最外两层:以太网帧头(报文的"信封")、ARP(把 IP 翻译成 MAC 的"查号台")、IPv4 头("邮路单")。走法是固定的:先上十六进制原文,再对照解析结果逐字节读。这套读法练熟了,任意一帧拿到手都不慌。后两节在同一读法下深入传输层与应用层。
取一枚真实帧的前 14 字节:
aa bb cc dd ee ff 88 c9 d0 11 22 33 08 00 └──── 目的 MAC ────┘ └──── 来源 MAC ────┘ └类型┘
对照解析结果验证手工阅读:
$ tshark -r lan.pcapng -c 1 -T fields -e eth.dst -e eth.src -e eth.type aa:bb:cc:dd:ee:ff 88:c9:d0:11:22:33 0x0000800 $ tshark -r lan.pcapng -c 1 -V | sed -n '/Ethernet/,/^Internet/p' | head -6 Ethernet II, Src: 88:c9:d0:11:22:33, Dst: aa:bb:cc:dd:ee:ff Destination: aa:bb:cc:dd:ee:ff Source: 88:c9:d0:11:22:33 Type: IPv4 (0x0800)
三个字段各自是行话:目的 MAC 排在最前是硬件设计的遗产(交换机读到前 6 字节就能开始查转发表);类型字段是 3.3 节讲的分派钩子之一,0x0800 指向 IPv4,0x0806 指向 ARP,0x86DD 指向 IPv6。常见的类型值值得记三个:0800、0806、8100——最后一个是 VLAN。
**VLAN 现场勘查。**类型字段出现 0x8100 时,真正的类型被推后 4 字节,这 4 字节是 VLAN 标签:
aa bb cc dd ee ff 88 c9 d0 11 22 33 81 00 0f a2 08 00 └──── 目的 MAC ───┘└──── 来源 MAC ───┘└VLAN┘└标签┘└类型┘ │ └── 优先级3位 + 丢弃指示1位 + VLAN号12位 └────── 0x8100 本身 0x0fa2 = 0000 1111 1010 0010 → VLAN 号 = 0xfa2 & 0xfff = 4002
$ tshark -r vlan.pcapng -c 1 -T fields -e vlan.id -e eth.type 4002 0x0000800
多租户机房里"抓到的帧比预期少一半",十有八九是镜像口没带 VLAN 标签或网卡驱动剥了标签——能在字节里认出 8100,就不会被这种现场迷惑。
IP 要封装成帧时需要目的 MAC,ARP 负责广播喊话"谁是的告诉":
$ tshark -r arp.pcapng -V | sed -n '/Address Resolution/,/^$/p' | head -12 Address Resolution Protocol (request) Hardware type: Ethernet (1) Protocol type: IPv4 (0x0800) Hardware size: 6 Protocol size: 4 Opcode: request (1) Sender MAC address: 88:c9:d0:11:22:33 Sender IP address: 192.168.31.14 Target MAC address: 00:00:00:00:00:00 Target IP address: 192.168.31.1
九个字段读出一场完整喊话:硬件类型以太网、上层是 IPv4、MAC 长 6 字节、IP 长 4 字节、这是请求(操作码 1,应答是 2)、发送方自报家门、目标 MAC 填全零(因为还不知道)。应答帧则是单播回给请求者,操作码 2,目标字段补全。
勘验要点有二。其一,ARP 没有认证,任何主机都可以应答——ARP 欺骗(伪造应答把流量引向自己)在小型网络里仍然常见,特征是同一 IP 在短时间内出现多个不同 MAC 的应答。Wireshark 里 arp.duplicate-address-detected 这类专家标记会直接喊出来。其二,免费 ARP(gratuitous ARP)是"自问自答":主机上线时广播自己的 IP 与 MAC,用于探测地址冲突。抓到一串免费 ARP,往往意味着有机器在频繁重启或换地址。
上主菜——IPv4 头逐字节精读。先看原文与字段对照:

用真实帧验证两处读法。TTL 与协议:
$ tshark -r lan.pcapng -Y "ip.src==192.168.31.14" -c 3 -T fields \ -e ip.ttl -e ip.proto -e ip.len -e ip.flags.df 64 17 90 0 64 6 60 1 64 6 1500 1
三条记录三个信息:TTL 64 且未过路由(本地通信);第二、三行 DF=1——现代系统默认禁止分片,靠路径 MTU 发现机制避免切割;总长度 1500 正好是常见最大传输单元,说明这是满载帧。
**分片现场勘查。**当 DF=0 且载荷超过路径 MTU 时,路由器会切割。现场特征是"同标识、偏移递增、最后一帧 MF=0":
$ tshark -r frag.pcapng -Y "ip.flags.mf==1 || ip.frag_offset>0" -T fields \ -e ip.id -e ip.flags.mf -e ip.frag_offset -e ip.len 0x1a2b 1 0 1500 0x1a2b 0 185 516
两帧同标识 0x1a2b:第一帧 MF=1、偏移 0、长 1500(含 20 头即 1480 载荷);第二帧 MF=0、偏移 185(乘 8 等于 1480 字节处)、长 516。Wireshark 会自动重组并在列表显示重组后的完整报文(帧注释注明"重组自 N 帧")。看到大量分片,通常指向路径 MTU 配置不一致——隧道叠加是最常见肇因。
脱离工具辅助,把一帧"完全陌生"的流量按本节方法手工读一遍(十六进制节选):
ff ff ff ff ff ff 00 1a 2b 3c 4d 5e 08 06 00 01 08 00 06 04 00 01 00 1a 2b 3c 4d 5e c0 a8 1f 0e 00 00 00 00 00 00 c0 a8 1f 01
逐段解读:目的 MAC 全 1 广播(交换机要泛洪的信号);源 MAC 00:1a:2b:3c:4d:5e;类型 0806——ARP 案宗。ARP 头接着读:硬件类型 1(以太网)、协议类型 0800(IPv4)、硬件长 6、协议长 4、操作码 01(请求)、发送方 MAC 与 IP(c0a81f0e = 192.168.31.14)、目标 MAC 全零、目标 IP c0a81f01 = 192.168.31.1——一台主机在广播问网关的 MAC 地址。对照解析器验证:
$ tshark -r arp.pcapng -c 1 1 0.000000 Broadcast ARP 60 Who has 192.168.31.1? Tell 192.168.31.14
手工读出的每个字节都与解析结论吻合。这个演练的价值不在"替代工具",而在建立字节与字段的直觉——当解析器失灵(私有协议、损坏文件)时,这份直觉就是你唯一的解剖刀。练法也简单:每天任选一帧,遮住解析结果先手工读,再对答案(7.3 节的练习循环正是这么运转的)。
外两层拆完,下一节进入传输层——TCP 连接从第一声敲门到最后一次挥手的完整一生。