Modes de diffusion
I. Introduction
IP possède trois types fondamentaux d’adresses : unicast, broadcast et multicast. Une adresse unicast est utilisée pour envoyer un paquet vers une destination unique. Une adresse de diffusion est utilisée pour envoyer un datagramme à l’ensemble d’un sous-réseau. Une adresse multicast
permet d’envoyer un datagramme à un ensemble d’hôtes qui peuvent être
sur différents sous-réseaux et qui sont configurés en tant que membres
d’un groupe multicast.
Diffusion = Plusieurs récepteurs pour une seule émission d'un paquet
La diffusion est disponible de deux façons différentes :
1. diffusion intégrale (broadcasting) : dans laquelle la diffusion s’effectue en direction de toutes les machines d’un réseau donné.
2. multidiffusion ou diffusion de groupe (multicasting) : envoi de données à un sous-groupe de tous les éléments d'un réseau.
· un groupe identifie un service de diffusion
· lorsqu’un message est émis à destination d’un groupe, tous les membres peuvent recevoir un exemplaire du message.
· pour recevoir il faut être membre du groupe.
· pour envoyer cela n’est pas nécessaire.
adresse IP multicast :
1. Une adresse IP multicast n'identifie pas une machine sur un réseau mais un groupe multicast.
2. Classe d'adresse IP entre 224.0.0.0 et 239.255.255.255 (Classe D).
3. Adresses entre 225.0.0.0 et 238.255.255.255 sont utilisables par un programme quelconque.
4. Les autres sont réservées.
II. Configuration :
Pour utiliser le multicast en C, on doit passer par la configuration des sockets (couche IP)
1. Lire l'état d'une option : getsockopt
int getsockopt(int sock, int niveau, int option, void *valeur, socklen_t *longueur)
2. Modifier l'état d'une option : setsockopt
int setsockopt(int sock, int niveau, int option, void *valeur, socklen_t longeur)
Paramètres d’entrées :
1. sock : la socket que l'on veut gérer
2. niveau : le niveau du protocole choisi, valeurs entre autres parmi
SOL_SOCKET : la socket elle-même, IPPROTO_IP : la couche IP, IPPROTO_TCP : la couche TCP, IPPROTO_UDP : la couche UDP
3. option : option choisie
Notamment pour le niveau SOL_SOCKET :
· SO_BROADCAST : autorisation de diffusion des paquets, ,
· SO_REUSEADDR : autorise de lier plusieurs sockets au même port
· SO_TYPE (avec get) : retourne le type de la socket (SOCK_DGRAM ...)
Notamment pour le niveau IP_PROTO :
· IP_[ADD/DROP]_MEMBERSHIP : inscription ou désinscription d'un groupe multicast,
· IP_MULTICAST_LOOP : paquet diffusé est reçu ou pas à son émetteur,
· IP_MULTICAST_TTL : TTL d'un paquet envoyé en multicast Programmation Réseaux 19 Avril 2015
4. valeur : données décrivant l'état de l'option. En général, on utilise un entier ayant pour valeur 0 ou 1.
· 0 : l'option n'est pas positionnée 1 : l'option est positionnée.
5. longueur : longueur du champ valeur.
II.1. Description du groupe multicast :
Pour décrire le groupe multicast on utilise la structure ip_mreq
struct ip_mreq
{ struct in_addr imr_multiaddr;
struct in_addr imr_interface;
};
• imr_multiaddr : adresse IP multicast
• imr_interfcae : adresse IP locale ou interface locale (On utilisera par défaut INADDR_ANY)
II.2. Réalisation de broadcast en C
pour faire de la diffusion (broadcast)
1. Créer la socket UDP de manière normale.
Int sock = socket(AF_INET, SOCK_DGRAM, 0);
2. appliquer l'option SO_ BROADCAST
int autorisation=1 ;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &autorisation, sizeof(int));
· On diffuse les paquets en utilisant l'adresse de diffusion du réseau
· Toutes les machines connectées au réseau recevront ce paquet
II.3. Réalisation de multicast en C
Pour initialiser une socket UDP en mode multicast , on doit respecter les étapes suivantes :
1. Créer la socket UDP de manière normale.
int sock = socket(AF_INET, SOCK_DGRAM, 0)
2. Créer l'objet ip_mreq
// récupération adresse ip du groupe
struct in_addr ip;
inet_aton("224.1.2.3", &ip);
// création identificateur du groupe
ip_mreq group ;
group.imr_multiaddr.s_addr = ip.s_addr;
gr_multicast.imr_interface.s_addr = INADDR_ANY;
3. Associer cet objet ip_mreq à la socket avec l'option IP_ADD_MEMBERSHIP Abonnement au groupe multicast
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(struct ip_mreq));
4. Eventuellement appliquer l'option SO_REUSEADDR pour lier plusieurs sockets sur le port utilisé par cette socket, c'est-à-dire sur le port du groupe multicast, Sinon on ne peut pas avoir deux 2 programmes utilisant le même groupe multicast sur la même machine à cause du bind réalisé
int reuse = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
5. Lier la socket au numéro de port du groupe multicast
// liaison de la socket au port du groupe multicast
struct sockaddr_in ad_multicast ;
bzero((char *) &adresse, sizeof(adresse));
ad_multicast.sin_family = AF_INET;
ad_multicast.sin_addr.s_addr = htons(INADDR_ANY);
ad_multicast.sin_port = htons(1234);
bind(sock, & ad_multicast, sizeof(struct sockaddr_in));
//Emission d'un paquet On utilise le couple @IP du groupe/port du groupe
struct sockaddr_in adresse;
int longueur_adresse = sizeof(struct sockaddr_in);
bzero((char *) &adresse, sizeof(adresse));
adresse.sin_family = AF_INET;
adresse.sin_addr.s_addr = ip.s_addr;
adresse.sin_port = htons(1234);
sendto(sock, message, tailleMessage , 0, (struct sockaddr*)&adresse, longueur_adresse);
// réception d'un paquet : avec recvfrom ou peut utiliser // aussi recv car ne recevra des paquets que venant du groupe
recv(sock, buffer, TAILLEBUFFER, 0);