3. 以太网帧结构:MAC地址、前导码、帧校验序列(FCS),抓包实战分析

各位好,欢迎来到第三章。今天咱们聊聊以太网帧——说白了,就是数据在网线上跑的时候,到底长什么样。

我记得刚入行那会儿,总觉得网络数据是“嗖”一下飞过去的,神秘得很。后来抓了包一看,嗯,其实每一帧都像一封信,有信封、有内容、还有签名。今天我就带你把信封拆开,看看里面到底写了啥。

3.1 以太网帧的“信封”长什么样?

先看一张总图,让你对帧结构有个整体印象。

以太网帧结构(IEEE 802.3) 前导码 7字节 SFD 1B 目的MAC 6字节 源MAC 6字节 类型/长度 2字节 数据(Payload) 46~1500字节 FCS 4字节 关键说明: • 前导码 + SFD:物理层同步信号,抓包时通常不显示 • MAC地址:6字节,全球唯一,前3字节是OUI(厂商代码) • 类型/长度:>1536表示上层协议类型(如0x0800=IP),≤1500表示数据长度 • FCS:CRC32校验,覆盖目的MAC到数据末尾 • 帧间隙(IFG):帧与帧之间至少12字节的空闲时间

这张图我建议你保存下来。每次抓包分析的时候,对照着看,思路会清晰很多。

3.2 前导码与SFD——物理层的“预备,起!”

前导码(Preamble)是7个字节的固定模式:10101010重复7次。它的作用很简单——让接收端的时钟同步起来。

你想想看,网线上信号是连续的电平变化,接收端得知道“什么时候开始读”。前导码就是那个“预备”信号。紧接着是SFD(帧起始定界符),1个字节的10101011,最后两位是11,告诉接收端:“准备好了,下一字节就是MAC地址了!”

抓包小技巧: Wireshark默认不显示前导码和SFD。因为它们是物理层的东西,网卡在接收时已经剥离了。如果你想看,得用专业的硬件抓包工具,比如Endace DAG卡。我个人习惯在分析物理层问题时才关注这个,平时直接看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帧。

注意: 如果类型/长度字段的值在1501~1535之间,这是无效值。我曾经在抓包时见过一个网卡驱动bug,发出来的帧这个字段是0x0601,导致交换机直接丢弃。排查了整整两天才找到原因。

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错误,先检查网线、网卡、交换机端口。别急着怀疑协议栈。
  • 前导码丢失: 用软件抓包看不到前导码,别慌。这是正常的,物理层已经处理了。