---
# System prepended metadata

title: IGMP網際網路群組管理通訊協定
tags: [通訊協定, Python Lan]

---

###### 撰寫日期：2023/07/19
###### 作者：陳彥夫
# IGMP網際網路群組管理通訊協定
{%hackmd BJrTq20hE %}

負責管理multicast成員的通訊協定

### 參考資料
[IP Multicast Technology Overview](https://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/mcst_ovr.html#wp1009068)
[IGMP基础](https://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/mcst_ovr.html#wp1009068)

# IGMPv1
IGMP查詢路由器每隔一段時間發送Membership query給主機的地址(假設224.0.01)，有啟用multicast的主機就會接收query，然後回傳report，表示他要接收這個組發的mullticast封包。

IGMPv1中運行查詢的路由器由群播路由協定決定。主機透過不回應query來退出群組。
* 封包類型：Membership query(0x11)、Menbership report(0x12)
* Membership query封包：查詢器週期性發送訊息給網路上所有主機
* Menbership report封包：若是對某個組的訊息感興趣，就會回傳此訊息給查詢器以表示加入群組
* Version：版本值為1
* Type：0x11為query封包，0x12為report封包
* Unused：預設為0，接收時被忽略
* Group address：multicast地址，query封包中為0，report封包中為加入的群組地址
![IGMPv1封包](https://img.onl/jAY63g)
    RouterA向224.0.0.1（區網內所有主機和路由器）發送query訊息，收到的組成員開啟計時器（0~10s）。
    HostA計時器超時，發送G1report訊息。如果HostB收到，就會暫停計時器停止送G1report訊息以減少網路上的流量。
    RouterA在收到HostA的report訊息就知道G1有成員，由群播路由協定產生（*，G）的群播轉發表。


![](https://img.onl/LQRZFR)
## 新成員加入
HostC不等待query訊息來，自己主動發送G2report以加入G2。
RouterA收到report後，知道了G2的成員，則產生群播轉發表(*,G2)
![](https://hackmd.io/_uploads/Hkg9bNUc3.png)
## 離開機制
IGMPv1沒有定義離開組的訊息
* 假如HostA想退出G1，就不再發送G1report的封包，但是因為區網中還有HostB會繼續發送G1report的封包，所以RouterA不會察覺HostA的離開
* 假如HostC想退出G2，就不再發送G2report的封包，但因為區網中不存在其他G2成員，RouterA則會在一定時間內刪除G2的群播轉發表

# IGMPv2
IGMPv2機制和v1大致相同，而v2增加了離開群組的機制。
* Type：
0x11Membership query：General-Group query和Group-specific query
0x12Membership report:IGMPv1\0x16membership report:IGMPv2
0x17Leave:離開的訊息
* Max resp time：成員在接收query訊息時要再最大響應時間內回復
* Group address：General-Group query中為0.0.0.0，Group-specific query為要查詢的群播地址，在membership report中為要加入的群播地址

![](https://hackmd.io/_uploads/r1B1GEU5n.png)

## 查詢器選舉

1. 最初所有運行IGMPv2的RouterA、B都以為自己是查詢器想本地所有主機和路由器發送query訊息.在RouterAB都收到對方的query訊息後將封包的srcIP和自己端口的IP地址做比較，地址較小的就會成為查詢器。
2. 之後就由查詢器RouterA向區網內所有的主機和路由器發送General-Group query。routerB則會啟動一個計時器，在計時器超時前收到A的封包就會重置，若超時就會重啟選舉過程
![](https://hackmd.io/_uploads/HJpFr4Lq3.png)

## 離開群組機制

1. HostA向本地所有的組播路由器（224.0.0.2）發送G1leave的訊息
2. 查詢器在收到leave訊息後會發送G1query的訊息，同時啟動計時器Timer-Membership
3. 若還有G1組還有成員則會在收到query後繼續發送report封包以維護組成員的關係
4. 若G1組沒有成員，在計時器超時後就會刪除（*,G1）的群播轉發表

![](https://hackmd.io/_uploads/BJQ2SEIc3.png)


# IGMPv3

IGMPv3訊息：query和report兩類，沒有定義成員leave的訊息

Query新增Group-and-Source-Specific Query：用於查詢該組成員是否願意接收特定來源的流量。

Membership report新增filter mode：INCLUDE/EXCLUDE表示想要接收那些特定來源的流量。

## 封包類型
S：若該值為1時，所有收到此query訊息的路由器不啟動
計時器
QQIC：IGMP查詢器的query間隔（秒）。
Number of source:封包中群播來源的數量。對於
General-Group query和Group-specific query來說這個值是0，
對於Group-and-Source-Specific Query為非0。
![](https://hackmd.io/_uploads/rJNddEUch.png)

## IGMPv3 record type
IGMPv3 report訊息的目的地是224.0.0.22，透過訊息中攜帶的group record在加入組的同時還能要求接收或不接受特定來源的群播封包.
Type record：MODE_IS_INCLUDE、MODE_IS_EXCLUDE、CHANGE_TO_INCLUDE_MODE、CHANGE_TO_EXCLUDE_MODE、ALLOW_NEW_SOURCES、BLOCK_OLD_SOURCES
透過更改fliter mode來加入或離開群組。
CHANGE_TO_INCLUDE_MODE表示從exclude到include，將接收include表中的來源流量，如果表是空的則會離開群組。
CHANGE_TO_EXCLUDE_MODE表示從include到exclude，將拒絕exclude表中的來源流量，如果表是空的則代表加入群組。

對應到[mininet實驗](https://hackmd.io/VDzwloB6QNq92zQ-w-svuA?view)
CHANGE_TO_INCLUDE_MODE離開群組
![](https://hackmd.io/_uploads/BJuiYV853.png)
CHANGE_TO_EXCLUDE_MODE加入群組
![](https://hackmd.io/_uploads/rkvTFNL5n.png)

# IP multicast address
群播地址是一群主機加入的組并且對特定群播流量感興趣
IP class D address：224.0.0.0~239.255.255.255
224.0.0.0~224.0.0.255 路由器不會轉發這些地址出區網外
ex：224.0.0.22  IGMPv3 report、224.0.0.1 發送到子網路中的所有系統

## layer 2 multicast mac address mapping
IPv4 => MAC
MAC 映射範圍01:00:5e:00:00:00 到 01:00:5e:7f:ff:ff
![](https://hackmd.io/_uploads/By_is4Lq3.png)
由於IP轉MAC地址時有5位元被捨棄因此224.128.1.1 、224.0.1.1、239.128.1.1 等IP地址都會被映射到 01:00:5e:00:01:01，如下圖。
![](https://hackmd.io/_uploads/r15en4Iq3.png)
如果一個用戶訂閱了A組（如 224.1.1.1），而其他用戶訂閱了B組（如 225.1.1.1），則他們A和B的封包都會接收。

## IGMP snooping
 
預設的layer2 switch會把所有的群播流量發送到目標區網的每一個port。switch監聽主機和路由器之間的IGMP report massage。根據收到的port建立群播轉發表。
![](https://hackmd.io/_uploads/SkA7JS8ch.png)









  



