以太网帧结构与MAC地址

大家好,欢迎来到第三章。今天咱们聊聊以太网帧和MAC地址。

说实话,搞网络分析这么多年,我见过太多人一上来就追着IP地址不放,反而把最基础的MAC地址和帧结构给忽略了。结果呢?出了问题死活查不出来,最后发现是帧格式对齐不对,或者MAC地址冲突。我个人习惯是,遇到网络故障,先从第二层看起——也就是数据链路层,看以太网帧是不是“长歪了”。

核心观点:以太网帧是数据链路层的“信封”,MAC地址是这个信封上的“收件人姓名和地址”。搞懂它俩,就等于拿到了网络分析的入场券。

以太网帧结构概览

好了,闲话少说。我们直接看帧结构。标准的Ethernet II帧(也叫DIX v2.0)长这样:

+----------------+----------+----------+----------+----------------+------+
|   前导码 (8B)   | 目的MAC  | 源MAC    | 类型/长度 |  数据载荷       | FCS  |
|                |  (6B)    |  (6B)    |   (2B)   |  (46-1500B)    | (4B) |
+----------------+----------+----------+----------+----------------+------+

注意:前导码在抓包文件里通常不显示,Wireshark会直接跳过它。很多新手第一次看到抓包结果时,会误以为前导码丢了——放心,它被网卡吃掉了。

为什么这么设计?说白了,每个字段都有它存在的意义。我们一个一个拆开讲。

前导码:帧的启航信号

前导码(Preamble)其实分成两部分:7字节的同步码和1字节的SFD(帧起始定界符)。同步码是10101010的循环,你可以理解为“大家注意了,我要开始传帧了”。SFD是10101011,告诉接收方“下一字节就是目的MAC了”。

我记得有一次帮客户排查千兆网络丢包问题,抓包看了半天,帧结构、IP校验和都没问题。最后无奈,拿示波器去量物理层信号——好家伙,前导码里的同步信号因为布线损耗被拉变形了。接收端网卡直接丢弃了这些帧。嗯,这种坑,不动硬件的人很难碰到。

目的/源MAC地址:网络上唯一的“身份证”

MAC地址是第二层的核心。它长48位,通常用十六进制表示,比如 00:1A:2B:3C:4D:5E。为了避免混淆,我建议大家用“三个一”来记:

  • 唯一性:全球唯一,由IEEE分配前24位(OUI,组织唯一标识符),后24位厂商自己定。
  • 固定性:通常是硬件烧录的,改起来麻烦。
  • 分层性:只在本局域网内有意义,跨网段要靠IP。

避坑指南:我曾经在数据中心遇到过一个奇葩问题。一台服务器的MAC地址变成了全是F的广播地址。你想想看,这不是等于告诉所有人“发给我的帧都广播出去”吗?整个二层网络瞬间瘫痪。最后发现是某厂商网卡驱动的一个BUG。

MAC地址的三种类型,一定要区分清楚:

类型 目的MAC特征 含义
单播 最低位为0 发给唯一目标
组播 最低位为1 发给一组设备
广播 全部为F(FF:FF:FF:FF:FF:FF) 发给所有设备

为什么会这样?因为网卡在收到帧时,会先看目的MAC是否与自己匹配,不匹配就直接丢弃。这大大减少了CPU负担。但广播不会被丢弃——所有网卡都会接收并处理它(然后判断是不是自己想要的协议)。

类型/长度字段:下层的“暗语”

这个字段的解读有一个约定:数值大于等于1536(0x0600)时,表示上层协议类型;小于等于1500时,表示帧的长度。比如:

  • 0x0800 表示封装的是IPv4报文
  • 0x0806 表示ARP报文
  • 0x86DD 表示IPv6报文

你想想看,要是没有这个字段,交换机收到一个帧后该交给谁处理?是交给IP协议栈,还是交给其他协议?这个小小的两字节,就是二层到三层的“交通警察”。

我建议你把常见的类型值背下来,排查故障时,一眼扫过去就知道上层是什么协议。Wireshark在Decode As...功能里,底层就是在帮你重设这个字段。

数据载荷与最小帧长

数据载荷部分,标准以太网帧要求最少46字节,最多1500字节(这叫MTU)。为什么要有下限?因为以太网有冲突检测机制(CSMA/CD),帧太短的话,发送方还没来得及检测到冲突就把帧发完了。所以,如果上层数据不够46字节,就填充到46。

实际抓包时,你会看到很多帧的实际载荷只有几十字节,但帧长显示都是60~64字节(加上14字节头部和4字节FCS,再加填充)。这不是浪费,而是协议在“保底”。

FCS校验:最后一公里

FCS(帧检验序列)是4字节的CRC-32校验和。它覆盖了目的MAC、源MAC、类型/长度、数据载荷这4个部分。接收端收到帧后,会重新计算CRC,如果对不上,就直接丢弃帧。

我曾经查过一次“间歇性掉线”问题。抓包发现大约每1000个帧就有1~2个CRC错误。后来发现是某根网线被机柜门夹住了,稍微一震就会产生误码。重启交换机、换网线都无法根治,最后把那根网线换了,世界就清净了。

注意:CRC错误不一定是物理层问题。如果FCS校验失败率忽高忽低,也可能是两端双工模式不匹配(一个全双工,一个半双工)。半双工那边会误以为发生了冲突,然后去重传——结果就会产生很多垃圾帧。

知识结构图:一看就懂

下面这张图,把这一节的核心关系串起来了。我个人习惯是把这种图印出来贴在工位上,遇到问题先扫一眼各个字段——基本上80%的故障都能定位到具体的字段上。

以太网帧结构与MAC地址知识体系 以太网帧(Ethernet II) 前导码(8字节) 目的MAC(6字节) 源MAC(6字节) 类型/长度(2字节) 数据载荷(46-1500字节) FCS校验(4字节) MAC地址(48位,6字节) 单播/组播/广播 ARP / 地址解析 冲突域 / 广播域 小提示 CRC错误 ≠ 一定是线缆问题 也可能是双工模式不匹配

总结:你真正需要记住的东西

这一章内容不少,但真正需要刻在脑子里的没几条:

  • 以太网帧由前导码、MAC头、载荷、FCS四部分组成。
  • MAC地址是二层的唯一标识,区分单播、组播、广播。
  • 类型/长度字段决定了上层协议。
  • FCS是最后的防线,不过它也不总能救你。
  • 最小帧长64字节(含头部和FCS)这个数字要记牢。

好了,这一章就讲到这里。去翻翻你自己的抓包文件,看看里面有没有CRC错误的帧,或者试试看能不能从源MAC的OUI推断出厂商。这些动手的过程,比死记硬背有用得多。