Files
cs-note/hhs/NETWORK/02-链路层/03-MAC地址与广播域.md
T
2026-05-27 11:24:47 +08:00

222 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [计算机网络, MAC地址, 广播域, 组播, OUI]
create time: 2026-05-17 23:10
---
# MAC 地址与广播域
## 概述
MAC(Media Access Control)地址是数据链路层的物理地址,为全球每台联网设备的每个网络接口分配一个唯一标识。理解 MAC 地址的范围边界——**广播域**——是网络规划的基础。
## MAC 地址结构
### OUI + NIC Serial
```mermaid
flowchart LR
subgraph OUI["OUI — 前 3 字节 (IEEE 分配)"]
B1["AA"] --- B2["BB"] --- B3["CC"]
end
subgraph NIC["NIC Serial — 后 3 字节 (厂商自定)"]
B4["DD"] --- B5["EE"] --- B6["FF"]
end
OUI --- NIC
```
- **OUI** (Organizationally Unique Identifier): 前 3 字节由 IEEE 分配给厂商
- **NIC Serial**: 后 3 字节由厂商自行分配给具体网卡
> [!tip] 48 位,全球唯一
> MAC 地址共 6 字节 = 48 位,理论上可表示 2^48(约 281 万亿)个地址。日常中你看到的 `aa:bb:cc:dd:ee:ff` 或 `aa-bb-cc-dd-ee-ff` 只是两种书写格式,完全等价。
### 寻址类型位
第一个字节的最低两位比特承载了关键的语义信息(它们属于 OUI 的一部分,但具有特殊含义):
| 比特位 | 名称 | 作用 |
|--------|------|------|
| Bit 0(最低位) | **I/G** (Individual/Group) | 0 = 单播,1 = 组播/广播 |
| Bit 1 | **U/L** (Universal/Local) | 0 = 厂商全局唯一,1 = 本地管理 |
> [!question] 思考一下
> 为什么 IEEE 要在 OUI 里预留两个"控制位",而不是把 48 位全部用来编号?
完整的类型判定:
| I/G | U/L | 类型 | 说明 | 示例 |
|-----|-----|------|------|------|
| 0 | 0 | **厂商单播** | 最常见,网卡出厂烧录 | `a0:88:b4:12:34:56` |
| 0 | 1 | **本地单播** | 管理员/软件自定义(见下文) | `02:42:ac:11:00:02` |
| 1 | 0 | **标准组播** | IPv4 组播 MAC | `01:00:5e:00:00:fb`(mDNS) |
| 1 | 1 | **本地组播** | 较少见 | — |
| 1 | 1 | **广播** | 特例:全 1 地址 | `ff:ff:ff:ff:ff:ff` |
> [!tip] 简化记忆
> 看第一个字节的十六进制最低位:**偶数** → 单播,**奇数** → 组播/广播。例如 `a0`(偶)= 单播,`01`(奇)= 组播。
## 广播域(Broadcast Domain)
### 定义
**广播域**是指广播帧能到达的所有设备的集合。在一个广播域内,一个设备发出的 ARP 请求或 DHCP Discover 能被该域内所有其他设备收到。
### 哪些网络设备处理/转发广播?
| 设备 | 是否转发广播帧? | 说明 |
|------|----------------|------|
| Hub(集线器) | ✅ 复制转发到所有端口 | 相当于延长网线,扩大冲突域也扩大广播域 |
| Switch(交换机) | ✅ 转发到除接收口外的所有端口 | **同一 VLAN 内广播不隔离** |
| Router(路由器) | ❌ 不转发 | 天然隔离广播域,每个接口独立广播域 |
| Firewall(防火墙) | ⚙️ 可配置 | 默认通常丢弃 |
```mermaid
flowchart LR
A["PC-A<br/>IP:192.168.1.10"] -->|"ARP广播"| B[Switch<br/>VLAN 10]
B -->|"ARP广播"| C["PC-B<br/>192.168.1.20"]
B -->|"ARP广播"| D["PC-C<br/>192.168.1.30"]
B --"不转发"--> E[Router<br/>VLAN 20]
E --> F["PC-D<br/>192.168.2.10"]
style A fill:#DDA0DD,color:#000
style E fill:#FF6B6B,color:#fff
```
**结论:** Switch 内部不隔离广播域,只有 Router(或三层交换机)的 VLAN 接口才能隔离广播。这就是为什么大型网络需要划分 VLAN。
> [!question] 冲突域 vs 广播域——你能分清吗?
> 这两个概念经常被混淆,它们是两个**不同维度**:
>
> | | 冲突域 (Collision Domain) | 广播域 (Broadcast Domain) |
> |---|---|---|
> | **定义** | 同一时刻只能有一台设备发送数据的网络范围 | 广播帧能到达的所有设备集合 |
> | **被 Hub 扩大** | ✅ 是 | ✅ 是 |
> | **被 Switch 隔离** | ✅ 每个端口一个冲突域 | ❌ 同 VLAN 内不隔离 |
> | **被 Router 隔离** | ✅ 是 | ✅ 是 |
>
> 简记:**Switch 隔离冲突域,Router 隔离广播域**。面试高频考点。
## 二层转发 vs 三层转发
### ARP 解析流程(跨网段的情况)
```mermaid
sequenceDiagram
participant Src as PC-A<br/>192.168.1.10
participant GW as 网关 Router<br/>eth0: 192.168.1.1<br/>eth1: 192.168.2.1
participant Dst as PC-D<br/>192.168.2.10
Src->>Dst: IP包 → 但目的MAC设为谁的?
Note over Src: 发现 dst不在同一子网,<br/>交给默认网关
Src->>GW: ARP "192.168.1.1是谁?"<br/>(局域网内广播)
GW-->>Src: ARP回复 "我是! eth0 MAC=aa:bb:cc:dd:ee:01"
Note over Src,Dst: 源MAC=Src MAC<br/>目的MAC=Gateway MAC<br/>目标IP=Remote IP
Src->>GW: Frame[EthHdr(Dst=GW_mac)|IP(src_ip,dst_ip)]
Note over GW: Strip Ethernet → 查路由表 → 重封帧
GW->>Dst: Frame[EthHdr(Dst=Dst_mac)|IP(src_ip,dst_ip)]
Note over GW: src MAC 变成了 Gateway MAC!<br/>MAC 逐跳改写,IP 不变
```
### 关键规律总结
| 层级 | 地址变化 | 跨越范围 |
|------|---------|---------|
| IP 地址(第3层) | **保持不变**(除非 NAT) | 端到端,从源到终点 |
| MAC 地址(第2层) | **每跳改写** | 只服务于当前链路(两台相邻设备之间) |
## MAC 地址表(Switch CAM 表)
### Switch 如何学习 MAC?
```mermaid
flowchart TD
S["Switch 启动"] --> L["清空 MAC 表"]
L --> R["收到帧 Port1"]
R --> Learn["提取 Src MAC → 记录: mac→port1"]
Learn --> Fwd{"已知目的 MAC?"}
Fwd -->|"是"| Forward["仅转发到对应端口"]
Fwd -->|"否"| Flood["泛洪到所有其他端口"]
```
### 查看 MAC 表
```bash
# Linux Bridge / 大多数交换机等价命令
$ bridge fdb show
aa:bb:cc:dd:ee:01 dev eth0 master br0 permanent
aa:bb:cc:dd:ee:ff dev eth1 vlan 10 self permanent
# 传统命令
$ arp -a # 查看 ARP 缓存(IP → MAC 映射)
$ ip neigh # 等价于 arp,更现代
```
### MAC 表老化
MAC 表条目有超时时间(通常 300 秒),超时后自动删除,等待下一帧到来重新学习。这防止了表中堆积无效条目。
## 本地管理地址(LAA)与 MAC 欺骗
### 什么是 LAA?
当 U/L 位 = 1 时,该地址不再是 IEEE 全局分配的,而是由**管理员或软件自行设定**,称为 Locally Administered Address (LAA)。
### 谁在用 LAA?
| 场景 | 说明 |
|------|------|
| Docker 容器 | 容器的 veth 接口 MAC 通常以 `02:42:` 开头 |
| 虚拟机 (KVM/QEMU) | 虚拟网卡 MAC 以 `52:54:` 开头 |
| 隐私保护 | iOS/Android 的 Wi-Fi 随机 MAC 地址 |
| MAC 欺骗攻击 | 攻击者伪造目标 MAC 以实施中间人攻击 |
### MAC 欺骗原理
```mermaid
sequenceDiagram
participant Attacker as 攻击者
participant Switch as Switch
participant Victim as 受害者
participant GW as 网关
Note over Switch: MAC表: GW_mac → Port3
Attacker->>Switch: 发送伪造帧 (Src MAC = GW_mac)
Note over Switch: 更新MAC表: GW_mac → Port1(攻击者)!
GW->>Switch: 发往受害者的数据
Switch->>Attacker: 转发到 Port1(攻击者端口)
Attacker->>Victim: 转发给受害者(无感知)
```
> [!warning] 防御 MAC 欺骗
> - **Port Security**:限制每个端口可学习的 MAC 数量
> - **Dynamic ARP Inspection (DAI)**:校验 ARP 报文合法性
> - **802.1X 认证**:端口级准入控制,未认证设备无法通信
## 广播风暴与防范
### 什么是广播风暴?
当广播帧在网络中无限循环(如物理环路未启用 STP)时,每个交换机会不断泛洪,最终耗尽带宽。
### 防范措施
| 措施 | 说明 |
|------|------|
| **STP/RSTP/MSTP** | 生成树协议,自动阻断环路端口 |
| **VLAN 划分** | 缩小广播域规模 |
| **BPDU Guard** | 在接入端口禁用 STP 协议包 |
| **广播速率限制** | Switch 端口限速广播流量 |
| **IP 亚网划分** | 减少每个广播域内的主机数 |
> [!tip] 最佳实践
> 生产网络的广播域规模建议不超过 `/23`(510 台主机)。超过就应考虑划分 VLAN,用三层路由互联。
## 关联笔记
- [[hhs/NETWORK/Ethernet帧结构]] — 以太网帧的目的/源 MAC 字段
- [[hhs/NETWORK/VLAN与Trunk]] — VLAN 如何进一步隔离广播域
- [[hhs/NETWORK/ARP协议完整流程]] — MAC 地址的动态解析过程