# Internet Group Management Protocol

Internet Group Management Protocol (IGMP, Protocole de gestion de groupe Internet) est un protocole de communication qui permet à des routeurs IPv4 d'établir de façon dynamique des groupes de plusieurs hôtes pour qu'ils puissent rejoindre des diffusions multipoint (multicast).
IGMP est utilisé pour des applications où beaucoup d'hôtes rejoignent simultanément un même serveur, par exemple pour le streaming en direct ou les jeux en ligne massivement multijoueur.
IGMP est un protocole de couche réseau (couche n$^o$ 3 du modèle OSI), au même niveau que le protocole Internet (IP). Il est défini pour les réseaux IPv4. La gestion du multicast pour IPv6 est effectuée par la fonction Multicast Listener Discovery (MLD) du protocole ICMPv6. D'un point de vue fonctionnel, MLDv1 équivaut à IGMPv2 et MLDv2 est semblable à IGMPv3.

## Utilisation d'IGMP

IGMP est un protocole asymétrique en ce sens que le comportement spécifié pour les hôtes diffère de celui des routeurs multicast. Toutefois, un routeur multicast pouvant s'abonner à un groupe multicast au même titre qu'un hôte, les routeurs multicast doivent exécuter les deux parties du protocole.
IGMP est un protocole exécuté entre les machines hôtes d'un même sous-réseau et les routeurs multicast de ce sous-réseau. Il permet à une machine hôte d'informer un de ces routeurs multicast sur ses abonnements en cours à des groupes multicast. Les routeurs maintiennent la liste des groupes multicast pour lesquels des machines hôtes leur ont rapporté être abonnées. Une telle liste est maintenue pour chacun des sous-réseaux qu'un routeur multicast interconnecte et permet au routeur de déterminer les paquets IP multicast à relayer sur ces sous-réseaux. Un paquet IP multicast est relayé sur un sous-réseau si l'adresse de destination de ce paquet est celle d'un des groupes multicast associés à ce sous-réseau.
Une source de trafic multicast n'est pas nécessairement membre d'un groupe, elle peut donc émettre un flux à destination du groupe sans signalisation préalable et sans prendre en charge IGMP. Sur une interface, les routeurs peuvent également forcer une souscription de type (*,G), c'est-à-dire indépendant de la source, ou encore Any Source Multicast (ASM), ou (S,G) (Source-Specific Multicast, SSM).

## Fonctionnement d'IGMP

Plusieurs versions d'IGMP existent et diffèrent en fonctionnalité. Seule la version 3 est de type SSM.
Toutes les versions d'IGMP utilisent le numéro de protocole 2 d'IP et fixent le champ Time to Live des paquets à 1, évitant ainsi leur propagation au-delà du sous-réseau qu'ils concernent. Les versions rencontrées actuellement sont les versions 2 et 3.

### IGMP v0

IGMPv0 est défini dans la RFC 988, cette version est considérée comme obsolète.

### IGMP v1

IGMPv1 est décrit dans la RFC 1112.
Il existe deux types de messages dans IGMPv1 : requête d'adhésion (membership query) et rapport d'adhésion (membership report).
Un routeur qui assure la transmission des paquets multicast sert de requérant (querier), c'est-à-dire qu'il émet les requêtes à intervalle régulier (toutes les 60 secondes par défaut).
Les hôtes répondent en indiquant dans un rapport les groupes auxquels ils souscrivent. Pour éviter un flot de réponses simultanées, des rapports sont envoyés avec un délai aléatoire (compris entre 0 et 10 secondes par défaut). Si, pendant ce délai, un hôte reçoit un rapport d'un autre hôte concernant ce groupe, son message de souscription est supprimé.
Aucun rapport n'est envoyé pour le groupe 224.0.0.1 (All hosts).
La version est 1. Le type est 1 pour la requête et 2 pour le rapport.
Pour les requêtes, l'adresse de destination est 224.0.0.1 (All hosts). Pour les rapports, l'adresse IP de destination est la même que celle du groupe qu'il concerne.
Un hôte qui souhaite joindre un groupe envoie un rapport sans attendre de requête.

#### Limitations d'IGMPv1

