IGMP 实战与排错 — 互联网组管理协议

Wireshark IGMP 过滤式、ip maddr / smcroute / iperf 组播测试、Snooping 配置与组播收不到流排查 / 网络层 / Protocol=2

这篇你能学到

  • 怎么用 Wireshark / tcpdump 的过滤式,从 igmp 一键捞出查询/报告/离开报文,并确认"到底有没有数据流"而不只是控制报文;
  • ip maddr / smcroute / iperf 怎么测"能不能加组、能不能收到流",以及交换机/路由器侧 Snooping、PIM、RPF 怎么查;
  • “收不到流"“播放几分钟卡死"“组播风暴"等七类故障的排查套路——核心是按"join → Report → Snooping → 组表 → PIM"五段逐段验证。

1. 抓包观察

1.1 Wireshark 显示过滤式

过滤式作用
igmp所有 IGMP 报文(起手式)
igmp.type == 0x11Membership Query(查询器发的,v1/v2/v3 通用)
igmp.type == 0x11 && igmp.maddr == 0.0.0.0通用查询(组地址为 0)
igmp.type == 0x11 && igmp.maddr != 0.0.0.0特定组查询(收到 Leave 后触发)
igmp.type == 0x12IGMPv1 Report
igmp.type == 0x16IGMPv2 Report(加入组)
igmp.type == 0x17Leave Group(v2 离开)
igmp.type == 0x22IGMPv3 Report
igmp.maddr == 239.1.1.1追踪某个具体组的全部 IGMP 活动
igmp.max_resp查看最大响应时间(判断查询器配置)
igmp.record_type == 3v3 的 CHANGE_TO_INCLUDE_MODE空源列表即离开
igmp.record_type == 4v3 的 CHANGE_TO_EXCLUDE_MODE
igmp.num_src > 0带源过滤的 v3 报文
ip.dst == 224.0.0.1通用查询的目的地址
ip.dst == 224.0.0.2v2 Leave 的目的地址
ip.dst == 224.0.0.22IGMPv3 报告的固定目的地址
ip.dst == 239.1.1.1 && udp实际的组播数据流(区别于 IGMP 控制报文)
ip.proto == 2从 IP 层维度确认 IGMP 存在
icmpv6.type >= 130 && icmpv6.type <= 132IPv6 的 MLD(v1)
icmpv6.type == 143MLDv2 报告

捕获过滤式(BPF)igmpip proto 2host 239.1.1.1net 224.0.0.0/4

1.2 典型字段判读

一次通用查询

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 224.0.0.1
    Time to Live: 1 ← 恒为 1,仅本链路
    Protocol: IGMP (2)
    Options: Router Alert ← 强制路由器上送处理
Internet Group Management Protocol
    [IGMP Version: 2]
    Type: Membership Query (0x11)
    Max Resp Time: 10.0 sec (0x64) ← 主机在 0~10 秒内随机响应
    Checksum: 0xee9b [correct]
    Multicast Address: 0.0.0.0 ← 0 表示通用查询

一次 IGMPv3 报告

1
2
3
4
5
6
7
8
9
Internet Protocol Version 4, Src: 192.168.1.10, Dst: 224.0.0.22
Internet Group Management Protocol
    Type: Membership Report (0x22)
    Num Group Records: 1
    Group Record : 239.1.1.1 Change To Include Mode
        Record Type: Change To Include Mode (3)
        Num Src: 1
        Multicast Address: 239.1.1.1
        Source Address: 10.0.0.1 ← 只接收此源,SSM 特征

排障时的四个观察点

  1. 有没有 Query? 没有 → 网段缺查询器,成员表会老化 → 组播中断。
  2. 有没有 Report? 没有 → 主机侧没 join,或应用绑错网卡。
  3. Report 之后有没有数据流? 有 Report 无数据 → 问题在上游(PIM/源)。
  4. 数据流是只到成员端口还是全 VLAN 泛洪? 泛洪 → Snooping 未生效。

2. 常用命令 / 配置

2.1 查看组播成员与路由(Linux)

