5.9 里那句"查不到就泛洪",本节把它单独拎出来讲完。交换机的 MAC 地址表是自学来的,所以存在一段"我还不认识你"的时期——此时的帧目的地址明明写的是某一个具体设备(单播),但交换机在表里翻不到,于是只能除入端口外所有口各送一份碰运气,这叫未知单播帧(Unknown Unicast Frame)泛洪。要分清两个维度:"单播 / 广播 / 组播"说的是目的 MAC 长什么样,"已知 / 未知"说的是交换机表里有没有——未知单播帧是"本该只送一份、却被送了很多份"的帧,它不是广播,但行为上像广播。本节讲清三件事:"未知"有哪三个来源(表还没学到 · 表项老化删了 · 表装满了)、泛洪具体怎么发(除入端口外全送、范围到广播域边界为止、帧本身一个字节不改、顺带把源 MAC 学会)、代价为什么值得警惕(一份变 N 份白占带宽、打扰所有口上的设备、同广播域内任何主机都可能嗅探到、放大会引发风暴)。最后给出一整套把泛洪压下去的手段,以及和 ARP 的配合关系。
本节是 5.9 · 5.10 的第三块拼图,也是最小的一块——但它是"交换机为什么会慢、为什么会漏"的答案。
- 5.9 创建以太网网络(二层交换机):讲了三个动作学习 / 转发 / 泛洪。本节把"泛洪"这个动作单独放大:它到底什么时候发生、发生时全网是什么景象
- 5.10 二层交换机的操作(二层交换机的数据传输):一帧的旅程第 ③ 步写着"未命中或广播 → 泛洪"——本节展开那个"未命中"
- 3.9 接收方是1个还是多个(单播、广播、组播):三种收件形态;本节把它们放进"交换机视角"再看一遍(判据多了一个:表里有没有)
- 3.16 将 IP 地址与 MAC 地址对应(ARP):ARP 请求本身就是广播帧,它既触发泛洪,又顺手把 MAC 表填好——这就是"泛洪通常只发生在第一次"的原因
- 5.6 数据的格式(以太网的数据帧格式):帧的目的 MAC 字段在交换机眼里就是"路牌";泛洪送出去的是原封不动的同一帧(透明设备)
- 5.4 接口是哪个(MAC地址):MAC 扁平无结构,所以交换机只能"建表查表",查不到就只能到处送——这是无结构地址的必然后果
- 5.2 负责传输数据的以太网(以太网概要):广播帧从除来源口外所有口送出;本节讲的是单播帧也会被这样送
- 3.18 对应用程序的数据进行可靠传输(TCP):泛洪多出来的那些份数被丢掉时没有任何人通知发送方,"可靠"仍是 TCP 事后补
- 4.9 审核公司员工浏览的 Web 网站(代理服务器的用途):未知单播泛洪是"同网段能抓到别人流量"的漏点之一,也是审计与抓包能奏效的前提
- 2.2 用于构建网络的设备(网络设备):交换机在链路层,它看到的只有帧头——所以"认不认识路"完全取决于一张表
一、先把"未知单播帧"这个名字拆开
这个名字里其实塞了两个互不相干的判断,拆开就懂了:
| 判断 | 看的是什么 | 可能的取值 |
|---|---|---|
| 是不是单播 | 帧头里目的 MAC 地址长什么样 | 单播 / 广播 / 组播 |
| 是不是已知 | 交换机 MAC 地址表里查不查得到这个目的 MAC | 已知 / 未知 |
于是未知单播帧=目的地址写着一个具体设备(单播),但交换机在表里找不到它在哪个口。
这时交换机只有一条路可走:它不知道该往哪个口送,那就除了来路以外,每个口都送一份——这就是泛洪(flooding)。
"单播 / 广播"是发送方写下的地址类型;"泛洪"是交换机对地址的检索结果。
所以: - 广播帧一定被泛洪(发送方就是要发给所有人) - 未知单播帧也会被泛洪(发送方只想发给一个人,是交换机不认识路) - 已知单播帧不会被泛洪(表里查到了,只从那一个口送)
交换机的动作其实有三种,别只记两种:
| 目的 MAC | 表里查得到吗 | 交换机怎么送 | 出现在几条链路上 |
|---|---|---|---|
| 某个具体设备(单播) | 查得到 | 定向转发 | 1 条 |
| 某个具体设备(单播) | 查不到 | 泛洪 | 除入端口外全部 |
全 FF:FF:FF:FF:FF:FF(广播)/ 组播地址 |
不查表 | 泛洪(组播可优化) | 除入端口外全部 |
组播帧(224.x 对应的 MAC 01:00:5E:...)默认也会泛洪——因为交换机看不懂"谁加入了这个组"。
但网管型交换机支持 IGMP snooping:偷看主机发的 IGMP 入组报文(收 3.9),把"这个组有哪些口要"记下来,之后组播就只往那些口送。
名字里的 snooping(偷看)很传神——交换机本身不参与组播协议,它只是"顺便听了听,然后自己记了一笔"。
二、"未知"是怎么发生的:三个来源
泛洪不是只在开机时发生一次,它有三个来源:
1. 表里还没有(最常见,也最正常)
- 交换机刚重启、表是空的
- 某台设备刚接入、还没发过任何帧
- 表项被老化删掉了——表项有寿命(常见默认约 300 秒,收 5.9),这段时间内没再通信就会被删
交换机是靠收帧来学的。它第一次见到"要给 C 发帧"这件事时,必然还没学到 C 在哪儿——除非 C 之前主动说过话。 所以一个很反直觉但正确的结论:A 想给 C 发数据,但 A 的帧能不能被"定向"送出去,取决于 C 之前有没有发过帧(任何帧都算——包括 C 自己发的 ARP、广播、甚至无关的流量)。 是对方先说过话,你才能被定向送达。
2. 表项老化,但双方的通信还在继续
这是最"冤枉"的一种:A 和 C 的通信一直没断(比如一个长连接、一路视频流),但流量正好是单向的——一直是 A 发给 C,C 从不回话。
- 这时交换机能学到 A(因为一直收到 A 的帧),但学不到 C(C 从不发帧)
- 如果 C 的表项恰好被老化删掉 → A 发给 C 的帧全部变成未知单播,全部泛洪
- 而且这个状态会一直持续(因为没有新的帧去重新学到 C)
监控摄像头往服务器推流、单向的日志上传、只有下行没有上行的组播转单播场景——都可能掉进这个状态: 带宽看着没满,但同网段所有设备都在被动收下并丢弃大量不属于自己的帧。
3. 表装不下 / 表被人灌满
- MAC 表有容量上限(家用几 K 条、机房几十万条,收 5.9)。表满了之后新号学不进去,一切新出现的目的是未知单播 → 泛洪
- MAC 泛洪攻击(MAC flooding):攻击者伪造大量源 MAC 拼命发包,把表灌满 → 交换机退化成集线器 → 攻击者所在网段能抓到所有人的流量(这正是泛洪的"攻击面")
三、泛洪到底怎么发
机制本身只有四句话,但每句都有来头:
① 除入端口外,所有口各送一份。
不能送回原路——帧的来路上那台设备刚发过这帧,它不需要再收一遍。所以"泛洪"是 N − 1 份,不是 N 份(N=交换机口数)。
② 泛洪的边界=广播域边界。 泛洪到广播域为止,不会自己跨过去(收 5.9):
- 不跨 VLAN(VLAN 之间逻辑上是两台独立交换机)
- 不跨路由器(路由器收到广播域里的泛洪帧,不会把它继续往外送)
所以前面反复出现的那句话在这里有了新读法:"划 VLAN 能隔离广播",其实同时也在隔离泛洪——因为泛洪域=广播域,是同一个圈。
③ 送出去的是原封不动的同一帧。 交换机是透明设备(收 5.9):泛洪出来的每一份,目的 MAC、源 MAC、数据一个字节都不改,就是同一帧被复制了几份、从不同口送出去。
路由器每过一跳换一整套 MAC 头(收 3.2);交换机泛洪一个字节都不改。 所以抓包时看到"同一个源 MAC 的帧出现在多个口"=泛洪;如果 MAC 头被换了,那才说明过了一次路由。
④ 泛洪的同时,源 MAC 照样被学会。 这是最容易忽略、也最关键的一点:发帧那一刻,交换机就顺手把"源 MAC ↔ 入端口"记进表了(收 5.9 的"先学源、再查目的")。
于是对方回包时就已经是定向的了——这正是下一节要讲的"泛洪只发生在第一次"。
四、泛洪的代价:为什么它值得单开一节
泛洪不是错误,是机制的必要代价。但要清楚它贵在哪儿:
| 代价 | 具体表现 |
|---|---|
| 带宽浪费 | 一份帧变成 N − 1 份,其中只有 1 份有用,其余全部是白烧的线路资源 |
| 打扰所有设备 | 每个口上的设备都要收下整帧 → 看目的 MAC → 不是自己的 → 丢掉,这是一次无谓的 CPU 中断(无线终端尤其敏感,这是"Wi-Fi 一卡全体卡"的成因之一 收 5.1) |
| 挤占交换机队列 | 泛洪出来的帧同样进队列;量大了会触发尾丢弃(收 5.10)——而且丢了不通知任何人 |
| 安全漏点 | 泛洪会把帧送到它本来不该去的地方:同广播域里任何主机(只要把网卡设成混杂模式)都可能嗅探到别人的流量 |
| 放大会引发风暴 | 环路存在时,泛洪帧会绕圈增殖 → 广播风暴(收 5.7)——这也是 STP 必须开的原因 |
很多人以为"交换机天生隔离流量",所以同一个交换机下抓不到别人的包。 但未知单播泛洪(以及广播、组播泛洪)恰恰是漏点:抓不到是常态,抓得到也完全可能。 "用交换机就等于安全"是错觉——要真隔离,得靠 VLAN + 端口隔离 + 802.1X(收 5.3)。
五、怎么把泛洪压下去
按"从便宜到费钱"排:
| 手段 | 做法 | 效果与注意 |
|---|---|---|
| 让表学全 | 让每台设备都定期发点帧(保活、ARP、心跳) | 最根本。双向有流量,表就不会老 |
| 调老化时间 | 把 aging time 调长 | 少泛洪,但表占得久、设备换口后可能短暂送错口 |
| VLAN 划小 | 把大二层拆成多个小 VLAN(收 5.3) | 泛洪域变小,泛洪的影响半径直接缩小——这是划 VLAN 最实在的收益之一 |
| 端口安全 port security | 限制每个口能学几个 MAC | 防MAC 泛洪攻击,也顺手挡住私接小交换机 |
| 未知单播抑制 / 风暴控制 | 超过阈值就丢或告警 | 有代价:真用户的第一个包也可能被丢(他正好是"未知"的),所以一般设阈值而不是禁用 |
| IGMP snooping | 让组播只发给要的人(收 3.9) | 只解决组播那一部分,不解决单播 |
泛洪是"交换机用带宽换取"我不用维护任何路由信息"的代价。 路由器要跑路由协议、要交换拓扑信息,但换来的是"知道该往哪送";交换机什么协议都不用跑(插上就通),代价就是"不认识的到处送"。 没有免费的午餐,只是把复杂度放在了不同的地方——这正是 5.7 那句"星型把麻烦搬进中心那台设备"的又一次现身。
六、和 ARP 的关系:真实网络里的"第一次"
理论归理论,真实网络里几乎不会出现"裸的未知单播泛洪",因为有个天然的"预热器"——ARP(收 3.16):
- A 想给 C 发数据,但只知道 C 的 IP,不知道 MAC → 先发 ARP 请求
- ARP 请求是广播帧(目的
FF:FF:FF:FF:FF:FF)→ 交换机泛洪 - C 收到并回 ARP 应答(单播)→ 交换机顺手学到 C 在哪个口
- 于是 A 真正要发的那个数据帧一出门,已经是已知单播了
ARP 广播把表填好 → 数据帧直接就定向。 反过来说:如果 ARP 缓存还有效(主机侧没超时),但交换机的 MAC 表已经老化删掉了,那么数据帧一出门就是未知单播——主机侧一切正常,网络上却在泛洪。 这就是"为什么查泛洪要看交换机,而不是看电脑"。
顺带一个实用推论:ping 的第一个包往往比后面几个慢一点(差几毫秒到几十毫秒)。原因常常就是这一趟触发了 ARP 广播 + 泛洪,而不是"网络刚开始不稳定"。
七、动手 Demo:亲手制造一次未知单播
目标:让一台电脑在几秒内"变成陌生设备",看交换机的反应,并把 MAC 表的前后变化对上。
第 1 步:先看清"现在表里有什么"(主机侧视角)
arp -a
你会看到一个 IP ↔ MAC 的邻居列表。先把它截屏或抄下来——这是"主机记得谁",跟交换机的 MAC 表不是一回事,但变化趋势一致。
第 2 步:把本机的 ARP 缓存清空(需要管理员权限的终端)
netsh interface ip delete arpcache
清完再 arp -a,会只剩很少几条(甚至只剩网关)。
第 3 步:去 ping 一台同网段的真机(用 IP,不要用主机名)
ping -n 5 192.168.1.x
盯住第一个包的时间。常见现象:第一个包明显比后几个慢(甚至偶尔"请求超时"一次),后面就平稳了。 第一个包慢的那一下,就是 ARP 广播 + 泛洪在填表。
第 4 步:再看一眼 ARP 表
arp -a
目标设备的记录回来了——这是你这台电脑学会了它。对应的交换机那边,是交换机从 ARP 应答里学会了它。
第 5 步:去交换机 / 家用路由器上找"MAC 地址表"
- 家用路由器:管理页里通常叫「已连接设备」「DHCP 客户端列表」「终端管理」,能看到"IP — MAC — 接口/端口"
- 网管型交换机:命令行 show mac address-table,或管理页的「MAC 地址表 / 转发表」
对照一下:列表里有它的 MAC 吗? 有 → 之后 A 发给它的帧是定向的;没有 → 还在泛洪。
第 6 步:抓包看"广播"和"单播"的区别(可选,但很值)
用 Wireshark 抓几分钟,过滤 arp:
- 请求:Destination: ff:ff:ff:ff:ff:ff —— 这是广播,被泛洪
- 应答:Destination: 你那台电脑的 MAC —— 这是单播,定向回来
两句话在同一屏里,正好把本节讲的东西摆出来。
第 7 步(进阶,两台电脑更直观):A 发帧时,在 C 上抓 如果 C 能抓到"A 发给 B"的帧——说明它被泛洪了(或者是广播/组播)。 抓不到——说明交换机早就认识 B,定向送出去了。 这就是"用抓包判断泛洪"的实战方法:泛洪没法从单帧本身看出来,只能从"它出现在几个口"看出来。
第 8 步:制造一次"老化"(有时间就试) 让一台手机 / 电脑长时间静默(比如手机息屏几十分钟、或直接断开再连上),再 ping 它。 老化的表项(默认约 300 秒)已经不在表里——这一次的包又是从泛洪开始。
第 9 步:可选,看邻居表的状态机
Get-NetNeighbor -AddressFamily IPv4 | Format-Table IPAddress, LinkLayerAddress, State
PowerShell 里能直接看到 Reachable / Stale / Incomplete 这些状态——
Incomplete 就是"我发了 ARP 还没人应答"(对应的 ping 会失败),Stale 就是"这条记录旧了、要用的时候得先确认一下"。
"第一个包慢、后面快" → 正常(在填表);"一直慢、每包都慢" → 不是泛洪,去查别处(丢包、环路、双工、无线干扰)。 泛洪是一次性开销,它不会让每个包都慢——能让每个包都慢的,是别的原因。
八、30 秒实验:让泛洪一直发生
找一个同网段里确定没人的 IP(比如 192.168.1.88),持续 ping:
ping -n 5 192.168.1.88
你会看到:5 个包全部"请求超时",而网络里一直在广播。
为什么它永远不会被学会?
- 这个 IP 上没有人,没人回 ARP 应答
- 交换机学不到 → 每一次 ping 的 ARP 请求都只能泛洪
- 只要对方不回话,"未知"这个状态就永远不会消失
对比一下刚才那台真机:两三次之后它就从"未知"变成"已知"了。
结论一句话:泛洪会不会停,取决于"对方有没有回话"。 这也是"单向流量引发长期泛洪"那类故障的根源——只收不发的设备,在交换机眼里永远是陌生的。
九、常见误区
- 把"未知单播"当成广播。 目的 MAC 写的是一个具体设备,只是交换机不认路。它是"被误当成广播处理"的单播,不是广播。
- 以为泛洪是发送方的行为。 泛洪是交换机的兜底动作;发送方要求"发给所有人"才是广播(收 5.9)。
- 以为泛洪只发生在开机那一刻。 老化、单向流量、表满、MAC 泛洪攻击,都会让它重来。
- 以为"表里没学到"是自己电脑的问题。 那只表在交换机里,
arp -a看到的是主机自己的邻居表,两者不是一回事(收 3.16)。 - 以为同一个交换机下抓不到别人的包。 泛洪(单播 / 广播 / 组播三种都有)就是漏点,"交换机=安全"是错觉。
- 以为泛洪能跨 VLAN / 跨路由器。 泛洪到广播域边界为止,和广播同一个圈。
- 以为"未知单播抑制"是纯赚。 它可能丢掉真用户的第一个包——他恰好是"未知"的那一个。
- 以为泛洪一定说明网络有问题。 它是机制的正常代价,只有量大、持续、无端增长时才值得追。
- 以为"ping 第一个包慢"是网络不稳。 那通常是 ARP + 泛洪在填表,属于正常。
- 以为泛洪会重传。 多出来的那些份数被丢掉时,交换机不通知、也不重传——补上是 TCP 的事(收 3.18)。
十、动手自测
- "未知单播帧"里,"单播"和"未知"分别说的是什么?
- 交换机收到一帧,动作有哪三种?分别对应什么条件?
- "未知"有哪三个来源?
- 为什么泛洪是送
N − 1份而不是N份? - 泛洪的范围到哪儿为止?为什么"划 VLAN"能压住泛洪?
- 为什么 A 发的帧能不能定向,取决于 C 之前有没有发过帧?
- 什么叫"单向流量引发的长期泛洪"?怎么修?
- ARP 和未知单播泛洪是什么关系?为什么说"泛洪通常只发生在第一次"?
- 抓包时怎么判断一个帧是被泛洪的?
- 怎样才能让泛洪一直发生(做一个 30 秒能验证的实验)?
- 未知单播抑制为什么"不是纯赚"?
答案:
① "单播"说的是目的 MAC 长什么样(指向某一个具体设备,不是全 F、不是组播位);"未知"说的是交换机 MAC 地址表里查不查得到。两者互不相干,合起来叫"未知单播帧"。 ② 定向转发(目的 MAC 是单播且表里查到 → 只从那一个口送)/泛洪(目的 MAC 是单播但表里查不到,或目的是广播 → 除入端口外全部送)/过滤(查出来的口正好是入端口 → 直接丢掉,收 5.9)。 ③ 表里还没有(刚开机、设备刚接入、表项老化)/表项老化了但流量是单向的(学不到对方,一直泛洪)/表装不下或被人灌满(表满、MAC 泛洪攻击)。 ④ 因为入端口那台设备刚发过这一帧,它不需要再收一遍——帧的来路上送回去没有任何意义,所以是"除入端口外"的 N − 1 份。 ⑤ 泛洪到广播域边界为止:不跨 VLAN、不跨路由器。因为泛洪域=广播域是同一个圈,把大二层切成多个小 VLAN,泛洪的影响半径就跟着缩小。 ⑥ 因为交换机是靠收帧来学源 MAC 的(收 5.9):C 任意发过一次帧(哪怕是它自己发的 ARP 或广播),交换机就知道了"C 在哪个口"。所以"A 能不能被定向送到"取决于"C 之前有没有说过话"。 ⑦ 通信是单向的(一直是 A 发给 C,C 从不回话):交换机能学到 A,却学不到 C,C 的表项一旦老化被删,A 发给 C 的帧就全部泛洪且永不恢复。修法:让双向有流量(保活 / 心跳 / 偶尔让 C 也发点东西),或把老化时间调长、把 VLAN 划小。 ⑧ ARP 请求是广播帧,会触发泛洪;而 ARP 应答是单播,它让交换机顺手学到了对方的 MAC。于是 A 真正要发的数据帧出门时已经是已知单播——所以"泛洪通常只发生在第一次"。前提是 ARP 缓存和 MAC 表同时有效;如果主机还有 ARP 记录但交换机表已老化,数据帧出门时就会泛洪。 ⑨ 泛洪没法从单帧本身看出来(交换机不改帧),只能从"这个帧出现在几个口"看出来:如果在目的主机以外的口也抓到了同一个帧,就是泛洪。网管型交换机可以用端口统计或抓包对比来确认。 ⑩ 去 ping 一个同网段里确定没人的 IP(如 192.168.1.88):没人回 ARP 应答 → 表里永远学不到 → 每一次都泛洪。对比 ping 一台真机,两三次后它就变成"已知"了。 ⑪ 因为真用户的第一个包恰恰也是"未知单播"——抑制功能只看"这个目的 MAC 在不在表里",分不清"是攻击"还是"某人刚开始通信",阈值设低了就会把正常流量一起丢掉(表现为"偶尔第一次连不上、重试就好")。
十一、下一步学什么
- ☑ 5.12 二层交换机的操作(以太帧发送后的MAC地址表的登记) —— 已学完:把"学习"这个动作拆到底——登记的时机(读帧头阶段、比转发决策更早)、为什么只看源 MAC 不看目的 MAC、一行表项的四个字段、登记的三种情形(新增 / 刷新 / 漂移)、哪些帧会登记哪些不会、表怎么被老化与容量养着,以及 MAC 表与主机 ARP 表的对照。见 二层交换机的操作(以太帧发送后的MAC地址表的登记)。
相关笔记
- 二层交换机的操作(以太帧发送后的MAC地址表的登记) —— 下一节:本节说"泛洪的同时源 MAC 照样被学会",下一节讲清这个"学会"具体怎么写进表里
- 二层交换机的操作(二层交换机的数据传输) —— 一帧的旅程里"未命中 → 泛洪"那一步;本节把它展开成一整节
- 创建以太网网络(二层交换机) —— 学习 / 转发 / 泛洪 / 过滤 / 老化五个动作的出处;本节专讲"泛洪"
- 接收方是1个还是多个(单播、广播、组播) —— 三种收件形态;本节给判据加了第二维:"表里有没有"
- 将IP地址与MAC地址对应(ARP) —— ARP 请求是广播、应答是单播;正是这一对把 MAC 表填好的
- 接口是哪个(MAC地址) —— MAC 扁平无结构;所以交换机只能建表查表,查不到就只能到处送
- 数据的格式(以太网的数据帧格式) —— 目的 MAC 字段就是交换机看的"路牌";泛洪送出的每一份都原封不动
- 如何连接(网络拓扑) —— 环路 + 泛洪 = 广播风暴;泛洪放大是风暴的燃料
- 负责传输数据的以太网(以太网概要) —— 广播帧从除来源口外所有口送出;本节补上"单播帧也会被这样送"
- 对应用程序的数据进行可靠传输(TCP) —— 泛洪多出来的份数被丢掉时无人通知,可靠性由 TCP 兜底
- 审核公司员工浏览的Web网站(代理服务器的用途) —— 上网审计;同网段能抓到别人流量,泛洪是漏点之一
- 用于构建网络的设备(网络设备) —— 设备=层的肉身;交换机只看帧头,所以"认不认识路"全靠一张表