ICMP type 69 code 192 ?
La situation de départ
Pour analyser une connexion réseau intermittente, j'ai eu l'idée d'écrire un genre de programme "ping" avec des rapports d'anomalie à ma sauce.
Le problème
Pour mettre le pied à l'étrier j'ai récupéré un code source chez les geeks. J'apporte les changements souhaités, compilation, je lance. Super, ça fonctionne. Au début.
Et puis de temps en temps j'ai un message inattendu :
"Error..Packet received with ICMP
type 69 code 192"
Bon, un coup de google duckduckgo pour ICMP type 69... très peu de réponses, en fait, que des gens qui se posent la même question. Pas merci Google cette fois-ci.
Allons voir le RFC approprié... Ah, les codes ICMP vont jusqu'à 18 ?! Peut-être qu'une autre norme en a ajouté depuis ?
Non.
Y aurait-il sur le web, des routeurs tellement mal fichus qu'ils ne respectent pas un standard inchangé depuis 40 ans ? Pour comprendre, me voila parti à faire un dump hexadécimal des paquets en erreur...
Solution courte
Ce que le programme teste n'est pas le début du paquet ICMP, mais le début du paquet IP. Un paquet IPv4 commence par 0x45 = 69 en décimal. Il faut chercher les données ICMP un peu plus loin dans le paquet !
Explication longue
Dans la doc Linux, man raw(7) précise :
"The IPv4 layer generates an IP header when sending (...) For receiving, the IP header is always included in the packet"
Donc la donnée que le programme envoie (une structure ICMP) est différente de ce qu'il reçoit (une structure IP).
Le programme d'origine teste ce qu'il croit être le type et le code ICMP. En réalité il teste les champs Version/IHL/DSCP de l'entête IP ! Il affiche une erreur quand le code n'est pas 0 (le code d'un ECHOREPLY). Je suppose qu'à l'origine, il testait aussi type ICMP == 0 mais ça ne marchait pas... et le programmeur a mis la valeur qui marchait, 69 donc.
D'une part, le test va considérer comme des réponses valides des paquets ICMP qui n'ont rien à voir avec ECHO REPLY (par ex. des Network Unreachable, ce que j'essayais de mettre en évidence à l'origine).
D'autre part, certaines réponses sont reçues dans des paquets IP prioritaires, d'où le "code ICMP" 192 qui est en réalité le champ IPv4 TOS/DSCP 0xc0 indiquant la priorité "network control".
J'ai mis un peu de temps à le trouver, ce bug-là.
Commenter cet article