这些命令能干什么:回答"本机到底 join 了哪些组、内核 IGMP 状态如何、组播路由表有没有建起来”。ip maddr shownetstat -g 是最常用的两端核实手段;/proc/net/igmp/proc/net/mcfilter 则能看到内核视角的组与源过滤。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 查看各接口加入的组播组(最常用)
ip maddr show
ip maddr show dev eth0

# 传统方式,同样查看组成员
netstat -g
cat /proc/net/igmp # 内核 IGMP 状态,含组地址与引用计数
cat /proc/net/mcfilter # IGMPv3 源过滤列表
cat /proc/net/dev_mcast # 网卡层面的组播 MAC 过滤表

# 手工加入/离开组播组(测试用)
ip maddr add 01:00:5e:01:01:01 dev eth0 # 二层组播 MAC
ip maddr del 01:00:5e:01:01:01 dev eth0

# 组播路由表(需组播路由守护进程)
ip mroute show
netstat -gn

# 添加组播路由(让组播流量走指定接口)
ip route add 224.0.0.0/4 dev eth0

2.2 组播收发测试

这些命令能干什么:真正"发一路、收一路"验证端到端组播是否通。iperf 最方便;socat 适合脚本化;smcroute 能在没有组播路由守护进程时手工加组、加转发规则,常作为排错利器。注意发送端 TTL 必须 >1 才能跨网段(默认 1 只能本网段)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ── iperf 方式(最方便)──
# 接收端(订阅 239.1.1.1:5001)
iperf -s -u -B 239.1.1.1 -i 1 -p 5001
# 发送端(TTL 必须 >1 才能跨网段!默认 1 只能本网段)
iperf -c 239.1.1.1 -u -T 32 -t 60 -i 1 -b 5M -p 5001

# ── socat 方式 ──
# 接收
socat UDP4-RECVFROM:5001,ip-add-membership=239.1.1.1:eth0,fork -
# 发送
echo "hello multicast" | socat - UDP4-DATAGRAM:239.1.1.1:5001,ip-multicast-ttl=32

# ── smcroute(静态组播路由/加组工具)──
sudo smcroutectl join eth0 239.1.1.1 # 让接口加入组,触发 IGMP Report
sudo smcroutectl leave eth0 239.1.1.1
sudo smcroutectl add eth0 10.0.0.1 239.1.1.1 eth1 # 静态组播转发规则
sudo smcroutectl show

# ── ping 组播地址(探测本链路成员)──
ping -c 3 -I eth0 224.0.0.1 # 所有主机应答
ping -c 3 -I eth0 224.0.0.2 # 所有组播路由器应答
ping -c 3 -I eth0 239.1.1.1 # 该组成员应答

2.3 抓包

这些命令能干什么:在网卡层面"听诊"真实 IGMP 与组播流。tcpdump 的 igmpip proto 2net 224.0.0.0/4 能分别按协议、按网段抓;最后那行 udp and dst 239.1.1.1 用来确认"到底有没有收到真正的数据流”,而不只是 IGMP 控制报文。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sudo tcpdump -i eth0 -nn igmp
sudo tcpdump -i eth0 -nn -v 'ip proto 2'
sudo tcpdump -i eth0 -nn 'host 239.1.1.1' # 组播数据 + IGMP 一起抓
sudo tcpdump -i eth0 -nn 'net 224.0.0.0/4' # 所有组播流量
sudo tcpdump -i eth0 -nn -v 'igmp' -w igmp.pcap

# 统计各类 IGMP 报文数量
tshark -r igmp.pcap -T fields -e igmp.type | sort | uniq -c

# 确认是否真的收到了组播数据流(而不只是控制报文)
sudo tcpdump -i eth0 -nn -c 20 'udp and dst 239.1.1.1'

2.4 内核参数

这些参数能干什么:调整主机侧组播行为——开启组播转发(做路由器时要)、强制 IGMP 版本排查兼容性、igmp_max_memberships/igmp_max_msf 在大量订阅或源过滤时调大上限、关掉 rp_filter 避免 RPF 把组播包误丢。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 允许接收组播(默认开启)
sysctl net.ipv4.conf.eth0.mc_forwarding # 组播转发(做路由器时需要)
sysctl -w net.ipv4.conf.all.mc_forwarding=1

