Old-School Networking / 2026 ・ No.03

古法网络入门

第3讲 数据链路层 ── MAC 地址与交换机,“问所有人”的 ARP

发布

Wireshark 的界面。选中第 1 行 ARP,详情中展开了 Ethernet II 的目的 Broadcast(ff:ff:ff:ff:ff:ff),以及 Address Resolution Protocol (request) 的内容(Opcode: request、Sender MAC 02:00:00:00:01:10、Sender IP 10.0.1.10、Target MAC 00:00:00:00:00:00、Target IP 10.0.1.11)
新井的电脑最先发出的 ARP 询问。目的是所有人(Broadcast),想问的对方 MAC 还不知道,所以是 00:00:00:00:00:00(在笔者于云端搭建的练习用网络中,于 2026 年 10 月 24 日记录,用 Wireshark 4.2.2 打开后截图。界面保持英文。窗口上方的标题栏是为了说明而后加的)

第 2 讲我们看到比特变成信号在网线上跑。
这一讲往上一层,是数据链路层。帧的收件人 MAC 地址,记住收件人并分别投递的交换机,从 IP 地址查 MAC 地址的 ARP。
第 1 讲里电脑为什么一开始就“问所有人”?我们用一台交换机和三台电脑的练习网络来确认。还会做一个实验:环路让一个帧每秒变成 55 万个。

一

收件人这一层

新井第 1 讲里,电脑一开始就对所有人问“10.0.1.1 的 MAC 是?”。这是不是有点失礼?一上来就问所有人。

古井不认识对方的脸,只能在教室里喊“古井在吗?”。只有被叫到的本人举手。

新井对没被叫到的人来说,是打扰吧。

古井所以有办法,只在第一次问所有人。今天就看这个。

全 12 讲路线图(当前位置:第 3 讲)

1 全景图 2 物理层 3 数据链路层 4 IP 地址 5 路由器 6 TCP 7 UDP・套接字 8 TLS 9 DNS 10 HTTP 11 开发者的网络 12 故障排查 当前位置 全景图 第1层 第2层 第3层 第4层 第5・6层 第7层 实战
  • MAC 地址 ── 6 字节的构成、厂商编号、本地与全球、发给所有人
  • 交换机 ── 记住目的地,只发往需要的口。记住之前发往所有口
  • ARP ── 从 IP 地址查 MAC 地址。答案记住 30 秒左右
  • MTU、VLAN、STP ── 一次能运多大、把一台分开的技术、防止环路的技术
二

数据链路层的工作

数据链路层的工作,是在同一个网络里,送到相邻的设备。第 1 讲看到,MAC 地址每经过一台路由器就被换掉。数据链路层负责的只是“这条线上的下一台”。

为此,数据链路层把比特流切成叫帧的单位,写上收件人(目的和源 MAC 地址)和内容的种类,最后加上第 2 讲的 FCS,丢弃损坏的帧。代表是 Ethernet(有线)和 Wi-Fi(IEEE 802.11),两者都使用同样格式的 MAC 地址。

POINT

数据链路层=送到相邻设备的层。收件人是 MAC 地址,单位是帧。到远方对方的路径,是下一层第 3 层(IP)的工作。

三

MAC 地址

MAC 地址是 6 字节(48 位)的编号,通常用“:”连接十六进制来写。前 3 字节是 IEEE 分配给厂商的编号(OUI),后 3 字节是厂商给每台设备定的编号。

本系列电脑的 MAC 地址 02:00:00:00:01:10 的构成

02 : 00 : 00 : 00 : 01 : 10 厂商编号(OUI) 设备编号 由 IEEE 分配 厂商逐台决定 把开头的 02 写成二进制 0 0 0 0 0 0 1 0 最低位=0:发给一台 倒数第二位=1:本地 本系列的 MAC 以 02 开头,是“本地”编号。手动设定,所以没有厂商编号

第一个字节的最低两位有含义。最低位是 1 表示发给一组(组播)。全部为 1 的 ff:ff:ff:ff:ff:ff 是发给所有人(广播)。倒数第二位是 1,表示不是厂商给的编号,而是自己定的本地编号。本系列的 MAC 以 02 开头,是为了易读而手动设定的。

数一数 Wireshark 4.2.2 自带的厂商编号表,3 字节的 OUI 有 34,621 个。最多的是 Apple,1,193 个,其次是 Cisco 1,111 个、Huawei 1,097 个。一个 OUI 可以生成约 1,678 万台的编号,大公司都持有好几个。

