以太网与 MAC 地址
以太网与 MAC 地址
多个设备怎么共享一根线
1970 年代,办公环境开始普及小型机。多个员工想同时访问公司那台 IBM 小型机。怎么连?工程师面前有三个选择:
方案 A:每个员工用一根线直连小型机。 100 个员工就要 100 根线从机房拉到工位,小型机也得有 100 个网口。线缆多、维护难、加人难。
方案 B:所有员工用一根公共线。 像有线电视一样,所有人共享一根主干电缆。这是最省线的方案,但所有人都用同一根线,信号会"撞车"——两个人同时说话,电磁波叠加成乱码。
方案 C:每台员工机器都接一个盒子,盒子之间用高速总线连起来。 每个盒子是独立设备,能识别"这个信号是给谁的",不是给自己的就过滤掉。
1973 年施乐公司帕洛阿图研究中心(Xerox PARC)的鲍勃·梅特卡夫(Bob Metcalfe)发明了以太网(Ethernet),用的就是方案 C 的思路:以太网这个名字来自"以太"(光传播的假想介质),寓意"信号像光一样在公共介质中传播"。梅特卡夫后来创办了 3Com,把以太网带出实验室。
MAC 地址:设备的身份证
以太网最核心的设计是给每个网卡分配一个全球唯一的 48 位地址,叫 MAC 地址(Media Access Control Address)。前 24 位是厂商代码(OUI),后 24 位是厂商自己分配的序列号。比如 00:1A:2B:3C:4D:5E 前缀 00:1A:2B 表示 Apple 公司。
MAC 地址理论上全球唯一——每张网卡出厂时烧死在硬件里。理论上不同厂商的 OUI 不同,理论上同一厂商的网卡序列号不会重复。现实里有些网卡允许软件改 MAC 地址(克隆模式),Docker 容器、虚拟机就会用这个功能。
MAC 地址的格式有几种写法:
00:1A:2B:3C:4D:5E(Linux 命令行)00-1A-2B-3C-4D-5E(Windows 设备管理器)001A.2B3C.4D5E(Cisco 设备)
三种写法表示同一个地址。冒号、横线、点都可以,分隔只是为了人眼方便。
以太网帧结构
数据在线缆上以"帧"为单位传输。标准以太网帧(Ethernet II)长这样:
以太网 II 帧结构:
每个字段的用途:
- 目的 MAC:这个帧是给谁的。交换机用这个字段决定把帧转发到哪个端口。
- 源 MAC:发送方是谁。接收方用这个字段回包。
- 类型:上层协议类型。0x0800 是 IPv4,0x86DD 是 IPv6,0x0806 是 ARP。
- 数据载荷:上层协议的数据,比如一个完整的 IP 数据报。最少 46 字节(不够要填充),最多 1500 字节(这就是 MTU 1500 的来历)。
- FCS(Frame Check Sequence):CRC32 校验和。接收方算一遍校验和,如果对不上就丢弃。
MTU 是关键概念——Maximum Transmission Unit 最大传输单元。1500 字节是标准以太网 MTU。如果 IP 数据报超过 1500 字节,网络层要分片(fragment)。分片增加复杂度和丢包风险,所以现代网络尽量用大 MTU(巨型帧 9000 字节)减少分片。
交换机的革命
早期以太网是总线型,所有机器共享一根同轴电缆。CSMA/CD 协议负责协调"什么时候可以发":先听后发、边发边听、冲突退避。这套机制延迟不可预测,性能差。
1990 年代交换机普及,每台机器独占一条到交换机的链路,再也不需要 CSMA/CD。交换机内部有个 MAC 地址表:端口 1 见过 MAC 00:1A:2B... 就把表项记下来。收到帧时查表,目的 MAC 对应哪个端口,就转发到哪个端口(其他端口不收)。
| MAC 地址 | 端口 |
|---|---|
| AA:BB:CC:11:22:33 | 1 |
| DD:EE:FF:44:55:66 | 2 |
| 11:22:33:AA:BB:CC | 3 |
第一次收到未知目的 MAC 时,交换机做"泛洪"(flooding)——把帧从所有端口都发出去,目标机器收到后会回包,回包时交换机就能学到目标 MAC 在哪个端口。后续帧就只往这个端口发。
这是交换机的自学习机制。30 多年了,原理没变。
真实场景:用 Wireshark 抓 MAC 帧
打开 Wireshark,过滤器写 eth.addr == aa:bb:cc:11:22:33,就能看到特定 MAC 的所有流量。点开一条帧看:
- Frame 78 (1514 bytes on wire, 1514 bytes captured)
- Ethernet II
- Destination: Cisco_11:22:33 (00:1A:2B:11:22:33)
- Source: Apple_44:55:66 (00:CD:FE:44:55:66)
- Type: IP (0x0800)
- Internet Protocol
- ...
这里 Source 字段显示 "Apple_44:55:66",因为 Wireshark 查了 OUI 厂商列表,识别出前 24 位是 Apple 的。实用的过滤器:
| 过滤器 | 用途 |
|---|---|
eth.addr == aa:bb:cc:11:22:33 | 特定 MAC 收发包 |
eth.dst == ff:ff:ff:ff:ff:ff | 所有广播帧 |
eth.type == 0x0806 | 所有 ARP 帧 |
eth.type == 0x86dd | 所有 IPv6 帧 |
MAC 地址会过期吗
MAC 地址理论上不"过期"——硬件不变地址就不变。但有几种情况 MAC 会"变":
换网卡。 老笔记本的 Intel 网卡坏了,换成 Realtek 网卡,MAC 就变了。
虚拟机。 VMware 默认每次启动虚拟机会生成不同的 MAC(但保持首字节是特定值,方便识别)。这导致 DHCP 服务器可能分配到不同 IP。
Docker。 Docker 创建容器时给每个容器分配一个虚拟 MAC,前 24 位是 02:42:...(OUI 是 Docker 注册的)。
MAC 随机化(隐私保护)。 现代手机连 Wi-Fi 时使用随机 MAC,目的就是不让商场、咖啡馆的 Wi-Fi 运营商跟踪你。
MAC 地址漂移。 某些虚拟化环境下,虚拟机从 A 物理机迁移到 B 物理机,但 MAC 保留。交换机 MAC 表里的端口信息就过期了——这叫 MAC 地址漂移,严重的会导致网络环路。
一个常见的坑:MAC 地址表满了怎么办
家用 8 口交换机 MAC 表有 8000 项左右,机房里 48 口交换机可能只有 16000 项。如果接入设备超过表项数(比如 Docker Swarm 集群、虚拟桌面云),交换机会把最久没用过的表项挤掉,新设备第一次发包时被泛洪处理。
单播泛洪(Unicast Flooding) 是性能杀手——一个未知目的 MAC 的单播帧被发到所有端口,等于把局域网"广播"了一遍。攻击者可以伪造大量虚假 MAC 发包,耗光交换机表项,导致正常用户的单播也被泛洪,整个网络性能暴跌。这叫 MAC Flood Attack,属于数据链路层攻击。
防御方法:交换机开启端口安全(Port Security),限制每个端口能学到的 MAC 数量(比如最多 5 个)。超过限制的 MAC 直接丢弃或关闭端口。
思考题
- 为什么 MAC 地址是 48 位而不是 32 位或 64 位?48 位能表示多少个地址?够用吗?(提示:IEEE 注册成本、IPv6 用 64 位 EIU-64、地址空间分配方式)
- 交换机和集线器(Hub)有什么区别?集线器现在还有用吗?(提示:物理层 vs 数据链路层、冲突域、CSMA/CD)
- 你电脑接在公司网络里 ping 不通隔壁工位电脑,但能 ping 通网关。问题可能出在哪一层?(提示:ARP 缓存、VLAN 隔离、IP 子网、防火墙)
- 用 Wireshark 抓包时能看到
Source: Apple_44:55:66,这是 MAC 地址前 24 位的厂商识别。如果你抓到一个 MAC 前 24 位是02:42:xx:xx:xx:xx,你能判断这是什么设备吗?
延伸阅读
- 《深入浅出计算机网络》(高军)第 3 章
- IEEE 802.3 标准
- 动手实验:在 Windows 命令行
arp -a查看本机 ARP 缓存 - 动手实验:用 Wireshark 抓一次 ping,看 ARP 解析过程