Files
2026-05-27 00:12:00 +08:00

11 KiB
Raw Permalink Blame History

tags, create time
tags create time
计算机网络
Ethernet
MAC
帧结构
数据链路层
2026-05-17 22:50

Ethernet 帧结构

概述

Ethernet(以太网)是目前最主流的局域网技术。最初由 Robert Metcalfe 在 Xerox PARC 于 1973 年发明,1980 年由 Xerox、DEC、Intel 联合发布 DIX 标准,1983 年 IEEE 正式发布 802.3 标准。

理解 Ethernet 帧结构是掌握网络底层通信的基础——每一帧都包含了足够的信息来让网卡判断"这是给我的吗?内容完整吗?上层协议是什么?"

物理层封装:前导码与帧间隔

在以太网帧到达网线之前,物理层(PHY)会自动加上 前导码 (Preamble) 和 帧首定界符 (SFD),这部分对软件不可见,但理解它有助于理解"帧"与"包"的边界。

|<---------- Preamble + SFD (8B) -------->|<------------- Ethernet Frame ------------>|
┌───────────────────────┬────────┬─────────┬──────────┬──────────┬──────────┬─────────┐
│  Preamble (7 bytes)   │ SFD(1B)│Dest MAC │ Src MAC  │ EtherType│ Payload  │   FCS   │
│  10101010 × 7         │10101011│ 6 bytes │ 6 bytes  │ 2 bytes  │ 46-1500B │ 4 bytes │
└───────────────────────┴────────┴─────────┴──────────┴──────────┴──────────┴─────────┘
                                                                ↑ 14B Header
  • Preamble: 7 字节的 10101010 交替模式,用于接收方的时钟同步(位同步)
  • SFD (Start Frame Delimiter): 10101011,最后两个连续 1 表示"帧数据从下一个字节开始"
  • IFG (Inter-Frame Gap): 帧与帧之间至少间隔 12 字节(96 bit time),让网卡有时间处理上一帧

[!question] 为什么前导码是 7 字节而不是 8 字节? 前 7 字节用于时钟同步,SFD 单独标记帧起始。接收方需要足够的跳变沿来锁定频率,7 字节 × 8 bit = 56 次跳变,在早期的 10Mbps 以太网中大约需要 5.6μs 完成同步。

Ethernet II 帧格式(最常见)

┌──────────┬──────────┬──────────┬─────────────┬──────────┐
│ Dest MAC │ Src MAC  │ EtherType│   Payload   │   FCS    │
│  6 bytes │  6 bytes │ 2 bytes  │  46–1500 B  │ 4 bytes  │
│ aabb.ccdd│ dd.eeff. │  0x0800  │  IP Packet  │ crc32()  │
│  ee.ff.00│          │          │             │          │
└──────────┴──────────┴──────────┴─────────────┴──────────┘
         ←──────── 14 bytes Header ───────→  ← Tail →
                              ←──── Min Frame = 64B ────→
                              ←──── Max Frame = 1518B ────→

字段详解

字段 大小 说明
Dest MAC 6 bytes 目标 MAC 地址,ff:ff:ff:ff:ff:ff 表示广播
Src MAC 6 bytes 源 MAC 地址,发出方的物理地址
EtherType 2 bytes 上一层协议类型:0x0800=IPv4, 0x86DD=IPv6, 0x0806=ARP
Payload 46–1500 bytes 承载的上层数据包。最小 46 字节,不足则填充(Padding)
FCS 4 bytes CRC-32 校验和,网卡硬件自动计算,接收端验证错误则直接丢弃

为什么 Payload 最小 46 字节?

最早的以太网最大电缆长度 2500m,信号传播延迟需要至少 64 字节才能保证碰撞检测(CSMA/CD)生效。所以规定整个帧最小 64 字节,减去 14 字节头部和 4 字节 FCS,Payload 最少 46 字节。短包会补零填满。

现代 Gigabit+ 网卡已不用 CSMA/CD,但为了兼容仍保留此限制。

IEEE 802.1Q(VLAN Tagged)帧

当网络中使用 VLAN 时,帧中会插入一个 4 字节的 802.1Q Tag。注意:TPID 占据了原本 EtherType 的位置,真正的 EtherType 跟在 TCI 之后:

┌──────────┬──────────┬─────────────┬──────────┬──────────┬─────────────┬──────────┐
│ Dest MAC │ Src MAC  │ TPID (0x8100)│   TCI    │ EtherType│   Payload   │   FCS    │
│  6 bytes │  6 bytes │   2 bytes   │ 2 bytes  │ 2 bytes  │  42–1500 B  │ 4 bytes  │
│          │          │             │ PCP DEI  │  0x0800  │             │          │
│          │          │             │ 3b  1b   │          │             │          │
│          │          │             │ VID(12b) │          │             │          │
└──────────┴──────────┴─────────────┴──────────┴──────────┴─────────────┴──────────┘
                         ←──────── 4B 802.1Q Tag ────────→

新增字段:

  • TPID (Tag Protocol Identifier): 0x8100 — 占据 EtherType 的位置,标识"这不是普通协议类型,而是 VLAN Tag"
  • TCI (Tag Control Information): 包含 PCP(优先级,3 bit)、DEI(丢弃适格指示符,1 bit)、VID(VLAN ID,12 bit)

[!note] CFI → DEI 早期标准中该位叫 CFI (Canonical Format Indicator),用于标记 MAC 地址是否为规范格式。802.1Q-2011 修订后改为 DEI (Drop Eligible Indicator),用于标识在网络拥塞时可优先丢弃的帧。