不过,最近的手机和电脑在 Wi-Fi 上越来越多地不用真实 MAC 地址。iPhone 从 iOS 14 起有“私有 Wi-Fi 地址”,Android 从 10 起默认对每个网络使用随机的 MAC 地址。这是为了不让商店 Wi-Fi 等通过 MAC 地址追踪同一个人的行踪。请记住:MAC 地址不一定是“全球唯一的设备编号”。

四

帧的头部

Ethernet 帧的头部只有 14 字节。

Ethernet 头部(以及加入 VLAN 标签时)

普通的帧(头部 14 字节) 目的 MAC 6 源 MAC 6 类型 2 内容 46〜1500 FCS 4 带 VLAN 标签(多 4 字节) 目的 MAC 6 源 MAC 6 标签 81 00 + VLAN 类型 2 内容 FCS 4 VLAN 号是 12 位(1〜4094) 类型(EtherType)的例子 0800 IPv4 0806 ARP 86DD IPv6 8100 VLAN 标签

目的地址在最前面,所以交换机只要读完前 6 个字节,就能开始查从哪个口送出去(也有在收完整帧之前就开始转发的交换机)。第三个“类型”(EtherType)是表示内容是什么的 2 字节。0800 是 IPv4 数据包,0806 是 ARP。接收方看这个编号,把内容交给下一个负责者(第 3 层)。

五

交换机会记住

第 2 讲说过,交换机只往目的口送。那么交换机怎么知道哪个口上是谁?答案是看收到的帧的源地址,记下来。

交换机的学习。记住发送方,不认识的目的地发往所有口

① 发给所有人(ARP 询问) 交换机 新井 p1 古井 p2 山田 p3 路由器 p4 记住发送方(p1),发往所有口 ② 回复(已记住目的地) 交换机 新井 p1 古井 p2 山田 p3 路由器 p4 只发往记住的 p1,也记住 p2 记住的表(MAC → 口) 02:00:00:00:01:10 p1 02:00:00:00:01:11 p2

我重新搭了练习网络。用 Linux 网桥做交换机,接上新井(10.0.1.10)、古井(.11)、山田(.12)的电脑和路由器(.1)。在 4 台上同时记录,从新井向古井 ping 3 次。

# 交换机(网桥)记住的表。ping 之前是空的
$ bridge fdb show br br0
    (什么都没有)
# 新井 ping 古井之后(MAC 以及对方所在的口)
$ bridge fdb show br br0
    02:00:00:00:01:10  p1
    02:00:00:00:01:11  p2
# 记住的内容 300 秒不用就会忘掉(ageing_time 的默认值)
并排显示三个 Wireshark 数据包列表。上面是新井电脑的记录,ARP 2 个和 ping 6 个共 8 个。中间是同一时间到达山田电脑的,只有 1 个发给所有人的 ARP。下面是一开始就知道目的 MAC 时,到达山田电脑的 ping 第 1 个,以及古井询问新井的 ARP,共 2 个
用三台电脑的记录确认交换机的学习。不是发给自己的帧,几乎不会到达山田的电脑(在笔者于云端搭建的练习用网络中,于 2026 年 10 月 24 日记录,用 Wireshark 4.2.2 打开后截图。界面保持英文。窗口上方的标题栏是为了说明而后加的)
收到的帧数新井古井山田路由器
① 普通 ping(从 ARP 开始)8811
② 一开始就知道古井的 MAC 时8822

在①中,到达山田和路由器的只有 1 个发给所有人的 ARP。之后的 6 个 ping,交换机只发往记住的口。在②中,新井不做 ARP 就直接发给古井,交换机还不知道古井在哪个口,于是把第 1 个 ping 发往所有口(不认识的目的地就发给所有人)。有意思的是,之后古井的电脑不知道新井的 MAC,又反过来向所有人发了 ARP 询问。

新井在②里,山田收到了一个不认识的 ping。

古井不是发给自己的,山田的电脑只是丢掉。不过在同一个局域网里,像这样可能看到别人的帧。所以重要的内容要加密(第 8 讲)。

六

ARP:从 IP 查 MAC

应用知道的是对方的 IP 地址(第 1 讲中是 10.0.2.20)。但帧的收件人需要 MAC 地址。这时登场的是 ARP(Address Resolution Protocol)。封面照片就是新井电脑发出的 ARP 询问本身。

ARP 是“问所有人,只有本人回答”

新井 古井 (.11) 山田 (.12) 10.0.1.11 的 MAC 是?(问所有人) 是我,02:…:01:11 (不是自己,不出声) REACHABLE STALE 0 10 20 30 40 50 60 70 32 秒后变成 STALE 经过秒数(实测)。变成 STALE 也不会删除,下次使用时再确认

