(Module SOI)
Structures de données dédiées aux adresses
Conversion des noms en adresses
Comme nous l'avons vu l'adressage à changé dans IPv6 par rapport à IPv4. Plus particulièrement, sa taille a augmenté, or les API sockets requièrent de l'utilisateur qu'il ait une connaissance de la taille de ces adresses dans de nombreux cas ce qui impose des modifications du code des applications anciennes. De plus les nouvelles caractéristiques disponibles ne peuvent être exploitées qu'en connaissance de cause.
Les changements apportés aux APIs ont été pensés de manière à simplifier cette migration. Il est néanmoins conseillé, tant que faire se peut, de faire cette évolution en n'utilisant que les fonctionnalités qui permettent la communication avec des hôtes IPv6 ou IPv4 de manière indifférente.
Il faut donc modifier les parties suivantes de l'API socket
D'autre part, setsockopt offre de nouvelles options IPV6_* sont toutes valables au niveau IPPROTO_IPV6. Entre autre, on peut changer le type d'une socket grâce à l'option IPV6_ADDFORM. IPV6_UNICAST_HOPS permet quant à elle de limiter la portée des paquets qui sont envoyés via cette socket. Les options multicast sont encore disponibles sous leur forme IPV6_* mais on peut désormais s'en passer, puisqu'ils sont inclus dans l'adresse.
On doit particulièrement faire attention au changement de taille de sockaddr_in qui était traditionnellement de 16 octets et qui est désormais avec sockaddr_in6 de 24 octets. Les programmeurs avaient en effet l'habitude d'en présumer à tel point que les implémentations qui ne l'assurait pas normalement mettaient des zéros de bourrages à l'intérieur pour maintenir cette longueur.
Les nouvelles structures sont désormais, sur les systèmes compatibles 4.3BSD :
etNous remarquons que le champ sin6_flowinfo a été rajouté pour coder deux informations, 24 bits pour les étiquettes de flux et 4 bits pour la priorité.
Une nouvelle fonction qui n'est pour le moment pas définitivement figée, permet de récupérer des informations sur les capacités de noeuds dans le réseau :
hostname et servname sont des chaînes de caractères fournissant les noms des machines dont on veut obtenir des informations. Dans une optique serveur traditionnelle on ne remplira que le champ servname tandis que dans l'optique client, on remplit les deux champs servname et hostname pour savoir quelles est leur compatibilité. hints est un pointeur sur addrinfo qui contient des indices permettant de trouver de manière optimale les informations voulues, il donne des précisions sur les capacités de l'appelant. res permet de récupérer l'adresse d'une liste chaînée qui contient les informations demandées.
Un exemple pour une machine ne supportant que TCP :
Une nouvelle fonction a été ajoutée pour prendre en compte les nouvelles et les anciennes adresses :
La valeur de af peut être AF_INET ou AF_INET6 et dans le premier cas on recherche une adresse IPv4 alors que dans le second on retourne une adresse IPv6. D'autre part une nouvelle option à appliquer au champ option de la structure _res : RES_USE_INET6.Si cette option est activée gethostbyname appelle gethostbyname2 dans ses deux modes disponibles, sinon elle se comporte comme avant. Le tableau suivant résume le fonctionnement de la résolution de noms dans tous les cas suscités :
|
RES_USE_INET6 off |
RES_USE_INET6 on |
|
| gethostbyname (host) | elle renvoie une adresse IPv4 sinon une erreur | elle renvoie une adresse IPv6 et si elle n’en trouve pas elle renvoie une adresse IPv4 mapped IPv6 sinon une erreur |
| gethostbyname2(host,AF_INET) | elle renvoie une adresse IPv4 sinon une erreur | elle renvoie une adresse IPv4-mapped IPv6 sinon une erreur |
| gethostbyname2(host,AF_INET6) | elle renvoie une adresse IPv6 sinon une erreur | elle renvoie une adresse IPv6 sinon une erreur |
la fonction inverse gethostbyaddr ne change pas puisqu’elle contient déjà un argument af et il suffit de lui donner la valeur AF_INET6 pour qu'elle retourne des noms correspondant à des adresses IPv6.
IPv6 s'est doté d'outils similaires qui convertissent à la fois des adresses IPv4 et IPv6 :
et inet_pton convertit une adresse texte vers une forme binaire.. La variable af spécifie le type d'adresse utilisé IPv4 ou IPv6, src est une chaine de caratères contenant la représentation imprimable de l'adresse à convertir en binaire, et dst recevra la forme binaire après conversion. Il faut prendre garde à assurer une taille suffisante à dst, dans le premier cas, pour que toutes les adresses puissent y entrer. Elle retourne 1 si la conversion marche, 0 si l'adresse n'est pas valide et -1 si af est inconnuinet_ntop convertit une forme binaire vers une adresse texte. La variable af spécifie le type d'adresse utilisé IPv4 ou IPv6, src est un tableau d'octets contenant la représentation binaire de l'adresse à convertir en ascii, dst recevra la forme texte après conversion, et size contient la taille du tableau d'octets src. Elle retourne NULL en cas d'échec ou le pointeur sur la chaîne résultante qui a la même valeur que dst.
Exemple :
Néanmoins il convient de faire attention aux nombreuses modifications des structures utilisées qui impliquent pour le programmeur des modifications de ses habitudes, et qui lui imposent de réviser toutes les suppositions implicites faites sur les particularités de celles-ci (par exemple de prendre garde au fait que sizeof(struct sockaddr) est différent de sizeof(struct sockaddr_in6) alors qu'il sont de même taille en IPv4).