--- tags: [计算机网络, Ethernet, MAC, 帧结构, 数据链路层] 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 可以知道网卡的制造商: ```bash $ 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` → 101**0** → I/G=0, U/L=0 → 单播 + 全局管理 > - `3` → 001**1** → I/G=1, U/L=1 → 组播 + 本地管理 > - `2` → 001**0** → 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% ## 关联笔记 - [[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 的实际部署