3. 以太网帧结构:MAC地址、前导码、帧校验序列(FCS),抓包实战分析
各位好,欢迎来到第三章。今天咱们聊聊以太网帧——说白了,就是数据在网线上跑的时候,到底长什么样。
我记得刚入行那会儿,总觉得网络数据是“嗖”一下飞过去的,神秘得很。后来抓了包一看,嗯,其实每一帧都像一封信,有信封、有内容、还有签名。今天我就带你把信封拆开,看看里面到底写了啥。
3.1 以太网帧的“信封”长什么样?
先看一张总图,让你对帧结构有个整体印象。
这张图我建议你保存下来。每次抓包分析的时候,对照着看,思路会清晰很多。
3.2 前导码与SFD——物理层的“预备,起!”
前导码(Preamble)是7个字节的固定模式:10101010重复7次。它的作用很简单——让接收端的时钟同步起来。
你想想看,网线上信号是连续的电平变化,接收端得知道“什么时候开始读”。前导码就是那个“预备”信号。紧接着是SFD(帧起始定界符),1个字节的10101011,最后两位是11,告诉接收端:“准备好了,下一字节就是MAC地址了!”
3.3 MAC地址——网络设备的“身份证”
MAC地址是6字节(48位),通常写成XX:XX:XX:XX:XX:XX的格式。前3字节是OUI(组织唯一标识符),由IEEE分配,代表厂商。后3字节是厂商自己分配的序列号。
举个例子:00:0c:29:1a:2b:3c,前3字节00:0c:29是VMware的OUI。我在项目中遇到过好几次,看到这个OUI就知道是虚拟机在通信,排查虚拟化网络问题时特别有用。
MAC地址有几个特殊类型,我整理了一张表:
| 类型 | 第1字节最低位 | 示例 | 说明 |
|---|---|---|---|
| 单播 | 0 | 00:0c:29:1a:2b:3c | 发往单个设备 |
| 多播 | 1 | 01:00:5e:00:00:01 | 发往一组设备(如IGMP) |
| 广播 | 全1 | ff:ff:ff:ff:ff:ff | 发往所有设备(ARP请求) |
这里有个坑——我曾经调试一个网络不通的问题,抓包发现目的MAC是ff:ff:ff:ff:ff:ff,但交换机没转发。后来发现是端口配置了“广播风暴控制”,把广播帧丢了。嗯,MAC地址虽然简单,但实际环境里坑不少。
3.4 类型/长度字段——二义性的由来
这个字段很有意思。IEEE 802.3标准里,它既可以表示上层协议类型,也可以表示数据字段的长度。
- 值 > 1536(0x0600): 表示类型。比如0x0800是IPv4,0x0806是ARP,0x86DD是IPv6。
- 值 ≤ 1500(0x05DC): 表示数据字段的长度。这是IEEE 802.3原始格式。
为什么会有这种二义性?说白了就是历史原因。以太网V2标准用类型字段,IEEE后来想统一,搞了个长度字段。但大家已经习惯了用类型,所以实际网络中几乎全是“类型”用法。你抓包看到的,99%都是Ethernet II帧。
3.5 数据字段——最小46字节的玄机
数据字段的范围是46~1500字节。为什么最小是46?因为CSMA/CD协议要求帧长至少64字节(从目的MAC到FCS末尾)。减去14字节的头部和4字节的FCS,数据最少得46字节。
如果上层数据不够46字节怎么办?填充(Padding)。网卡会自动在后面补0,直到凑够46字节。抓包时你会看到Wireshark标记为[Padding]。
最大1500字节是MTU(最大传输单元)。超过1500的数据,IP层会分片。这个咱们后面讲IP协议时会详细说。
3.6 FCS——帧校验序列,数据的“指纹”
FCS是4字节的CRC32校验值。它覆盖从目的MAC到数据末尾的所有字节。发送端算一遍,接收端算一遍,如果对不上,说明帧在传输过程中损坏了,直接丢弃。
CRC32的算法是多项式除法,具体数学我就不展开了。你只需要知道:FCS能检测出所有1位、2位错误,以及奇数位错误,还能检测出长度≤32的突发错误。可靠性很高。
我在项目中遇到过一个问题:某台服务器的网卡频繁丢包,抓包发现FCS校验失败。换网卡、换线都没用,最后发现是机柜的接地不良,导致信号干扰。嗯,物理层的问题有时候真的很隐蔽。
3.7 抓包实战——用Wireshark看以太网帧
光说不练假把式。咱们打开Wireshark,抓一个实际的HTTP请求,看看以太网帧长什么样。
假设你访问http://example.com,抓包后找到对应的帧,展开Ethernet II部分:
Frame 1: 74 bytes on wire (592 bits), 74 bytes captured (592 bits)
Ethernet II, Src: VMware_1a:2b:3c (00:0c:29:1a:2b:3c), Dst: Router_ab:cd:ef (00:1a:2b:3c:4d:5e)
Destination: Router_ab:cd:ef (00:1a:2b:3c:4d:5e)
Source: VMware_1a:2b:3c (00:0c:29:1a:2b:3c)
Type: IPv4 (0x0800)
[Frame check sequence: 0x12345678 [unverified]]
[FCS Status: Unverified]
看到没?Wireshark直接显示了源MAC、目的MAC和类型。FCS默认不校验,因为软件抓包时网卡已经校验过了。如果你想看FCS值,可以在Wireshark的偏好设置里开启“Validate the Ethernet checksum if possible”。
- 源MAC和目的MAC:确认通信双方的身份。如果目的MAC是广播地址,说明是ARP或DHCP请求。
- 类型字段:0x0800是IPv4,0x0806是ARP。看到ARP帧时,注意观察请求的是谁的IP。
- 帧长度:74字节(14字节头部 + 60字节数据)。数据部分包含了IP头部、TCP头部和HTTP请求。
3.8 常见问题与避坑指南
最后,分享几个我踩过的坑:
- MAC地址冲突: 两台设备MAC地址相同,交换机会混乱。我曾经在测试环境里手动改了MAC地址,忘了改回来,结果整个办公室的网络都受影响。
- 巨型帧(Jumbo Frame): 有些交换机支持超过1500字节的帧,但默认是关闭的。如果你改了MTU,记得两端都要配,否则帧会被丢弃。
- FCS错误: 如果抓包时看到大量FCS错误,先检查网线、网卡、交换机端口。别急着怀疑协议栈。
- 前导码丢失: 用软件抓包看不到前导码,别慌。这是正常的,物理层已经处理了。