Entête ICMP

Entête ICMP

1 – Définition du protocole ICMP

Le protocole ICMP (Internet Control Message Protocol) permet de gérer les informations relatives aux erreurs du protocole IP. Il ne permet pas de corriger ces erreurs, mais d’en informer les différents émetteurs des Datagrammes en erreurs. Chaque pile IP, que ce soit des routeurs ou des stations de travail, gèrent l’entête ICMP par défaut.

Ce protocole est considéré comme faisant partie de l’ensemble des protocoles TCP/IP. Cependant, contrairement à TCP et UDP, il se situe en couche 3 et donc, il est encapsulé dans IP. Le mot « Encapsulation » relate clairement la confusion du placement d’ICMP dans les 7 couches OSI.

Les messages d’erreur ICMP sont transportés sur le réseau sous forme de Datagramme, comme n’importe quelle donnée. Ainsi, les messages d’erreurs peuvent eux-mêmes être sujet aux erreurs. Toutefois, en cas d’erreur sur un message ICMP, aucune trame d’erreur n’est délivrée pour éviter un effet « boule de neige ».

Vous trouverez tous les détails du protocole ICMP dans la RFC 792.

2 – Structure de l’entête ICMP

Voici la structure de l’entête ICMP basé sur 8 octets.

entete-icmp entete icmp

Les deux champs Identifiant et Numéro de séquence ne sont présent que dans le cas d’un paquet de type Ping sinon les champs reste présent mais en tant que bourrage et donc non utilisés.

3 – Définition des différents champs

3.1 – Type et Code

Les champs Type et Code sont codés respectivement sur 8 bits ce qui donne un totale de 2 octets. Ils représentent la définition de message d’erreur contenu. Voici la liste des principales combinaison entre les champs Type et Code :

  • type=00 et code=00 : Réponse à une demande d’écho
  • type=03 et code=00 : Réseau inaccessible
  • type=03 et code=01 : Hôte inaccessible
  • type=03 et code=02 : Protocole inaccessible
  • type=03 et code=03 : Port inaccessible
  • type=03 et code=04 : Fragmentation nécessaire mais interdite
  • type=03 et code=05 : Echec de routage par la source
  • type=03 et code=06 : Réseau de destination inconnu
  • type=03 et code=07 : Hôte de destination inconnue
  • type=03 et code=08 : Machine source isolée
  • type=03 et code=09 : Réseau de destination interdit administrativement
  • type=03 et code=10 : Hôte de destination interdite administrativement
  • type=03 et code=11 : Réseau inaccessible pour ce type de service
  • type=03 et code=12 : Hôte inaccessible pour ce type de service
  • type=03 et code=13 : Communication interdite par un filtre
  • type=03 et code=14 : Host Precedence Violation
  • type=03 et code=15 : Precedence cutoff in efect
  • type=04 et code=00 : Volume de donnée trop importante
  • type=05 et code=00 : Redirection pour un hôte
  • type=05 et code=01 : Redirection pour un hôte et pour un service donné
  • type=05 et code=02 : Redirection pour un réseau
  • type=05 et code=03 : Redirection pour un réseau et pour un service donné
  • type=08 et code=00 : Demande d’écho
  • type=09 et code=00 : Avertissement routeur
  • type=10 et code=00 : Sollicitation routeur
  • type=11 et code=00 : Durée de vie écoulée avant d’arrivée à destination
  • type=11 et code=01 : Temps limite de réassemblage du fragment dépassé
  • type=12 et code=00 : Entête IP invalide
  • type=12 et code=01 : Manque d’une option obligatoire
  • type=12 et code=02 : Mauvaise longueur
  • type=13 et code=00 : Requête pour un marqueur temporel
  • type=14 et code=00 : Réponse pour un marqueur temporel
  • type=15 et code=00 : Demande d’adresse réseau
  • type=16 et code=00 : Réponse d’adresse réseau
  • type=17 et code=00 : Demande de masque de sous réseau
  • type=18 et code=00 : Réponse de masque de sous réseau

3.1.1 – Type=0,8 – Le Ping

Le principe du Ping étant, à la base, de valider la présence d’un Hote IP. Pour cela, l’application Ping utilisera la séquence 8-0 afin d’émettre une demande d’écho. Les données reçues dans un message d’écho doivent être réémises dans la réponse. Ainsi, si le message de retour correspond à l’émission, on en déduit que l’Hote est présent. De plus, on peux en déduire d’autres services, tel que le temps de réponse, la taille paquet maximum la durée de vie et etc.

L’ identificateur et le numéro de séquence peuvent être utilisés par l’émetteur du message d’écho afin d’associer facilement l’écho et sa réponse. Par exemple, l’identificateur peut être utilisé comme l’est un port pour TCP ou UDP, identifiant ainsi une session. Et le numéro de séquence peut être incrémenté pour chaque message d’écho envoyé. L’hôte de destination respectera ces deux valeurs pour le retour.

3.1.2 – Type=3 – Destination non valide

Ce type de message est émis dans le cas où un routeur ou un hôte ne puisse pas router un paquet.

3.1.3 – Type=4 – Volume de donnée trop importante

Un routeur ou hôte peut être amené à détruire un Datagramme s’il manque de mémoire pour bufferiser. Dans ce cas, le routeur émettra un message à destination de la source du Datagramme détruit, un paquet ICMP de type 4.

Cela peut ce produire dans un second cas. Quand le Datagramme arrive trop rapidement pour qu’il puisse être traité le message ICMP peut donc constituer une demande de diminution de débit de transfert.