VID 取值范围 0–4095,其中 VID 0 用于表示优先级帧(不含 VLAN 信息),VID 4095 为保留值,实际可用 VLAN 为 1–4094(共 4094 个)。

[!question] 插入 4 字节 Tag 后帧会不会超过最大长度? 会。带 Tag 的帧最大长度从 1518 字节扩展到 1522 字节。这也是为什么交换机端口通常区分"最大帧长度"配置。

常见 EtherType 对照表

协议 EtherType 说明
IPv4 0x0800 IP 数据包
IPv6 0x86DD IPv6 数据包
ARP 0x0806 地址解析协议
RARP 0x8035 反向 ARP(历史遗留)
PPPoE Discovery 0x8863 PPPoE 发现阶段
PPPoE Session 0x8864 PPPoE 会话阶段
802.1Q 0x8100 VLAN 标记
LACP 0x8809 链路聚合控制协议
LLDP 0x88CC 链路层发现协议

EtherType vs Length:如何区分?

这是以太网中一个经典的历史遗留问题。Ethernet II 和 IEEE 802.3 原始标准在同一个 2 字节位置上使用了不同的语义:

值范围 含义 对应标准
≥ 0x0600 (1536) EtherType — 上层协议标识 Ethernet II
≤ 0x05DC (1500) Length — Payload 字节数 IEEE 802.3 LLC/SNAP

由于合法的 Payload 长度最大为 1500 字节,而合法的 EtherType 最小为 1536,两者不会重叠。现代网络中绝大多数帧都是 Ethernet II 格式,802.3 LLC/SNAP 仅在一些特殊场景(如 STP、某些工业协议)中出现。

[!question] 如果你用 Wireshark 抓到一个该字段值为 0x05EE 的帧,它是什么? 0x05EE = 1518,落在 1501–1535 之间——这是一个非法值,正常的以太网实现不会产生这样的帧。

MAC 地址空间与 OUI

OUI(Organizationally Unique Identifier)

MAC 地址的前三个字节由 IEEE 统一分配给厂商,称为 OUI。查询 OUI 可以知道网卡的制造商:

$ ip link show
link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
                    ↑ 前三个字节 aa:bb:cc 就是 OUI

# 在线查询:https://www.wireshark.org/tools/oui-lookup.html
# Linux 也可以用 ethtool -P eth0 查看出厂 MAC

第一个字节的两个重要比特位

MAC 地址的第一个字节中,最低两位各自承载独立含义(注意:在网络传输中 MAC 地址按 LSB first 顺序发送,但日常书写采用 MSB first):

第一字节: b7 b6 b5 b4 b3 b2 b1 b0
                                ↑ I/G 位 (Individual/Group)
                           ↑ U/L 位 (Universal/Local)

I/G bit(bit 0)— 单播/组播

值 类型 说明 示例
0 单播 (Unicast) 发给单一设备 aa:bb:cc:dd:ee:ff
1 组播 (Multicast) 发给一组设备 01:00:5e:xx:xx:xx(IPv4 组播)

广播地址 ff:ff:ff:ff:ff:ff 是组播的特例(所有 bit 为 1)。

U/L bit(bit 1)— 全局/本地管理

值 类型 说明
0 全局管理 (GUA) 由 IEEE 分配 OUI,厂商保证唯一(网卡出厂 MAC)
1 本地管理 (LAA) 管理员手动设置或软件生成(如 Docker 容器 MAC、虚拟网卡)

[!tip] 如何快速判断?看 MAC 第一个字节的十六进制最后一位

  • a → 1010 → I/G=0, U/L=0 → 单播 + 全局管理
  • 3 → 0011 → I/G=1, U/L=1 → 组播 + 本地管理
  • 2 → 0010 → I/G=0, U/L=1 → 单播 + 本地管理(如 Docker 生成的 MAC)

MAC 地址的比特序

MAC 地址在网线上传输时采用 LSB first(小端序),这与我们日常书写 aa:bb:cc:dd:ee:ff 的 MSB first 习惯相反。这也解释了为什么 IPv4 组播 MAC 的前缀是 01:00:5e 而不是 01:00:5f——因为 01 的实际传输顺序是 10000000,I/G 位确实是第 1 个被发出的比特。

MTU、MSS 与 Jumbo Frame

关键概念区分

概念 层级 标准值 说明
MTU (Maximum Transmission Unit) 链路层 1500 bytes 帧中 Payload 的最大长度(不含 Header 和 FCS)
MSS (Maximum Segment Size) 传输层 (TCP) 1460 bytes TCP 数据段的最大载荷,= MTU - 20(IP) - 20(TCP)
Max Frame 链路层 1518 bytes 整个以太网帧(含 Header 14B + FCS 4B)

Jumbo Frame(巨型帧)

部分交换机和网卡支持 Jumbo Frame,将 MTU 提升到 9000 字节(甚至更大):

帧类型 MTU 最大帧长 适用场景
标准以太网 1500 B 1518 B 通用网络
Jumbo Frame 9000 B 9018 B 数据中心、iSCSI、NFS 存储网络

[!warning] Jumbo Frame 的使用陷阱

  1. 全链路必须一致:路径上任何一台设备不支持 Jumbo Frame,就会导致分片或丢包
  2. 非标准协议:IEEE 从未正式标准化 Jumbo Frame(>1500 的 MTU),各家厂商实现略有差异
  3. 实际收益:减少帧头开销比例,CPU 中断次数降低,在大数据传输场景下吞吐量提升 10%–30%

关联笔记