# 强制指定 IGMP 版本(排查兼容性问题时很有用)
sysctl -w net.ipv4.conf.eth0.force_igmp_version=2 # 0=自动, 1/2/3=强制版本

# 组播组数量上限(大量订阅时可能需要调大)
sysctl net.ipv4.igmp_max_memberships # 默认 20
sysctl -w net.ipv4.igmp_max_memberships=200
sysctl net.ipv4.igmp_max_msf # 每组源过滤条目上限,默认 10

# 反向路径过滤:组播场景常因 RPF 检查失败丢包
sysctl -w net.ipv4.conf.all.rp_filter=0

2.5 交换机 / 路由器配置(Cisco 风格)

这份配置能干什么:三层侧把组播路由 + PIM + IGMP 版本/定时器配好(ASM 需 RP,SSM 启用 232/8);二层侧把 IGMP Snooping 打开——其中 querier 在纯二层网段必须配,否则 Snooping 会退化为泛洪。下面一排 show 命令就是排错时逐段核实的"照妖镜”。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
! ── 三层:启用组播路由与 PIM ──
ip multicast-routing
interface Vlan10
 ip address 192.168.10.1 255.255.255.0
 ip pim sparse-mode ! 或 ssm / dense-mode
 ip igmp version 3 ! 指定 IGMP 版本
 ip igmp query-interval 125
 ip igmp last-member-query-interval 1000
ip pim rp-address 10.0.0.100 ! ASM 需要 RP
ip pim ssm default ! 启用 SSM(232.0.0.0/8)

! ── 二层:IGMP Snooping ──
ip igmp snooping ! 全局开启(多数设备默认开)
ip igmp snooping vlan 10
ip igmp snooping vlan 10 querier ! 纯二层网段必须配ip igmp snooping vlan 10 querier address 192.168.10.254
ip igmp snooping vlan 10 immediate-leave ! Fast Leave,仅端口下单用户时启用
ip igmp snooping vlan 10 mrouter interface Gi0/1 ! 手工指定路由器端口

! ── 排错命令 ──
show ip igmp groups ! 组成员表show ip igmp interface Vlan10 ! 查询器身份、版本、定时器
show ip igmp snooping groups ! 二层组 ↔ 端口映射
show ip igmp snooping mrouter ! 路由器端口
show ip mroute ! 组播路由表 (S,G)/(*,G)
show ip mroute count ! 各组流量统计(判断是否真有流)
show ip pim neighbor
show ip rpf 10.0.0.1 ! RPF 检查,组播丢包高频根因
debug ip igmp

2.6 Windows

Windows 上的对应命令能干什么:和 Linux 思路一致——netsh interface ipv4 show joins 看本机 join 了哪些组、route print -4 | Select-String "224" 看组播路由,用来确认订阅与路由侧是否就绪。

1
2
3
4
netsh interface ipv4 show joins # 查看已加入的组播组
netsh interface ipv4 show global # 查看组播转发状态
Get-NetIPAddress -AddressFamily IPv4
route print -4 | Select-String "224"

3. 常见故障与排错

3.1 排障主线:五段验证法

先记住结论:组播链路比单播长得多,任何"收不到流"都不要一上来就怀疑网络——必须逐段定位,哪一段断了,问题就在那一段与前一段之间。这五段是从应用到源头的完整链路。

1
2
3
4
5
① 应用是否 join? → ip maddr show / netstat -g,看组是否在列
② 主机是否发出 IGMP Report?→ tcpdump -i eth0 igmp
③ 交换机 Snooping 是否学到?→ show ip igmp snooping groups
④ 路由器是否建立组成员? → show ip igmp groups
⑤ 上游 PIM 是否拉到流? → show ip mroute / show ip mroute count

哪一段断了,问题就在那一段与前一段之间。

3.2 现象:接收端收不到组播流

先记住结论:收不到流,根因八成不在"网络断",而在 join 错了网卡、或发送端 TTL 还是默认的 1(跨不了网段)、或 RPF 把包丢了、或根本没有查询器。按表里逐项核,比瞎猜快得多。