3.1.4 – Type=5 – Redirection

Ces types de messages sont émis afin d’indiquer que le chemin emprunté n’est pas le bon pour la destination demandé. La réception de ce type de message d’erreur peut être interprétée par la modification de la table de routage locale. C’est plus communément appelé « ICMP Redirect ».

3.1.5 – Type=9,10 – découverte de routeur

Au démarrage d’une station, plutôt que de configurer manuellement les routes statiques, surtout si elle sont susceptibles de changer et que le nombre de stations est grands, il peut être intéressant de faire de la découverte automatique de routeurs. Pour cela, il y a deux possibilités. La première est l’envoi régulier de messages ICMP de type 9 « Avertissement routeur » d’annonces de routes par les routeurs. La seconde possibilité est qu’une station sollicite les routeurs avec un message de type 10 « Sollicitation routeur ».

La découverte de routeur n’est pas un protocole de routage, son objectif est bien moins ambitieux , juste obtenir une route par défaut. 

Vous trouverez tous les détails du « découverte de routeur » dans la RFC 1256.

3.1.6 – Type=11 – Temps excédé

Lorsqu’un routeur traitant un Datagramme est amené à mettre à jour le champ Durée de Vie de l’entête IP et que ce champ atteint une valeur zéro, le Datagramme sera détruit. Le routeur peut alors envoyer un message d’erreur « Time To Live expiré ». Ce message ICMP peux être émis aussi dans le cas où le temps de réassemblage expire et le Datagramme ne peux donc être reconstitué à temps.

3.1.7 – Type=12 – Erreur d’entête

Si un routeur rencontre un problème avec un paramètre d’entête IP l’empêchant de finir son traitement, le datagramme sera alors détruit. Un message d’erreur de type 12 sera donc alors émis.

3.1.8 – Type=13,14 – Marqueur temporel

Le but de ce type de message est de s’échanger des données temporelles pour, par exemple, synchroniser les horloges.

3.1.9 – Type=15,16,17,18 – Demande d’information

Ce type de message est envoyé vers une adresse constituée du numéro de réseau dans le champ source de l’entête IP et un champ destinataire à 0. La pile IP qui répondra pourra alors envoyer une réponse avec les adresses entièrement renseignées.

3.2 – Checksum

Le champ Checksum est codé sur 16 bits et représente la validité du paquet de la couche 3 ICMP. Pour pouvoir calculer le Checksum, il faut positionner le champ du checksum a 0. Ce calcul est strictement le même que celui du protocole IGMP.

Voici un exemple de fonction permettant le calcul du checksum ICMP.

unsigned short calcul_du_checksum(bool liberation, unsigned short *data, int taille)
     {
     unsigned long checksum=0;
     // ********************************************************
     // Complément à 1 de la somme des complément à 1 sur 16 bits
     // ********************************************************
     while(taille>1)
         {
         if (liberation==TRUE)
             liberation_du_jeton(); // Rend la main à la fenêtre principale
         checksum=checksum+*data++;
         taille=taille-sizeof(unsigned short);
         }
 
     if(taille)
         checksum=checksum+*(unsigned char*)data;
 
     checksum=(checksum>>16)+(checksum&0xffff);
     checksum=checksum+(checksum>>16);
 
     return (unsigned short)(~checksum);
     }
 
 unsigned short calcul_du_checksum_icmp(bool liberation, struct icmp icmp_tampon,char data_tampon[65535])
       {
       char tampon[65535];
       unsigned short checksum;
 
       // ********************************************************
       // Initialisation du checksum
       // ********************************************************
       icmp_tampon.checksum=0; // Doit être à 0 pour le calcul
 
       // ********************************************************
       // Calcul du ICMP
       // ********************************************************
       memcpy(tampon,(unsigned short *)&icmp_tampon,sizeof(struct icmp));
       memcpy(tampon+sizeof(struct icmp),data_tampon,strlen(data_tampon));
       checksum=calcul_du_checksum(liberation,(unsigned short*)tampon,sizeof(struct icmp)+strlen(data_tampon));
 
       return(checksum);
       }

3.3 – Identifiant

Le champ identifiant est codé sur 16 bits et définit l’identifiant de l’émetteur. Pour cela, il est conseillé d’assigner le numéro du processus assigné (PID) à l’application lors de l’exécution. Cela permet de le rendre unique inter application. Cela ressemble beaucoup aux numéros de port pour les protocole TCP et UDP.

3.4 – Numéro de séquence

Le champ Séquence est codé sur 16 bits et permet au récepteur, d’identifier si il manque un paquet. Le plus classique étant une incrémentation linéaire de 1. Ainsi, si le récepteur reçoit la séquence 1 puis 3, il peut en déterminer une perte d’un paquet. Néanmoins, ce n’est pas normalisé, donc personne n’à la garantie que l’émetteur utilisera cette méthode. Cela peut aussi permettre à l’émetteur d’envoyer multiples paquets et de pouvoir distinguer les retours.

4 – Suivi du document

Création et suivi de la documentation par _SebF

Modification de la documentation par Julien LEGRAND

  • Correction du chapitre 3.1 sur le code 0 « réponse à une demande d’écho »

5 – Discussion autour de l’entête ICMP

Vous pouvez poser toutes vos questions, faire part de vos remarques et partager vos expériences à propos de l’entête ICMP. Pour cela, n’hésitez pas à laisser un commentaire ci-dessous :

Commentaire et discussion

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *