IP组播的基本概念
组播面对一对多的通信场景

-
源无需发送多个数据拷贝,仅需发送一份即可
-
只有加入到特定组播组的成员,才会收到组播数据
-
不需要该数据的设备不会收到该组播流量
组播的应用场景
- 用于多接收者期望收取相同流量的场景
- 适用于接收者地址(或位置)未知的场景
- 培训、联合作业场合的通信
- 数据仓库、金融应用(股票)
IP组播的服务模型

从上至下看
- 第一层,组播源向特定组播组发送组播数据,它并不关心组成员的所在
- 第二层,组播路由器把数据拷贝并转发给需要该数据或存在组播接收者的网络分支,路由器上会使用组播路由协议,比如
PIM。当然也会使用组成员管理协议IGMP来跟下层的组员通信 - 第三层,主机加入自己感兴趣的组播组,以便收到发往这些组播组的数据包,组成员用
IGMP协议跟上游通信
其实在路由器到主机之间通常会加上二层交换机,路由器会把组播数据发送到特定的主机中,因为组播数据包中有主机的MAC地址,根据交换机的MAC地址表,可以保证只传到特定的主机。
这里介绍些术语

IP组播MAC跟IP
组播数据包格式如下

IP地址
在IPv4地址空间中,D类地址(224.0.0.0/4)被用于组播,其地址范围为224.0.0.1—239.255.255.254

MAC地址
- 只要是第一个字节的第
0个bit为1则是组播MAC地址 - 组播数据包,目的
IP地址为组播IP地址 - 组播数据包,目的
MAC地址为组播MAC地址,这个组播MAC地址是代表一个特定的组播组的,跟组播IP地址有对应关系,下面会讲映射关系 - 通常的
IPv4组播MAC地址的高24位为01-00-5E。当然还有其他的特殊组播MAC,比如pause帧的目的MAC地址是01-80-C2-00-00-01
MAC跟IP的映射关系
IP地址的后23bit跟MAC地址的后23bit一一对应。通常的组播MAC地址以01-00-5E开头。比如230.20.88.76对应的是01-00-5e-14-58-4c,224.0.1.1对应的是01-00-5E-00-01-01。

从这里看出,一个组播MAC地址可能对应多个组播IP地址,比例为1:32。因为IP地址中丢弃的32bit。
IPv6组播MAC地址的高16位为33-33,低32位为IPv6组播地址的低32位。33-33-11-11-00-01是IPv6组播地址FF01::1111:0001的MAC地址。

这里有个有趣的小故事,为什么是23bit映射

组播路由协议概述
这边主要是讲第二层自己本身运行的一些组播路由协议。对这些组播路由协议,实在是有些复杂,所以这部分略过。主要知道就是这些组播路由协议的主要作用。
- 防环
- 确定组播流量的转发路径,建立一棵组播分发树
- 组播分发树体现在每一台组播路由器上便是
(S,G)或(*,G)的组播转发表项。

IGMP
这部分介绍第三层,主要是IGMP 协议。这个协议用于主机(组播成员)和最后一跳路由器之间,两层都会用到这个协议,IP头部中的TTL通常是1。注意,组播源不需要运行任何组播协议!!!它只需要把组播数据包发出来就行了。

该协议定义了一个网段内主机与组播路由器之间如何维护组成员信息,其作用可以简单概括为
-
路由器通过
IGMP查询网段上是否有组播组的成员。因为默认时路由器是不会向接口下转发组播数据流的,除非该接口上存在组成员。 -
主机使用
IGMP报文向路由器申请加入和退出组播组。
协议
IGMPv2报文采用IP封装,协议号为2,而且TTL字段值通常为1。如下为其报文内容。