询问是发给所有人的(目的 ff:ff:ff:ff:ff:ff),里面写着“我是 10.0.1.10、02:00:00:00:01:10,请告诉我 10.0.1.11 的 MAC”。对方的 MAC 还不知道,所以那里填 0。只有 10.0.1.11 的古井回答给新井。答案在 ARP 缓存里记一段时间,下次就不用再问了。

# ping 之后的 ARP 缓存(IP 与 MAC 的对应表)
$ ip neigh show
    10.0.1.11 dev eth0 lladdr 02:00:00:00:01:11 REACHABLE
# 就这样等着……(每秒查看一次)
# 32 秒后变成 STALE(可能过期)
$ ip neigh show
    10.0.1.11 dev eth0 lladdr 02:00:00:00:01:11 STALE
# 30 秒左右(15〜45 秒之间)就会变。并不会被删掉

对方在别的网络时,问对方的 MAC 也得不到回答。于是电脑去问出口路由器(默认网关)的 MAC。第 1 讲中新井的电脑问的不是 10.0.2.20 而是 10.0.1.1,就是这个原因。

NOTE

ARP 没有确认“回答是否真实”的机制。同一局域网里的恶意机器如果谎称“10.0.1.1 是我”,就能截取通信(ARP 欺骗)。有些企业级交换机具备防范功能。

七

MTU:一次能运多大

Ethernet 帧能运的内容最多 1,500 字节。这个上限叫 MTU(Maximum Transmission Unit)。加上头部 14 和 FCS 4,帧最大 1,518 字节。再结合第 2 讲的“最少 64 字节”,帧的大小在 64〜1,518 字节之间。

我实际发了一个正好填满 MTU 的 ping,和一个只多 1 字节的 ping。

# 内容 1472 字节+ICMP 8+IP 20=1500。加上“不要分片(-M do)”发送
$ ping -c 1 -M do -s 1472 10.0.1.11
    PING 10.0.1.11 (10.0.1.11) 1472(1500) bytes of data.
    1480 bytes from 10.0.1.11: icmp_seq=1 ttl=64 time=0.053 ms
# 多 1 字节变成 1501……
$ ping -c 1 -M do -s 1473 10.0.1.11
    PING 10.0.1.11 (10.0.1.11) 1473(1501) bytes of data.
    ping: local error: message too long, mtu=1500

1,500 字节以内能通过,1,501 字节发不出去

ping -s 1472(内容 1472) 1472 1500 ✓ ping -s 1473(内容 1473) 1473 1501 ✕ MTU 1500(第2层能运的内容上限) IP 头部 20 + ICMP 8 + 内容。哪怕超过 1 字节就是“message too long”

大的数据由 TCP 切成 MTU 以内的块来发送(第 6 讲)。需要注意的是途中有 MTU 较小的区间时。家用光纤的 PPPoE(1,492)或 VPN 隧道,因为头部增加,MTU 会变小。如果只有大数据包过不去,就会出现“小页面能打开,只有大文件卡住”的怪故障(第 12 讲讨论)。

八

VLAN:把一台分开

办公室里“财务的电脑和访客 Wi-Fi 想接在同一台交换机上,但不想混在一起”时,不必买好几台交换机,而是用 VLAN。这是把一台交换机的口按编号当作不同局域网来处理的技术。

分成 VLAN 10 和 VLAN 20 后,“发给所有人”也分开了

交换机(1 台) 新井 VLAN 10 古井 VLAN 10 山田 VLAN 20 路由器 Trunk 10 / 20 新井的“发给所有人”只到达 VLAN 10 之内 到不了山田那里(等于另一个局域网) 跨 VLAN 要经过路由器(第3层)

在交换机之间或通往路由器的线上,为了一根线运送多个 VLAN(Trunk),会在帧里插入 4 字节的标签。81 00 是“有标签”的记号,接下来的 12 位是 VLAN 号。

Wireshark 的界面。两行 ARP 中选中了长度为 46 的第 2 行,详情中展开了 802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 10。字节栏里可以看到源 MAC 之后的 81 00 00 0a
带 VLAN 10 标签的帧。源 MAC 之后插入了 81 00(标签记号)和 00 0a(VLAN 10)共 4 字节,42 字节变成了 46 字节(这一帧是笔者把标签插进记录到的 ARP 里做出来的)(在笔者于云端搭建的练习用网络中,于 2026 年 10 月 24 日记录,用 Wireshark 4.2.2 打开后截图。界面保持英文。窗口上方的标题栏是为了说明而后加的)

本来也想在练习网络里搭 VLAN,但写这篇文章用的云端 Linux 没有 VLAN 功能,设置不了。所以照片里的帧,是把标签手工插进记录到的 ARP 里,再让 Wireshark 读取的。

九

环路与 STP

