《TCP/IP详解卷2:实现》笔记--IGMP:Internet组管理协议

IGMP在本地网络上的主机和路由器之间传达组成员信息,路由器定时向所有主机组多播IGMP查询。主机多播IGMP报告报文

以响应查询。

从体系结构的观点来看,IGMP是位于IP上面的运输层协议。它有一个协议号(2),它的报文是由IP数据报承载的。与ICMP

一样,进程通常不直接访问IGMP,但进程可以通过IGMP插口发送和接受IGMP报文。这个特性使得能够把多播选路守护程序

作为用户级进程实现。

下图是Net/3中IGMP协议的整体结构:

《TCP/IP详解卷2:实现》笔记--IGMP:Internet组管理协议_第1张图片

到达的IGMP查询使igmp_input为每个in_multi结构初始化一个递减定时器,该定时器由igmp_fastimo更新,当每个定时器

超时时,igmp_fasttimo调用igmp_sendreport。

当我们创建一个新的in_multi结构时,ip_setmoptions调用igmp_joingroup。igmp_joingroup调用igmp_sendreport来发布

新的组成员信息,使组的定时器能够在短时间内安排第二次通告。igmp_sendreport完成对igmp报文的格式化,并把它传给

ip_output。


1.igmp结构

igmp报文只有8个字节长,结构如下:

《TCP/IP详解卷2:实现》笔记--IGMP:Internet组管理协议_第2张图片

igmp_type包含一个4bit的版本码和一个4bit的类型码,如下图所示:

《TCP/IP详解卷2:实现》笔记--IGMP:Internet组管理协议_第3张图片

igmp报文构造如下:

《TCP/IP详解卷2:实现》笔记--IGMP:Internet组管理协议_第4张图片

Net/3只使用版本1的报文,多播路由器发送1类报文向本地网络上所有主机请求成员关系报告。对1类IGMP报文的响应是

主机的一个2类报文,报告它们的多播成员信息。3类报文在路由器之间传输多播选路信息,主机不处理3类报文。


2.IGMP_protosw的结构

IGMP的protosw结构如下:

《TCP/IP详解卷2:实现》笔记--IGMP:Internet组管理协议_第5张图片

三种时间触发IGMP处理:

一个本地接口加入一个新的多播组。

某个IGMP定时器超时。

收到一个IGMP查询。

还有两种事件也触发本地IGMP处理,但结果不发送任何报文:

收到一个IGMP报告。

某个本地接口离开一个多播组。


3.加入一个组:igmp_joingroup函数

当一个新的in_multi结构被创建时,in_addmulti调用igmp_joingroup。然后加入同一多播组的请求只增加in_multi结构的

引用次数,不调用igmp_joingroup。

函数的大概处理如下:

如果新的组时所有主机组,或成员关系请求时环回接口的,则不需要定时器,函数返回。因为每个多播主机都是所有组播组

的成员,不需要进行报告。没必要向环回接口发送组成员报告,因为本地主机是在回路网络上的唯一系统,它已经知道它的

成员状态了。

在其他情况下,新组的报告被立即发送(通过igmp_sendreport函数),并根据组的情况为组定时器选择一个随机值。

igmp_fastimo检查这个变量,避免不必要的处理。当新组的定时器超时时,就发布第2次成员关系报告。


4.igmp_fasttimo函数

igmp_fasttimo函数循环找到各个in_multi结构,对每个结构:

如果定时器为0,什么都不做。

如果定时器不是0,则将其递减。如果到达0,则发送一个IGMP组成员关系报告。


5.igmp_sendreport函数

igmp_sendreport函数为一个多播组构造和发送IGMP报告报文。

通过创建一个mbuf,然后设定相应的值,最后构造一个ip_moptions结构,并将它与报文一起传给ip_output。

进程级的多播路由器必须监听成员关系报告,当系统被配置成多播路由器时,总是接收IGMP数据报。通过传输层程序把

报文传给IGMP的igmp_input和pr_input函数。


6.输入处理:igmp_input函数

多播路由器接收所有的IGMP报文,但是多播主机只接收那些到达接收是目的多播组成员的IGMP报文(也即,那些接收

它们的接口是组成员的查询和成员管理报告)。

标准协议分用机制把接受的报文传给igmp_input。igmp_input的大概处理如下:

1.验证IGMP报文,包IGMP检验和等方式。

2.根据igmp_type内的代码处理报文,igmp_type包含一个版本码和一个类型码,根据这两个码分别进行处理。

3.把有效的IGMP报文传给rip_input,在rip_input里被提交给所有监听IGMP报文的进程。


6.1.成员关系查询:IGMP_HOST_MEMBERSHIP_QUERY

RFC1075推荐多播路由器每120秒至少发布一次IGMP成员关系查询。把查询发给224.0.0.1组(所有主机组)。

对于该igmp_type的处理如下:

接收查询报文并不会立即引起IGMP成员报告。相反,igmp_input为与接收查询的接口相关的各个组定时器设置一个随机的值,

当某组的定时器超时,则igmp_fasttimo发送一个成员关系报告,与此同时,其他所有查询的主机也进行同一动作。一旦某个

主机上的某个特定组的随机定时器超时,就像该组多播一个报告。这个报告将取消其他主机上的定时器,保证只有一个报告在

网络上多播。路由器与其他组成员一样,接收该报告。这个情况的一个例外就是所有主机组,这个组不设定定时器,也不发送

报告。


6.2.成员关系报告:IGMP_HOST_MEMEBER_REPORT

对于该igmp_type的处理如下:

发送到环回接口上的报告被丢弃。

如果源地址的网络或者子网部分为0(如果主机正在启动,这是被允许的),则把源地址设成子网地址,那么进程级的多播路由

守护进程能够知道它是从哪个子网过来的。


7.离开一个组:igmp_leavegroup函数

当in_multi结构中的引用计数器跳到0时,in_delmulti调用igmp_leavegroup。该函数不采取任何动作。

你可能感兴趣的:(TCP/IP详解卷2:实现)