- 版本:目前为止,
IGMP有三个版本,IGMPv1(RFC1112),IGMPv2(RFC2236),IGMPv3(RFC3376)。 - 类型:下面会具体介绍,主要有常规查询报文,特定组查询报文,成员关系报告报文,组成员离组报文。
- 最大响应时间:(只在查询报文中设置,在其他报文中为
0x00)是主机用“成员关系报告报文”来响应该查询包的最长等待时间,默认10s,可用igmp max-response-time修改(单位是秒)。 - 组播组地址:
- 普遍组查询报文中,该字段为全
0 - 特定组查询报文中,该字段设置为该组的组播地址
- 成员关系报告或离组报文中,该字段设置为目标组播组地址
- 普遍组查询报文中,该字段为全
类型
这里主要介绍IGMPv2。不过在介绍具体类型之前,需要先介绍下IGMP查询器这个概念。

普遍组/常规查询
-
IGMP查询器周期性地发送常规查询报文,对网络中的所有组播组进行查询。Wireshark中会显示为General Query。 -
路由器使用IGMP常规查询报文向网段中所有主机进行查询,报文目的地址为224.0.0.1,该查询面向所有的组播组,报文中的组地址字段设置为0.0.0.0。网段中的组成员收到查询报文后,需回应
IGMP成员关系报告。 -
如果一台组播路由器在
Multicast Listener Interval超时(默认2*60s+10s=130s)前仍没有收到一个特定子网的Membership Report消息,那么这个路由器将宣布这个子网中没有组员,不再向这个子网发送组播数据。



特定组查询
类型type为0x11,跟前面的普遍组查询,该查询报文面向特定的组播组,用于查询该组播组内是否存在成员。Wireshark中会显示为Group-Specific Query。
- 当
IGMP查询器收到某组播组的成员发出的IGMP离组报文,路由器便会发送IGMP特定组查询报文以便确认该组播组内是否有其他的成员存在。 - 特定组查询报文的目的地址为该发出
IGMP离组报文的主机所在组的组地址。 - 为了避免特定组查询报文被意外丢弃或被损坏导致路由器误以为组内没有成员,查询路由器将缺省间隔
1s连续 发送特定组查询报文,一共会发送2个报文,如果依然没有成员响应,则路由器将认为该组内没有其他成员,它将会删除相关IGMP组表项。
成员关系报告
类型type为0x16,主机向IGMP路由器发送的报告报文,用于申请加入某个组播组或者对查询 报文进行应答。(图中用IGMPv3做举例,问题不大)

- 主机通过
IGMP成员关系报告报文宣布自己成为组播组的成员。 - 报文的目的
IP地址为主机期望加入的组播组地址。 IGMP路由器通过该报文发现直连网段内的组成员。IGMP成员关系报告报文也用于确认IGMP查询器所发送的查询报文。
成员离开报文
类型type为0x17,成员离开组播组时主动向IGMP路由器发送的报文,用于宣告自己离开了某个组播组。 (图中用IGMPv3做举例,问题不大)

- 当组成员离开组播组时,需向网络中泛洪IGMP离组报文,该报文的目的IP地址为224.0.0.2。 相当于发给组播网络路由器中的所有路由器。
- 当
IGMP查询器收到一个离组报文的时候,会向这个组播组发送IGMP特定组查询报文,用于确认该组播组内是否存在其他组成员,如果组内还有其他成员,则这些主机需使用IGMP成员关系报告进行回应,如果一段时间后依然没有任何成员回应,则IGMP查询器认为该网段内不存在这个组播组的任何成员,于是将相关IGMP组表项删除。
关于成员离开,有两种情况。


版本1成员关系报告
用于兼容IGMPv1。
IGMP路由表
对于组播路由器来说,他们会维护一个IGMP路由表。

在linux上如何查看每个网卡接口的多播组成员情况?可以用netstat -g命令。(虽然下面的图显示的都没有什么信息)

或者使用ip maddr show命令可以查看系统中的组播记录。

当然以上信息都是针对我们是receiver,如果自己是组播源sender的话是看不出来的。
后续
后续会上测试代码,并抓包分析。