可能原因排查方法
应用绑到了错误网卡(多网卡机器最常见)ip maddr show 看组挂在哪个接口;应用需显式 IP_MULTICAST_IF / setsockopt 指定接口
发送端 TTL=1,跨不了网段组播 socket 默认 TTL=1!需 IP_MULTICAST_TTL 设为 32/64;iperf -T 32
RPF 检查失败show ip rpf <源IP>:若到源的单播路由不经过收到组播包的那个接口,组播包会被丢弃。需修正单播路由或配静态 mroute
路由器未启用组播路由 / PIMshow ip pim interfaceshow ip mroute 是否有 (*,G) 表项
无查询器,组成员老化show ip igmp interface 看 Querier 是谁;纯二层需配 Snooping Querier
IGMP 版本不匹配主机 v3、路由器 v2 → sysctl force_igmp_version=2 或统一版本
防火墙拦截 IGMP 或组播 UDPiptables -L -n -v,需放行 ip proto 2 与目标组播地址的 UDP
Linux rp_filter 丢包sysctl -w net.ipv4.conf.all.rp_filter=0
SSM 场景用了非 IGMPv3SSM 必须 v3;否则配 SSM Mapping

3.3 现象:组播播放几分钟后卡住/中断,重启应用又好

先记住结论:这是 “缺查询器"的经典症状——首次 join 的报告建了表项,但没人周期性发通用查询,主机就不再续订,260 秒后表项老化、转发停止;重启应用又发一次报告,于是好几分钟、再卡死,循环往复。所以看到"卡死但重启就好”,第一反应就去查查询器。

典型根因:网段内没有查询器。

主机 join 时发的非请求报告让路由器/交换机建立了表项,但此后无人发通用查询,主机也就不再发续订报告,260 秒后表项老化,转发停止。重启应用会重新发一次报告,于是又好几分钟——现象非常有迷惑性。

排查tcpdump -i eth0 'igmp and ip dst 224.0.0.1' 观察 125 秒内有无查询;show ip igmp interface 看 Querier。

处置:三层网段确保路由器启用 IGMP;纯二层网段在交换机上配置 ip igmp snooping vlan X querier

3.4 现象:组播在整个 VLAN 内泛洪,非成员端口也收到大量流量

先记住结论:整 VLAN 泛洪,几乎都是 IGMP Snooping 没真正生效(没开、没识别到路由器端口),或这个地址本来就落在 224.0.0.0/24(按 RFC 4541 必须泛洪、属正常)。先确认是不是 Snooping 退化成了泛洪。

原因:IGMP Snooping 未启用、未识别到路由器端口,或组播地址落在 224.0.0.0/24(该段按 RFC 4541 必须泛洪,属正常行为)。

排查show ip igmp snoopingshow ip igmp snooping mrouter;抓包看非成员端口是否收到 239.x.x.x 的 UDP 流。

处置:启用 Snooping;确保有查询器(没有查询器时很多交换机的 Snooping 会退化为泛洪);必要时手工指定 mrouter 端口。

3.5 现象:接收端已离开,组播流仍持续占用带宽

先记住结论:离开了还转发,要么是 v1 根本没离开机制(只能等 260 秒老化)、要么是同网段还有别人在收(特定组查询后有人响应本就该继续)。只有"单用户端口 + 没开 Fast Leave"才会显得切换台慢。

原因排查与处置
用的是 IGMPv1(无离开机制)只能等 260 秒老化;升级到 v2/v3
主机异常退出,未发 Leave属正常老化过程;可调小定时器缩短窗口
Snooping 的 Fast Leave 未启用,切换台慢IPTV 场景启用 immediate-leave前提:端口下只有一个用户,否则会误删其他人的订阅)
同网段还有其他成员特定组查询后有人响应,本就应继续转发;show ip igmp groups 确认还有谁

3.6 现象:CPU 高、组播风暴

先记住结论:组播风暴的根因通常是 Snooping 没开导致全网泛洪,或 组播 MAC 32:1 重叠让网卡收到大量无关帧由 CPU 过滤,或恶意源高速灌流。量大时还要注意"大量主机同时响应查询"——v3 取消了报告抑制,成员多时更需靠随机延迟摊平。