* Il n'y a pas de message qui permet à un hôte d'indiquer qu'il quitte un groupe. Le requérant ne peut donc déterminer qu'un groupe ne dispose plus de membres sur un segment qu'après un délai généralement fixé à trois fois l'intervalle entre les requêtes (c'est-à-dire trois minutes) et pendant lequel aucun rapport concernant ce groupe n'est reçu. Ceci peut poser des problèmes pour les flux multicast à haut débit, qui peuvent causer de la congestion au niveau de l'accès au sous-réseau si un client passe rapidement d'un groupe à un autre.
* La RFC ne dit pas comment le requérant est choisi s'il existe plusieurs routeurs multicast dans le sous-réseau.

### IGMP v2

RFC 2236 décrit la version 2 d'IGMP. C'est la version d'IGMP la plus répandue parmi les systèmes d'exploitation généraux, elle est notamment prise en charge par Windows 98 et le noyau Linux 2.4.
Celle-ci corrige certaines limitations de la version 1, sont ajoutés :
* une requête spécifique à un groupe,
* un mécanisme d'élection d'un requérant,
* le délai maximal pour la réponse est indiqué dans la requête,
* un message pour quitter le groupe.
Le champ Type englobe le champ version d'IGMPv1 et permet un certain niveau de rétrocompatibilité avec la version 1.
* Une requête générale avec une valeur Type de 0x11 sera bien interprétée comme un message de requête par un hôte qui ne prend en charge que la version 1. Une requête spécifique au groupe contient l'adresse du groupe.
* La valeur Type 0x12 est utilisée pour la rétrocompatibilité, il s'agit en réalité d'un rapport d'hôte en version 1.
* La valeur 0x16 est un rapport dans la version 2.
* La valeur 0x17 (leave) est utilisée pour quitter un groupe.
Le champ Max Resp Time indique le temps maximal dont dispose un hôte pour répondre, en dixièmes de secondes. Les hôtes utilisent un délai aléatoire inférieur à cette limite pour la réponse et suppriment éventuellement les rapports comme en version 1. Le délai maximal vaut 100 (10 secondes) pour une requête générale, et 10 (1 seconde) pour une requête spécifique à un groupe.
La RFC indique qu'un hôte « devrait » envoyer un message quitter quand il quitte un groupe, ceci implique que ce message n'est pas obligatoire. Ceci rend les optimisations telles que IGMP snooping particulièrement difficiles. Les implémentations du protocole utilisent cependant systématiquement ce message.

#### Processus pour quitter un groupe

Le message pour quitter un groupe est dirigé vers l'adresse 224.0.0.2 (All-routers). Quand le routeur requérant reçoit ce message, il envoie en réponse un message query spécifique au groupe quitté pour déterminer s'il subsiste un hôte membre du groupe dans le sous-réseau. Si aucune réponse n'est reçue, le routeur considère qu'il n'existe plus d'abonnés au groupe. Ce message est généralement répété, de sorte que le délai pour qu'un groupe quitte un segment est situé entre 2 et 3 secondes par défaut.

#### Élection du requérant

Quand un routeur reçoit une requête provenant d'un autre routeur, il compare l'adresse IP source avec la sienne. Le routeur dont l'adresse est la plus basse est sélectionné comme requérant sur le segment. Quand un routeur reçoit une telle requête supérieure à la sienne, il démarre un compteur de 250 secondes pendant lequel il s'abstient d'envoyer des requêtes. Si aucun message d'un requérant avec une IP plus petite n'est reçu pendant cette période, les requêtes sont émises à nouveau.

#### Interopérabilité avec IGMP v1

* Si un hôte détecte un requérant v1, il se comportera comme un hôte IGMPv1 et émettra des rapports en format v1 pendant au moins 400 secondes. Un hôte peut déterminer qu'il s'agit d'une requête v1 en examinant le contenu du champ Max Resp Time, s'il vaut 0, alors il s'agit en réalité du champ Unused en v1.
* Un hôte v1 répondra aux requêtes v2, cependant les rapports v2 ne seront pas interprétés correctement par les hôtes v1 et seront donc ignorés par ces derniers. En présence d'un mélange d'hôtes v2 et v1, la suppression des rapports ne sera donc pas complètement efficace. D'autre part, le requérant doit ignorer les messages quitter d'un groupe s'il détecte un hôte v1 dans ce groupe.

#### Limitations d'IGMPv2

Les seuls états possibles sont de type (*,G), c'est-à-dire qu'il n'est pas possible à un hôte d'indiquer qu'il ne souhaite recevoir un groupe que d'une source déterminée, ni exclure une source déterminée.

### IGMP v3

La version 3 (RFC 3376) ajoute la possibilité de spécifier une souscription à un groupe avec une source particulière, ou à l'exclusion de certaines sources. La RFC précise que le champ ToS du paquet IP est fixé à 0xc0 (Internetwork Control) et que l'option Router Alert (RFC 2113) est utilisée.
IGMPv3 est pris en charge par Linux à partir de 2.6.7, par Windows XP, Cisco IOS 12.1(5)T et FreeBSD 8.0.
La suppression des rapports, dont la prise en charge est obligatoire pour les versions 1 et 2, est supprimée dans cette version. Ceci facilite le fonctionnement d'IGMP Snooping et permet de réduire la latence au moment où le dernier membre quitte un groupe (fast leave).
Il existe deux types de messages IGMPv3 :
* Type=0x11 : Requête
* Type=0x22 : Rapport v3
Les champs type 0x12 (rapport v1), 0x16 (rapport v2) et 0x17 (quitter v2) doivent être pris en charge par une implémentation d'IGMP v3 pour la rétrocompatibilité.

#### Requêtes

Il existe trois types de requêtes :
* la requête générale : l'adresse de groupe est laissée vide, et N=0
* la requête spécifique à un groupe : l'adresse de groupe est indiquée, et N=0
* la requête spécifique à un groupe et à des sources : l'adresse du groupe est indiquée, N≠0 et la liste des sources est fournie.
La requête générale est envoyée à l'adresse 224.0.0.1 (All hosts), tandis que les requêtes relatives à des groupes sont envoyées à l'adresse du groupe en question.
Le champ Max Resp Code est codé de la façon suivante :
* s'il correspond à un nombre inférieur à 128, il a le même sens qu'en v2, c'est-à-dire des dixièmes de secondes,
* si le premier bit vaut 1, les trois bits suivants sont des bits d'exposant, tandis que les 4 bits suivants servent de mantisse, ce qui permet d'exprimer des valeurs plus élevées, sachant que l’équation est (mant | 0x10) << (exp + 3), la valeur maximale est 111110000000000b en binaire, soit 31×2$^{(7+3)}$ = 31744 dixièmes de seconde, soit un peu moins de 53 minutes, ce qui contribue à limiter le flot des réponses en présence d'un grand nombre de membres dans un sous-réseau.
Le champ S, quand il est à 1, indique aux autres routeurs de ne pas tenir compte de ce message pour la mise à jour de la minuterie.
Le champ QQIC (Querier's Query Interval Code) représente le délai entre les requêtes. Les routeurs qui sont non-requérants s'alignent sur cette valeur.
Le champ QRV (Querier's Robustness Variable) est une indication de la fiabilité de la transmission dans le sous-réseau. Les rapports et requêtes sont retransmis en fonction de la valeur de ce champ.

#### Rapports

Les rapports indiquent les groupes et éventuellement les sources auxquels les hôtes souscrivent. Ils sont envoyés à l'adresse 224.0.0.22 dédiée à IGMP v3. Deux modes sont possibles :
* le mode d'inclusion, où toutes les sources souhaitées sont indiquées,
* le mode d'exclusion, où toutes les sources sont souhaitées, sauf celles indiquées. La liste des sources exclues est éventuellement nulle, ce qui signifie que l'hôte souscrit à toutes les sources.
Conceptuellement, les routeurs tiennent à jour une table composées de tuples de la forme suivante :
(adresse multicast, minuterie de groupe, mode de filtrage, (liste des sources))
Chaque source est de la forme suivante :
(adresse source, minuterie de source)

## Messages IGMP

Voici la liste des messages IGMP ainsi que leur adresse de destination.
G représente l'adresse du groupe concerné.
| Version IGMP | Type de message | Version/Type | Adresse destination |
| 1 | requête | 0x11 | 224.0.0.1 |
| 1 | rapport | 0x12 | G |
| 2 | requête | 0x11 | 224.0.0.1 |
| 2 | requête G | 0x11 | G |
| 2 | rapport | 0x16 | G |
| 2 | quitter | 0x17 | 224.0.0.2 |
| 3 | requête | 0x11 | 224.0.0.1 |
| 3 | requête G | 0x11 | G |
| 3 | rapport | 0x22 | 224.0.0.22 |
* Rapport v2
* Rapport v3

## IGMP Snooping

La technique IGMP Snooping consiste, pour un commutateur Ethernet, à optimiser la diffusion des trames multicast en observant le trafic IGMP.