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

聊完IP和TCP之前,咱们得先把地基打牢——以太网帧。你想想看,数据在网线上跑的时候,总得有个“信封”把它包起来吧?这个信封就是以太网帧。我刚开始学网络的时候,总觉得这层太底层、太枯燥,直到有一次排查一个丢包问题,折腾了两天,最后发现是FCS校验失败导致的。嗯,从那以后我再也不敢小看这层了。

3.1 以太网帧长什么样?

说白了,以太网帧就是数据链路层的协议数据单元。它负责把网络层的IP数据包封装起来,加上头部和尾部,然后扔到物理介质上传输。目前最常用的是Ethernet II(也叫DIX 2.0)帧格式,IEEE 802.3也有,但咱们抓包看到的绝大多数都是Ethernet II。

一个完整的以太网帧,结构如下:

字段 长度(字节) 说明
前导码(Preamble) 7 同步时钟,101010...交替
帧起始定界符(SFD) 1 10101011,标识帧开始
目的MAC地址 6 接收方硬件地址
源MAC地址 6 发送方硬件地址
类型/长度(Type/Length) 2 Ethernet II用类型,IEEE 802.3用长度
数据载荷(Payload) 46~1500 上层协议数据,如IP包
帧校验序列(FCS) 4 CRC32校验,检错用

关键点:前导码和SFD在Wireshark抓包时是看不到的——它们属于物理层的东西,网卡在接收时会剥离掉。你看到的帧是从目的MAC地址开始的。

3.2 MAC地址:设备的“身份证”

MAC地址,全称Media Access Control Address,是网络接口卡(NIC)出厂时烧录的硬件地址。它长48位,通常写成6组十六进制数,比如 00:1A:2B:3C:4D:5E。

我个人习惯把MAC地址分成两部分看:

  • 前24位(OUI):组织唯一标识符,由IEEE分配给厂商。比如 00:1A:2B 可能是某家公司的。
  • 后24位:由厂商自行分配,保证同一厂商下的网卡不重复。

这里有个坑,我曾经踩过——MAC地址的第七位(从左数第一个字节的最低位)是广播/多播标志位。如果这一位是0,表示单播;是1,表示多播。而全1的MAC地址 FF:FF:FF:FF:FF:FF 就是广播地址,所有网卡都会接收。

注意:MAC地址是二层地址,只在同一个广播域内有效。跨路由器通信时,源和目的MAC地址每经过一跳都会改变,但IP地址不变。这个区别很多人一开始会搞混。

3.3 前导码与帧同步

前导码这玩意儿,说实话,在Wireshark里是看不见的。但它确实存在。为什么需要它?因为网卡和网卡之间没有独立的时钟线,它们得靠数据信号本身来同步。

前导码是7个字节的 10101010 交替模式,接收端网卡通过检测这个模式来锁定时钟频率。紧接着是1字节的SFD 10101011,最后两位的 11 告诉接收端:“注意,真正的帧数据要来了!”

我记得有一次在实验室里用示波器看以太网信号,前导码的波形特别规整,像心跳一样。嗯,这大概就是数字通信的“呼吸”吧。

3.4 帧校验序列(FCS)——数据的“防伪标签”

FCS是帧的最后一个字段,4字节,用CRC32算法计算。发送方把目的MAC、源MAC、类型、数据载荷全部算一遍,得到一个32位的校验值,附在帧尾。接收方收到后,用同样的算法再算一遍,如果结果不一致,说明帧在传输过程中被损坏了,直接丢弃。

你可能会问:那上层协议(比如TCP)也有校验啊,为什么二层还要做?

原因很简单——尽早丢弃坏帧,避免无效数据往上传递浪费资源。而且CRC32的检错能力很强,能检测出单比特错误、双比特错误、奇数个错误甚至突发错误。

避坑指南:我曾经遇到过一个问题——交换机端口频繁报CRC错误,但网线测试仪测出来是通的。后来发现是网线过长(超过100米),信号衰减导致误码。换了一根短网线,问题解决。所以,FCS错误不一定是网卡坏了,先查物理层。

3.5 Wireshark抓包验证

光说不练假把式。咱们打开Wireshark,抓一个实际的以太网帧看看。

操作步骤:

  1. 启动Wireshark,选择你的网卡接口。
  2. 在过滤栏输入 icmp,然后ping一个地址(比如 ping 8.8.8.8)。
  3. 找到对应的ICMP请求包,双击展开。

你会看到类似这样的结构:

Frame 1: 74 bytes on wire (592 bits), 74 bytes captured (592 bits)
Ethernet II, Src: 00:1a:2b:3c:4d:5e, Dst: 08:00:27:ab:cd:ef
    Destination: 08:00:27:ab:cd:ef (08:00:27:ab:cd:ef)
    Source: 00:1a:2b:3c:4d:5e (00:1a:2b:3c:4d:5e)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 192.168.1.100, Dst: 8.8.8.8
Internet Control Message Protocol

注意看:

  • Ethernet II 这一行就是二层帧头。
  • Source/Destination 就是MAC地址。
  • Type: 0x0800 表示上层是IPv4协议。如果是0x0806,那就是ARP。
  • Wireshark默认不显示FCS,因为网卡在接收时已经剥离了。但你可以通过设置让Wireshark保留它(Edit → Preferences → Protocols → Ethernet → 勾选 "Assume packets have FCS")。

验证技巧:你可以用 eth.addr == 00:1a:2b:3c:4d:5e 过滤特定MAC地址的流量。这在排查某台设备是否在发送异常帧时特别有用。

3.6 以太网帧结构全景图

下面这张图把整个以太网帧的封装关系画出来了,从物理层的前导码到上层的IP数据包,一目了然。

以太网帧结构全景图 前导码 7字节 SFD 1字节 目的MAC 6字节 源MAC 6字节 类型 2字节 数据载荷(IP包) 46~1500字节 FCS 4字节 Wireshark抓包可见部分(从目的MAC到数据载荷) 前导码和SFD由网卡处理,FCS默认被剥离,需手动开启显示 物理层(不可见) 数据链路层头部 上层数据 尾部

3.7 常见问题与排查思路

在实际工作中,跟以太网帧相关的问题,我总结了几类:

  • FCS错误持续增长:先查物理层——网线、光模块、接口是否松动。如果物理层没问题,再查网卡驱动或硬件故障。
  • MAC地址冲突:同一广播域内出现两个相同MAC地址,会导致交换机MAC表震荡,丢包严重。用 arp -a 或Wireshark过滤 arp.duplicate-address-detected 可以定位。
  • 帧长度异常:小于64字节的帧叫“短帧”(Runt),大于1518字节的叫“超大帧”(Jabber)。这两种通常都是硬件或驱动问题。

个人经验:我曾经在数据中心排查过一个“间歇性丢包”的故障,抓了三天包,最后发现是一台交换机的某个端口光模块老化,偶尔发出CRC错误的帧。交换机丢弃了这些帧,但上层应用感知到的是TCP重传。所以,遇到TCP重传率高的场景,别忘了看看二层的FCS统计。

好了,以太网帧的结构和验证方法就聊到这儿。你可以在自己的环境里抓几个包看看,对照着本文的表格和SVG图,把每个字段都找到。动手试一次,比看十遍书都管用。