L'objectif de cette section est de fournir un programme minimaliste qui affiche les adresses IP associées à un hôte ou à une interface réseau. Le code source de ce programme fait donc appel à la fonction getaddrinfo(). Cette fonction offre de nombreuses options mais son utilisation reste simple. Elle s'appuie sur l'enregistrement de type addrinfo. Ce type permet de constituer une liste chaînée des différentes adresses disponibles.
![]() |
Note |
|---|---|
|
Cette section suit la démarche proposée dans le livre Beej's Guide to Network Programming. Relativement au code proposé dans cet excellent guide, les modifications apportées ici sont marginales. Elles ont cependant une incidence sur l'organisation du code des sections suivantes. |
Le programme showip est constitué d'un appel à la fonction getaddrinfo() suivi d'une boucle de parcours des enregistrements renseignés lors de l'appel. Cette boucle de parcours est reprise ensuite dans tous les autres programmes de ce document.
Appel à getaddrinfo()
struct addrinfo hints, *res, *p;<snipped/> memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // IPv4 ou IPv6 hints.ai_socktype = SOCK_STREAM; // Une seule famille de socket if ((status = getaddrinfo(argv[1]
, NULL, &hints, &res
)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)
); return 2; }
|
On utilise 3 variables de type |
|
|
Les options choisies pour l'appel à |
|
|
Les paramètres du programme showip sont passés directement en ligne de commande de façon classique ; |
|
|
Le pointeur |
|
|
En cas d'erreur sur l'interprétation de la chaîne fournie dans |
Boucle de parcours des enregistrements addrinfo
<snipped/>
printf("IP addresses for %s:\n\n", argv[1]);
p = res;
while (p != NULL) {
// Identification de l'adresse courante
<snipped/>
// Adresse suivante
p = p->ai_next;
}
|
Le pointeur |
|
|
Si cette adresse vaut |
|
|
On fait pointer |
Cette technique de parcours des enregistrements de type addrinfo est reprise dans les sections suivantes pour définir les conditions d'ouverture des «prises» réseau ou sockets.
Exemple d'utilisation du programme showip
L'exemple donné ci-dessous montre que deux adresses IP sont assoicées au nom d'hôte vm1.fake.domain.
$ ./showip.o vm1.fake.domain
IP addresses for vm1.fake.domain:
IPv6: 2001:db8:feb2:10::11
IPv4: 192.0.2.11
Code source complet du programme showip.c
/*
* showip.c -- Affiche les adresses IP correspondant à un nom d'hôte donné en
* ligne de commande
*
* This code was first published in the
* Beej's Guide to Network Programming
* Credit has to be given back to beej(at)beej.us
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
int main (int argc, char *argv[]) {
struct addrinfo hints, *res, *p;
void *addr;
int status;
char ipstr[INET6_ADDRSTRLEN], ipver;
if (argc != 2) {
fprintf(stderr, "usage: showip hostname\n");
return 1;
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // IPv4 ou IPv6
hints.ai_socktype = SOCK_STREAM; // Une seule famille de socket
if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return 2;
}
printf("IP addresses for %s:\n\n", argv[1]);
p = res;
while (p != NULL) {
// Identification de l'adresse courante
if (p->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = '4';
}
else { // IPv6
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = '6';
}
// Conversion de l'adresse IP en une chaîne de caractères
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
printf(" IPv%c: %s\n", ipver, ipstr);
// Adresse suivante
p = p->ai_next;
}
// Libération de la mémoire occupée par les enregistrements
freeaddrinfo(res);
return 0;
}

![[Note]](/images/note.png)

