IGMP 是Internet Group Management Protocol(互联网组管理协议)的简称。它是TCP/IP 协议族中负责IP 组播成员管理的协议,用来在IP主机和与其直接相邻的组播路由器之间建立、维护组播组成员关系。
IGMP协议(IPv4) 和MLD协议(IPv6)用来帮助主机指定对那些组感兴趣(加入哪一些多播组),以及确定来自某些特定源的报文应该被接收还是过滤掉。为了实现这一目标,主机需要向本地子网的组播路由器发送一些报文来向组播路由器交互一些多播成员关系管理的信息。
组播使用了D类IP地址,IP地址的范围为224.0.0.0-239.255.255.255。其中224.0.0.1代表子网上的所有计算机,224.0.0.2代表子网上的所有路由器。另外,多播ip地址只可作为目的地址,而且不能生成关于多播地址的差错报文。
IGMP的mac地址为01-00-5e-xx-xx-xx,其中后23bits是ip地址的低23bits。从这也说明了只要知道一个多播ip地址,即可换算出其mac地址,不需要通过arp请求获取mac地址。
IGMP协议到目前已经有三个版本:
其中MembershipQuery分为三种:General Query,用于查询接口下所有多播成员信息;Group-Specific Query,用于查询接口下指定组的成员信息; Group-and-Source-Specific Query,该类型为IGMPv3中新增加的,用于查询接口下是否有成员需要接收指定源列表中的源所发出的特定组的多播流。
区别是:
简而言之:IGMP 各版本区别v1无离开信息,v2有离开信息,v3允许主机指定它要接收通信流量的主机对象。IGMPSnooping(窥探)监听IGMP协议包,形成组播成员关系表;IGMP Proxy(代理)是靠拦截用户和路由器之间的IGMP报文建立组播表。
在具体实现功能时,又分为IGMP SNOOPING与IGMP PROXY两种。
对于IGMP SNOOPING这是在二层实现组播数据限制的一个功能。对于一个路由器或者2层switch,当lan层的一个端口发送一个IGMP report报文加入一个组播组后,如果没有开启IGMP SNOOPING,则数据会flood到所有lan側端口,这样会增加网络负载。如果开启了IGMP SNOOPING,路由器或者2层switch就会分析IGMP报文,为端口和IGMP组播组地址建立映射关系,这样下行的组播流数据就只会转发到加入组播组的端口,而不会flood到所有桥端口。
对于IGMP PROXY,主要是拦截lan側pc发送的igmp报文,其在wan側作为客户端相应上行路由的查询操作,而在lan側则作为服务端定期发送查询报文。
当lan側加入的组播组在IGMP PROXY设备上没有相应的组播路由时,才会给上层发送组播加入报文,当lan側加入的组播组在IGMP PROXY设备上已经存在时,则无需再将加入报文转发出去。这样不仅能够达到有效抑制二层组播泛滥的问题,且能更有效的获取和控制用户信息,降低网络负载。
报文首部
*ver:*版本
* Checksum:* 校验和
* Group Address:* 组播组地址
报文首部
IGMPv2报文首部兼容IGMPv1报文首部 。
*Type*:
*Max Rsp Code*: 最大响应时间,缺省10s(以0.1s为单位)
*Checksum*: 校验和
*Group Address*: 组播组地址
*Type* :
*Max Rsp Code*:最大响应代码
*S标志*:(禁止路由器处理),禁止任何接收路由器更新它们在收到查询时要更新 的那些 定时器(通常设为0)
*QRV*:查询者健壮变量(<=7)
*QQIC*:查询者查询间隔代码
注:
IGMPv3的报告报文兼容IGMPv1、和IGMPv2的报告报文。
*Type*:报告类型
*Reserved*:保留
*CheckSum*:检验和
*Reserved*:保留
*Num of Grp Records*: 多播组记录的数目。
*Group Record*: 多播组记录,其格式如下所示
*Records Type*: 记录类型
Record Type | 名称 | 含义 | 何时发送 |
0x1 | IS_IN | MODE_IS_INCLUDE:来自相关源地址的报文不应该被过滤掉 | 用于应答多播路由器的查询报文 |
0x2 | IS_EX | MODE_IS_EXCLUDE:来自相关源地址的报文应该被过滤掉 | 用于应答多播路由器的查询报文 |
0x3 | TO_IN | CHANGE_TO_INCLUDE_MODE:来自相关源地址的报文不应该被过滤掉 | 本地应用程序过滤状态发生变化 |
0x4 | TO_EX | CHANGE_TO_EXCLUDE_MODE:来自相关源地址的报文应该被过滤掉 | 本地应用程序过滤状态发生变化 |
0x5 | ALLOW | ALLOW_NEW_SOURCES:来自相关源地址的报文不应该被过滤掉 | 多播源地址列表发生变化 |
0x6 | BLOCK | BLOCK_OLD_SOURCES:来自相关源地址的报文应该被过滤掉 | 多播源地址列表发生变化 |
我们可以看到 Record Type为 0x01、0x02时,记录表示的是一种当前的状态,即主机当前对某种组播感兴趣;0x03、0x04主要是翻译了对某种组播是否感兴趣的状态发生的变化;0x05,0x06则是表示源地址列表发生了变化。
我们知道,多播路由器会定时发送查询报文,这是主机在应答时发送的报告报文的记录类型就是0x01、0x02这两种记录。 如果主机因自身对多播组的兴趣发生变话,而主动发送报告报文,那么报文的记录类型就是0x03、0x04、0x05、0x06这几种,具体是哪一种取决于主机对多播组的兴趣发生了怎么样的变化。
*Aux Data Type*:辅助数据类型
*Num of Sources*: 多播源地址列表的数据。
*Multicast Address*: 多播组地址
*Sources Address*: 多播源地址列表
*Auxiliary Data*:辅助数据
在前面介绍IGMPv3的报文时,在Group Record时,可以看到,Record Type有许多中类型,IS_IN、IS_EX、TO_IN、TO_EX、ALLOW、BLOCK。这里我们关注下IS_IN、IS_EX、TO_IN、TO_EX这四种Mode(其实是两对)。我们先看IS_IN、IS_EX这一对模式,它们分别表示有主机针对某个组播来自特定源的流量感兴趣,以及本地子网对某个组播来自特定源的流量不感兴趣。事实上,任何可以用IS_EX组播表示的成员关系,也都可以用对应的IS_IN表示。 比如:IS_EX(ALL)相当于IS_IN(NULL), IS_EX(NULL)相当于IS_IN(ALL), IS_EX(src1,src2)相当于IS_IN(src3,src4…)。同理,所有能以TO_EX表示的成员关系,可以都可以用TO_IN表示。
出于上面的结论,为了使得IGMPv3更加简洁易用,轻量级的IGMPv3遍出现了。首先,IGMPv3应该支持ASM和SSM。先考虑SSM的情况,我们如果要指定组播源,那么这个组播源大多数情况下是属于全体组播源中的少数,所以在指定组播源时,轻量级的IGMPv3不再使用IS_EX(a,b,c…)和TO_EX(a,b,c…), 而都用IS_IN和TO_IN表示。在考虑ASM的情况,由于不指定组播源,如果我们使用IS_IN和TO_IN,那要包含所有的组播源,这样就会导致Report消息太繁重。因此,我们仍然支持IS_EX(NULL)和TO_EX(NULL)来表示ASM。