11 KiB
tags, create time
| tags | create time | |||||
|---|---|---|---|---|---|---|
|
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 的使用陷阱
- 全链路必须一致:路径上任何一台设备不支持 Jumbo Frame,就会导致分片或丢包
- 非标准协议:IEEE 从未正式标准化 Jumbo Frame(>1500 的 MTU),各家厂商实现略有差异
- 实际收益:减少帧头开销比例,CPU 中断次数降低,在大数据传输场景下吞吐量提升 10%–30%
关联笔记
- hhs/NETWORK/01-基础概念/01-OSI与TCP-IP模型对比 — 以太网属于链路层
- hhs/NETWORK/02-链路层/03-MAC地址与广播域 — MAC 地址的工作范围
- hhs/NETWORK/02-链路层/04-Switch与路由器 — Switch 如何使用 MAC 表转发帧
- hhs/NETWORK/02-链路层/02-CSMA-CD与以太网退避 — CSMA/CD 碰撞检测机制
- hhs/NETWORK/02-链路层/05-VLAN与Trunk — 802.1Q VLAN 的实际部署