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,抓一个实际的以太网帧看看。
操作步骤:
- 启动Wireshark,选择你的网卡接口。
- 在过滤栏输入
icmp,然后ping一个地址(比如ping 8.8.8.8)。 - 找到对应的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数据包,一目了然。
3.7 常见问题与排查思路
在实际工作中,跟以太网帧相关的问题,我总结了几类:
- FCS错误持续增长:先查物理层——网线、光模块、接口是否松动。如果物理层没问题,再查网卡驱动或硬件故障。
- MAC地址冲突:同一广播域内出现两个相同MAC地址,会导致交换机MAC表震荡,丢包严重。用
arp -a或Wireshark过滤arp.duplicate-address-detected可以定位。 - 帧长度异常:小于64字节的帧叫“短帧”(Runt),大于1518字节的叫“超大帧”(Jabber)。这两种通常都是硬件或驱动问题。
个人经验:我曾经在数据中心排查过一个“间歇性丢包”的故障,抓了三天包,最后发现是一台交换机的某个端口光模块老化,偶尔发出CRC错误的帧。交换机丢弃了这些帧,但上层应用感知到的是TCP重传。所以,遇到TCP重传率高的场景,别忘了看看二层的FCS统计。
好了,以太网帧的结构和验证方法就聊到这儿。你可以在自己的环境里抓几个包看看,对照着本文的表格和SVG图,把每个字段都找到。动手试一次,比看十遍书都管用。