Outils de conversion d'adresses IP
Source de problèmes en perspective !!!
Source de
problèmes en perspective: l'endianess !!! Le réseau possède
son propre rangement des octets nommé Network Byte Order
Votre machine a le sien : Host Byte Order
Or dans les informations que vous allez fournir, certaines seront utilisés sous votre système d'exploitation favori, d'autres au moment du transfert sur le réseau. Il sera donc nécessaire de compléter certains champs des structures qui sont utilisées non pas dans l'ordre de votre système (puisque là vous serez forcement bon !) mais dans celui du réseau !!!
Des fonctions vont nous aider à résoudre ce problème: (A noter, il existe les mots courts et les mots longs...)
- htons()--"Host to Network Short" pour ordonner les mots (les poids
faible et fort) dans l'ordre Network Byte Order
- htonl()--"Host to Network Long" même chose que précédemment
mais avec des mots longs
- ntohs()--"Network to Host Short" pour ordonner les mots (les poids
faible et fort) dans l'ordre Host Byte Order
- ntohl()--"Network to Host Long" même chose que précédemment
mais avec des mots longs
N'oubliez
donc pas d'utiliser ces fonctions, et de préférence systématiquement,
même si vous savez que le microprocesseur que vous utilisez ordonne déjà
les données de la même manière que celui du réseau.
Votre code sera plus facilement portable !
includes nécessaires
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
Détail des fonctions
La première fonction que nous allons voir est une fonction permettant de convertir une chaîne de caractères contenant une adresse IP format 999.999.999.999 au format sin_addr respectant le Network Byte Order. Donc inutile de le convertir ensuite !
unsigned long int inet_addr (const char *cp);
En entrée:
cp contient la chaîne de caractères composant l'adresse IP
En sortie: la codification de l'adresse IP ou -1 si l'adresse est incorrecte.
comme indiqué,
la fonction retourne unsigned long int. Ce qui veut dire qu'elle
nous retourne la valeur $FFFFFFFF en cas d'erreur (-1 non signé) soit
en décimal découpé en octet:
255 255 255 255 qui en adresse IP peut correspondre à 255.255.255.255 qui est l'adresse de "broadcast" donc non une erreur ! On lui préfèrera donc la fonction qui suit...
int inet_aton (const char *cp, struct in_addr *inp);
En entrée:
cp contient la chaîne de caractères composant l'adresse IP
inp pointeur sur une structure qui recevra le résultat de la convertion
En sortie:
La fonction retourne une valeur non nulle si la convertion à réussit, 0 sinon
La fonction qui suit va permettre de convertir une adresse IP dans un format unsigned long int respectant le Host Byte Order
unsigned long int inet_network (const char *cp);
En entrée:
cp contient la chaîne de caractères composant l'adresse IP
En sortie: la codification de l'adresse IP ou -1 si l'adresse est incorrecte.
Tout comme
inet_addr (), attention à la valeur -1 (pour un nombre
non signé: $FFFFFFFF), car cela peut-être l'adresse de "broadcast"
!
La fonction qui suit est l'inverse de inet_aton, cette fois, nous partons d'un nombre (codé Network Byte Order) pour la traduire en une chaîne de caractères avec des points pour représenter l'adresse IP.
char *inet_ntoa (struct in_addr in);
En entrée:
in contient la valeur de l'adresse IP en Network Byte Order.
En sortie:
Pointeur sur une chaîne de caractères allouée dynamiquement
Chaque appel
à cette fonction efface le contenu de la précédente conversion.