原因处置
Snooping 未开导致全网泛洪启用 IGMP Snooping
组播 MAC 32:1 重叠,网卡收到大量无关帧后由 CPU 过滤重新规划组地址,避免低 23 位冲突
恶意/异常源持续发送高速组播用 IGMPv3 源过滤或 ACL 限制;启用组播风暴抑制(storm-control)
大量主机同时响应查询调大 Max Response Time,利用随机延迟摊平(v1/v2 有报告抑制,v3 无,成员多时更需注意)

3.7 现象:跨网段收不到,同网段正常

先记住结论:同网段能收、跨网段收不到,第一嫌疑永远是 发送端组播 TTL 还是默认的 1(它只允许本网段);其次才是路由器没开组播路由/PIM、RPF 没过、ASM 缺 RP、或用的组地址落在永不跨网段的 224.0.0.0/24

排查方向:① 发送端组播 TTL 是否 >1(默认 1 是最常见的坑);② 路由器是否 ip multicast-routing + 接口 ip pim sparse-mode;③ RPF 检查show ip rpf <源IP>);④ ASM 场景 RP 是否可达(show ip pim rp mapping);⑤ 组地址是否落在 224.0.0.0/24该段永不跨网段转发,用它测跨网段必然失败)。

4. 与其他协议对比

维度IGMPMLD(IPv6)PIMICMPIGMP Snooping
所属层网络层(IP Proto=2)网络层(ICMPv6 的一部分,Type 130-132/143)网络层(IP Proto=103)网络层(IP Proto=1)数据链路层(二层特性,非独立协议)
作用范围主机 ↔ 第一跳路由器(一跳)同 IGMP路由器 ↔ 路由器(跨网络)端到端 / 逐跳交换机内部
职责组成员订阅与维护IPv6 组成员管理构建组播分发树差错报告与诊断二层组播端口精确转发
TTL111(Hello)可变
版本对应v1 / v2 / v3MLDv1≈IGMPv2MLDv2≈IGMPv3PIM-DM / SM / SSM / BIDIRv4 / v6随 IGMP 版本
关键 RFC1112 / 2236 / 33762710 / 38107761792 / 44434541
是否需要 RPPIM-SM 需要,PIM-SSM 不需要

IGMP 与 MLD 的对应关系速记IGMPv2 ↔ MLDv1IGMPv3 ↔ MLDv2;最大区别是 MLD 不是独立协议而是 ICMPv6 报文,且用链路本地地址(fe80::/10)作源,组播到 ff02::1(查询)/ff02::16(MLDv2 报告)。

5. 速查表 / 常见面试题

5.1 速查