交换机会把“不认识的目的地和发给所有人的帧”发往所有口。那么,用两根线连接两台交换机,形成一个环(环路),会怎样?想当备用线接上去,就真的会发生。我测了一下。

实测:只发了一个“发给所有人”

没有 STP SW1 SW2 hA hB 从 hA 发一个“发给所有人” hB 1 秒收到 556,744 个 不拔掉一根线就停不下来 有 STP(阻断一根) SW1 SW2 ✕ hA hB 从 hA 发一个“发给所有人” hB 收到 1 个 切断线后 4.2 秒完成切换 实测(Linux 网桥,STP 为经典 802.1D,等待时间设得较短)

从 hA 只发一个发给所有人的帧,两台交换机就互相转发,帧在环里不停地转。hB 1 秒内收到约 55 万个(测了 3 次,556,079〜582,306 个),不拔掉一根线就停不下来。帧没有像第 3 层 TTL 那样的“寿命”,所以不会自然消失。这叫广播风暴,在真实的办公室里,整个网络都会瘫痪。

防止它的是 STP(Spanning Tree Protocol,生成树协议)。交换机之间互相联络,为了不形成环,让一根线停用。

# 启用 STP 的两台交换机的端口状态(收敛用了 5.0 秒)
# SW1
    pa   forwarding
    l1   forwarding
    l2   forwarding
# SW2:第二根线(l2)是 blocking=被阻断
    pb   forwarding
    l1   forwarding
    l2   blocking

启用 STP 后,同样一个帧只到达 hB 一次。再切断正在使用的线,切换到被阻断的线花了 4.2 秒,期间 39 个 ping 没有回应。这是把老式 STP(802.1D)的等待时间设短后的值,默认设置要 30 秒左右。现在的企业交换机通常使用切换快得多的 RSTP(802.1w)。

新井只发一个就变成 55 万个……想当备用线加上去,就会这样啊。

古井古法的办公室里,有人在桌子底下把多余网线的两头插到同一个集线器上,整层楼就瘫了。家用交换机很多没有 STP。别接成环。

十

在自己的电脑上确认

想查什么MacWindowsLinux
自己的 MAC 地址ifconfig en0ipconfig /allip link
ARP 缓存arp -aarp -aip neigh
MTUifconfig en0netsh interface ipv4 show subinterfacesip link

看 arp -a,一定能看到家里路由器(默认网关)的 IP 地址和 MAC 地址。因为所有发往互联网的通信,帧都是发给它的。

Wi-Fi 接入点也是数据链路层的设备。它作为连接无线一侧和有线一侧的“桥”(网桥),看 MAC 地址进行转发。电波上的帧(802.11)最多有 4 个地址,格式不同,但在电脑里会被转成和 Ethernet 一样的格式,所以在 Wireshark 里看起来几乎没区别。

结 — 一页总结与下一讲

  1. 数据链路层是送到相邻设备的层。收件人是 MAC 地址,单位是帧。
  2. MAC 是 6 字节。前半是厂商编号(OUI)。ff:ff:ff:ff:ff:ff 是发给所有人。手机的 Wi-Fi 多用随机 MAC。
  3. 头部 14 字节(目的、源、类型)。类型 0800 是 IPv4,0806 是 ARP。
  4. 交换机看源地址记下来,认识的目的地只发一个口,不认识的和发给所有人的发往所有口。
  5. ARP 问所有人,只有本人回答。答案进缓存。实测 32 秒变成 STALE。
  6. MTU 是 1,500。1,472+28 能通过,多 1 字节就发不出去。
  7. VLAN 把一台分开,用 4 字节标签区分。环路会让一个帧每秒变成 55 万个。用 STP 阻断一根。

新井MAC 只管到相邻设备。那像 10.0.2.20 这样远的对方,是谁来决定路线的?

古井那就是下一讲的第 3 层。先从 IP 地址本身开始。10.0.1.10 的“/24”是什么意思,你能说明吗?

参考

记录来自笔者在云端 Linux(Ubuntu 24.04)上用网络命名空间搭建的练习网络,于 2026 年 10 月 24 日抓取。交换机是 Linux 网桥(学习时间为默认的 300 秒,关闭了 IGMP 通知),环路实验也用两台 Linux 网桥(STP 为 802.1D,forward_delay 2 秒、hello_time 1 秒、max_age 6 秒)。数字都是从这些记录和当时命令的输出读出的实际数值。只有 VLAN 的帧,因为该环境无法使用 VLAN,是把标签插进记录到的 ARP 做出来的。厂商编号的数量,是数了 Wireshark 4.2.2 自带的列表(tshark -G manuf)。登场人物均为虚构。

古法网络入门 第3讲 — 数据链路层 / 2026.10

← 返回文章列表