|
|
Entête ICMP
par _SebF
1 - Définition du
protocole
2 - Structure de l'entête
3 - Définition des différents
champs
3.1 -
Type et Code
3.1.1 - Type=0,8 - Le Ping
3.1.2 - Type=3 - Destination
non valide
3.1.3 - Type=4 -
Volume de donnée trop importante
3.1.4 - Type=5 - Redirection
3.1.5 - Type=9,10 -
découverte de routeur
3.1.6 - Type=11 - Temps excédé
3.1.7 - Type=12 - Erreur d'entête
3.1.8 - Type=13,14 - Marqueur
temporel
3.1.9 -
Type=15,16,17,18 - Demande d'information
3.2 -
Checksum
3.3 -
Identifiant
3.4 -
Numéro de séquence
4 - Discussion autour de la
documentation
5 -
Suivi du document
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 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.
Voici la structure de l'entête ICMP basé sur 8 octets.

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.
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 |
Code |
Description |
| |
|
|
|
0 |
0 |
Réponse à une demande d'écho |
|
3 |
0 |
Réseau inaccessible |
|
3 |
1 |
Hôte inaccessible |
|
3 |
2 |
Protocole inaccessible |
|
3 |
3 |
Port inaccessible |
|
3 |
4 |
Fragmentation nécessaire mais interdite |
|
3 |
5 |
Echec de routage par la source |
|
3 |
6 |
Réseau de destination inconnu |
|
3 |
7 |
Hôte de destination inconnue |
|
3 |
8 |
Machine source isolée |
|
3 |
9 |
Réseau de destination interdit administrativement |
|
3 |
10 |
Hôte de destination interdite administrativement |
|
3 |
11 |
Réseau inaccessible pour ce type de service |
|
3 |
12 |
Hôte inaccessible pour ce type de service |
|
3 |
13 |
Communication interdite par un filtre |
|
3 |
14 |
Host Precedence Violation |
|
3 |
15 |
Precedence cutoff in efect |
|
4 |
0 |
Volume de donnée trop importante |
|
5 |
0 |
Redirection pour un hôte |
|
5 |
1 |
Redirection pour un hôte et pour un service donné |
|
5 |
2 |
Redirection pour un réseau |
|
5 |
3 |
Redirection pour un réseau et pour un service donné |
|
8 |
0 |
Demande d'écho |
|
9 |
0 |
Avertissement routeur |
|
10 |
0 |
Sollicitation routeur |
|
11 |
0 |
Durée de vie écoulée avant d'arrivée à destination |
|
11 |
1 |
Temps limite de réassemblage du fragment dépassé |
|
12 |
0 |
En-tête IP invalide |
|
12 |
1 |
Manque d'une option obligatoire |
|
12 |
2 |
Mauvaise longueur |
|
13 |
0 |
Requête pour un marqueur temporel |
|
14 |
0 |
Réponse pour un marqueur temporel |
|
15 |
0 |
Demande d'adresse réseau |
|
16 |
0 |
Réponse d'adresse réseau |
|
17 |
0 |
Demande de masque de sous réseau |
|
18 |
0 |
Réponse de masque de sous réseau
|
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.
Ce type de message est émis dans le cas où un routeur ou un hôte ne puisse pas
router un paquet.
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.
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".
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.
Lorsqu'un routeur traitant un Datagramme est amené à mettre à jour le champ
Durée de Vie de l'en-tê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.
Si un routeur rencontre un problème avec un
paramètre d'en-tê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.
Le but de ce type de message est de s'échanger des données temporelles pour, par
exemple, synchroniser les horloges.
Ce type de message est envoyé vers une adresse constituée du numéro de réseau dans
le champ source de l'en-tê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.
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);
} |
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.
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.
Vous pouvez poser toutes vos questions,
vos remarques et vos expériences à propos de l'entête ICMP. Pour cela,
rendez-vous sur le
Forum "TCP-IP".
Version 1.1, le 06 novembre 2007, par Julien
LEGRAND,
correction du chapitre 3.1 sur le code 0 "réponse à une demande d'écho"
Version 1.0, le 20 septembre 2003, par
Sébastien FONTAINE, création du document.
|
|