记忆点
IP Protocol 号2
TTL1(仅本链路)
组播地址范围224.0.0.0/4
通用查询目的224.0.0.1
v2 Leave 目的224.0.0.2
v3 报告目的224.0.0.22
SSM 段 / 企业私用段232.0.0.0/8 / 239.0.0.0/8
组播 MAC 前缀01:00:5E + IP 低 23 位(32:1 重叠
Type 码0x11 查询、0x12 v1报告、0x16 v2报告、0x17 离开、0x22 v3报告
查询间隔 / 组成员间隔125 秒 / 260 秒
最大响应时间默认 10 秒(v2 上限 25.5 秒,v3 约 53 分钟)
查询器选举IP 地址最小者当选(v2/v3)
组播发送 TTL默认 1,跨网段必须调大
排障主线join → Report → Snooping → IGMP 组表 → PIM/mroute

5.2 常见面试题

Q1:IGMP 和 PIM 有什么区别? IGMP 工作在主机与第一跳路由器之间(一跳,TTL=1),负责组成员的订阅与维护;PIM 工作在路由器之间,负责构建组播分发树、把流量从源引到有成员的网段。二者是"接入侧"与"骨干侧"的分工,缺一不可。

Q2:IGMPv2 相比 v1 的核心改进是什么?Leave Group 报文 + 特定组查询 → 实现低离开延迟(v1 只能等 260 秒老化);② 查询器选举(IP 最小者当选,v1 靠组播路由协议指定);③ 最大响应时间可配

Q3:IGMPv3 最重要的能力是什么?为什么需要它? 源过滤(INCLUDE / EXCLUDE)。主机可指定只接收某些源、或排除某些源发往该组的流量。这既是 SSM(RFC 4607) 的必要前提(PIM-SSM 因此无需 RP,架构大幅简化),也能防止恶意源向组内注入伪造流量。此外 v3 一个报告可携带多条 Group Record,报文效率更高。

Q4:IGMPv3 没有 Leave 报文,怎么离开组?CHANGE_TO_INCLUDE_MODE(Record Type = 3)且源列表为空来表达"不再接收任何源的流量",语义上等价于离开。

Q5:组播 IP 如何映射到 MAC?为什么会有地址冲突? 01:00:5E + IP 地址的低 23 位。IP 组播地址有 28 位可变,MAC 只承载 23 位,丢弃 5 位 → 32 个 IP 组播地址映射到同一个 MAC。后果是网卡会收到不该收的帧,需由 IP 层过滤,造成额外 CPU 开销。规划组地址时应避免低 23 位相同。

Q6:为什么 IGMP 报文的 TTL 是 1? IGMP 只用于主机与本网段第一跳路由器之间的通信,不应被转发出去。TTL=1 从协议层面保证这一点,同时报文还携带 Router Alert 选项,确保路由器不会快速转发而是上送 CPU 处理。

Q7:什么是 IGMP Snooping?没有它会怎样? 二层交换机侦听 IGMP 报文,建立"组播组 ↔ 成员端口"映射,只向真正的成员端口转发组播帧。没有它,交换机会把组播帧当未知目的 MAC 在整个 VLAN 内泛洪,三层组播省下的带宽在二层被完全浪费,严重时形成组播风暴。注意 224.0.0.0/24 按 RFC 4541 必须始终泛洪。

Q8:查询器是怎么选出来的?为什么纯二层网段也需要查询器? IGMPv2/v3 中所有组播路由器互发通用查询,IP 地址最小者当选。纯二层网段若无三层设备发查询,主机不会周期性续订报告,交换机/路由器的成员表项会在 260 秒后老化 → 组播中断(现象是"播放几分钟后卡死")。因此需在交换机上启用 IGMP Snooping Querier 充当查询者。

Q9:组播播放几分钟后就断,重启应用又好,为什么? 经典的缺查询器问题。首次 join 的非请求报告建立了表项,但无人发通用查询导致主机不再续订,表项到期(组成员间隔 260 秒)被删除。重启应用会重新发报告,于是循环往复。

Q10:什么是 RPF 检查?为什么它会导致组播丢包? Reverse Path Forwarding 检查:路由器收到组播包时,查到源地址的单播路由,若该路由的出接口不是收到这个包的接口,则丢弃。目的是防止组播环路。当单播路由与实际组播路径不一致(如非对称路由、隧道场景)时会误丢包,需用 show ip rpf <源IP> 确认,并通过修正单播路由或配置静态 mroute 解决。

Q11:Fast Leave(Immediate Leave)什么时候能用? 收到 Leave 后不发特定组查询直接删除端口,用于 IPTV 快速换台。前提是该端口下只连接一个用户;若端口下挂了集线器或多台设备,会误删其他仍在收看用户的订阅。

Q12:ASM 和 SSM 有什么区别? ASM 是 (*, G) 模型——接收任意源发往组 G 的流量,需要 PIM-SM 与 RP(汇聚点),架构复杂且任何源都能注入;SSM 是 (S, G) 模型——只接收指定源 S 的流量,地址段 232.0.0.0/8依赖 IGMPv3 源过滤,无需 RP、直接建最短路径树,安全性与部署简洁性都更好,是 IPTV 与金融行情推送的首选。

Q13:为什么我的组播跨不了网段? 最常见原因是发送端组播 socket 的 TTL 默认为 1,需通过 IP_MULTICAST_TTL 设为 32/64(iperf -T 32)。其次检查路由器是否启用组播路由与 PIM、RPF 是否通过、以及所用组地址是否落在 224.0.0.0/24(该段设计上就永不跨网段)。