Provided by:
manpages-fr-dev_3.27fr1.4-1_all 
NOM
getaddrinfo, freeaddrinfo, gai_strerror - Traduction d'adresses et de
services reseau
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
const char *gai_strerror(int errcode);
Exigences de macros de test de fonctionnalites pour la glibc (consultez
feature_test_macros(7)) :
getaddrinfo(), freeaddrinfo(), gai_strerror() :
_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
DESCRIPTION
Etant donnes node et service, qui identifient un hote Internet et un
service, getaddrinfo() renvoie une ou plusieurs structure addrinfo,
chacune d'entre elles contenant une adresse Internet qui puisse etre
indiquee dans un appel a bind(2) ou connect(2). La fonction
getaddrinfo() combine la fonctionnalite fournie par les fonctions
getservbyname(3) et getservbyport(3) en une interface unique, mais a
l'inverse de ces fonctions, getaddrinfo() est reentrante et permet aux
programmes d'eliminer la dependance envers IPv4 ou IPv6.
La structure addrinfo utilisee par getaddrinfo() contient les membres
suivants :
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
Le parametre hints pointe sur une structure addrinfo qui specifie les
criteres de selection des structures d'adresses de sockets renvoyees
dans la liste pointee par res. Si hints n'est pas NULL, il doit pointer
sur une structure addrinfo dont les membres ai_family, ai_socktype, et
ai_protocol indiquent les criteres limitant l'ensemble d'adresses de
sockets renvoyees par getaddrinfo(), de la facon suivante :
ai_family Ce champ indique la famille d'adresse desiree des adresses
renvoyees. Les valeurs valides de ce champ inclues AF_INET
et AF_INET6. La valeur AF_UNSPEC indique que getaddrinfo()
doit renvoyer les adresses de socket de n'importe quelle
famille d'adresses (par exemple, IPv4 ou IPv6) pouvant etre
utilisees avec node et service.
ai_socktype Ce champ indique le type prefere de socket, par exemple
SOCK_STREAM ou SOCK_DGRAM. Mettre 0 dans ce champ indique
que getaddrinfo() peut renvoyer n'importe quel type
d'adresse de socket.
ai_protocol Ce champ indique le protocole des adresses de socket
renvoyees. Mettre 0 dans ce champ indique que getaddrinfo()
peut renvoyer des adresses de socket de n'importe quel
type.
ai_flags Ce champ indique des options supplementaires, decrites
ci-dessous. Plusieurs attributs peuvent etre indiques en
les groupant par un OU binaire.
Tous les autres membres de la structure pointee par hints doivent
contenir 0 ou etre des pointeurs NULL. Specifier hints a NULL est
equivalent a definir ai_socktype et ai_protocol a 0, ai_family a
AF_UNSPEC et ai_flags a (AI_V4MAPPED | AI_ADDRCONFIG).
node indique soit une adresse reseau en format numerique (decimal
pointe pour l'IPv4, comme prise en charge par inet_aton(3) ;
hexadecimal pour l'IPv6, comme prise en charge par inet_pton(3)), soit
un nom d'hote, dont l'adresse reseau est alors resolue. Si le membre
hints.ai_flags contient l'attribut AI_NUMERICHOST alors node devra etre
une adresse reseau numerique. L'attribut AI_NUMERICHOST empeche toute
tentative, eventuellement longue, de resolution de nom d'hote.
Si l'attribut AI_PASSIVE est indique dans hints.ai_flags, et si node
est NULL, les adresses de socket renvoyees seront pertinentes pour lier
(bind(2)) un socket qui acceptera (accept(2)) les connexions. Les
adresses de socket renvoyees contiendront l'<< adresse joker >>
(wildcard adress) (INADDR_ANY pour les adresses IPv4, IN6ADDR_ANY_INIT
pour les adresses IPv6). L'<< adresse joker >> est utilisee par des
applications (typiquement des serveurs) qui ont l'intention d'accepter
des connexions de n'importe quel hote. Si node n'est pas NULL,
l'attribut AI_PASSIVE est ignore.
Si l'attribut AI_PASSIVE n'est pas positionne dans hints.ai_flags, les
adresses de socket renvoyees seront pertinentes pour etre utilisees
avec connect(2), sendto(2) ou sendmsg(2). Si node est NULL, l'adresse
reseau sera definie avec l'adresse de l'interface de boucle (loopback)
(INADDR_LOOPBACK pour les adresses IPv4, IN6ADDR_LOOPBACK_INIT pour les
adresses IPv6) ; cela est utilise par les applications qui doivent
communiquer avec des correspondants s'executant sur la meme machine.
service definit le port dans chacune des structures d'adresses
renvoyees. Si cet argument est un nom de service (consultez
services(5)), il est convertit en son numero de port correspondant. Cet
argument peut egalement etre indique sous forme decimale, qui est
simplement converti en binaire. Si service est NULL, le numero de port
des adresses de socket renvoyees n'est pas initialise. Si
AI_NUMERICSERV est indique dans hints.ai_flags et si service n'est pas
NULL, service doit pointer vers une chaine contenant une valeur
numerique de port. Cet attribut est utilise pour inhiber l'invocation
du service de resolution des noms dans les cas ou l'on sait qu'il n'est
pas necessaire.
node ou service peuvent etre NULL, mais pas les deux a la fois.
La fonction getaddrinfo() alloue et initialise une liste chainee de
structures addrinfo, une pour chaque adresse reseau correspondant a
node et service, soumise aux restrictions imposees par l'argument
hints, et renvoie dans res un pointeur sur le debut de la liste. Les
elements de la liste sont chaines par le champ ai_next.
Il y a plusieurs raisons pour lesquelles la liste chainee peut avoir
plus d'une structure addrinfo : l'hote reseau est << multi-homed >> ;
le meme service est accessible depuis plusieurs protocoles (par exemple
AF_INET et AF_INET6) ou accessible depuis plusieurs types de socket
(par exemple, une adresse de type SOCK_STREAM et une autre de type
SOCK_DGRAM). Normalement, l'application essaie d'utiliser les adresses
dans l'ordre ou elles sont renvoyees. La fonction de tri utilisee dans
getaddrinfo() est definie dans la RFC 3484 ; le tri peut etre configure
pour un systeme particulier avec le fichier /etc/gai.conf (disponible
depuis la glibc 2.5).
Si hints.ai_flags contient l'attribut AI_CANONNAME, le champ
ai_canonname de la premiere structure addrinfo de la liste renvoyee est
defini pour pointer vers le nom officiel de l'hote.
Les champs restants de chaque structure addrinfo renvoyee sont
initialises de la facon suivante :
* Les champs ai_family, ai_socktype et ai_protocol renvoient les
parametres de creation de la socket (c'est-a-dire que ces champs ont
la meme signification que les parametres correspondants de
socket(2)). Par exemple, ai_family pourrait renvoyer AF_INET ou
AF_INET6 ; ai_socktype pourrait renvoyer SOCK_DGRAM ou SOCK_STREAM ;
et ai_protocol renvoie le protocole de la socket.
* Un pointeur vers l'adresse de la socket est place dans le champ
ai_addr, et la longueur de l'adresse de la socket, en octets, est
inscrite dans le champ ai_addrlen de la structure.
Si hints.ai_flags inclut le drapeau AI_ADDRCONFIG, alors des adresses
IPv4 sont renvoyees dans la liste pointee par res seulement si le
systeme local possede au moins une adresse IPv4 configuree. Des
adresses IPv6 sont seulement renvoyees si le systeme local possede au
moins une adresse IPv6 configuree.
Si hint.ai_flags specifie le drapeau AI_V4MAPPED, et si hints.ai_family
a ete specifie avec AF_INET6 et qu'aucune adresse IPv6 correspondante
n'a pu etre trouvee, alors des adresses IPv4 au format IPv6 sont
renvoyees dans la liste pointee par res. Si AI_V4MAPPED et AI_ALL sont
specifies dans hints.ai_flags, des adresses IPv6 et des adresses IPv4
au format IPv6 sont renvoyees dans la liste pointee par res. AI_ALL est
ignore si AI_V4MAPPED n'est pas aussi specifie.
La fonction freeaddrinfo() libere la memoire qui a ete allouee
dynamiquement pour la liste chainee res.
Extensions de getaddrinfo() pour les noms de domaines internationalis'es
Depuis la glibc 2.3.4, getaddrinfo() a ete modifie pour selectivement
permettre que les noms d'hotes entrant et sortant soient convertis vers
ou depuis le format des noms de domaines internationalises (IDN).
Consultez la RFC 3490, Internationalizing Domain Names in Applications
(IDNA). Quatre nouveaux attributs ont ete ajoutes :
AI_IDN Si cet attribut est defini, alors le nom du noeud contenu dans
node est converti dans le format IDN si necessaire. Le format
d'encodage choisi est celui de la locale du systeme.
Si le nom du noeud contient des caracteres non ASCII, alors le
format IDN est utilise. Ces parties du nom du noeud (separees
par des points) qui contiennent des caracteres non ASCI sont
encodees avec << ASCII Compatible Encoding (ACE) >> avant d'etre
transferees aux fonctions de resolution de noms.
AI_CANONIDN
A la suite d'une resolution de nom reussie et si AI_CANONNAME a
ete specifie, getaddrinfo() retournera le nom canonique du noeud
correspondant a la valeur de la structure addrinfo passee. La
valeur renvoyee est une copie exacte de la valeur retournee par
la fonction de resolution de noms.
Si le nom est encode avec ACE, alors une ou plusieurs
composantes de son nom sont prefixees par xn--. Pour convertir
ces composantes dans un format lisible, l'attribut AI_CANONIDN
peut etre utilise en plus de AI_CANONNAME. La chaine resultante
est encodee selon la locale du systeme.
AI_IDN_ALLOW_UNASSIGNED, AI_IDN_USE_STD3_ASCII_RULES
Utiliser ces attributs permet d'activer respectivement les
attributs << IDNA_ALLOW_UNASSIGNED >> (permettre des caracteres
Unicode non assignes) et << IDNA_USE_STD3_ASCII_RULES >>
(verifier la sortie pour etre sur que le nom d'hote est conforme
a STD3) utilises dans la gestion de l'IDNA.
VALEUR RENVOY'EE
getaddrinfo() renvoie 0 si elle reussit, ou l'un des codes d'erreur non
nuls suivants :
EAI_ADDRFAMILY
L'hote indique n'a pas d'adresse dans la famille reseau
demandee.
EAI_AGAIN
Le serveur de noms a renvoye une erreur temporaire. Reessayez
plus tard.
EAI_BADFLAGS
hints.ai_flags contient des drapeaux invalides ; ou
hints.ai_flags inclut AI_CANONNAME et name est NULL.
EAI_FAIL
Le serveur de noms a renvoye une erreur definitive.
EAI_FAMILY
La famille d'adresse reclamee n'est pas supportee.
EAI_MEMORY
Plus de memoire disponible.
EAI_NODATA
L'hote existe mais n'a pas d'adresse reseau definie.
EAI_NONAME
node ou service sont inconnus ou ils sont tous les deux NULL ;
ou AI_NUMERICSERV a ete specifie dans hints.ai_flags mais
service n'est pas un numero de port.
EAI_SERVICE
Le service demande n'est pas disponible pour le type de socket
demande. Il est probablement disponible avec un autre type de
socket. Par exemple, cette erreur peut se produire si service
est << shell >> (un service uniquement disponible avec les
sockets de type flux), et soit si hints.ai_protocol est egal a
IPPROTO_UDP ou soit si hints.ai_socktype est egal a SOCK_DGRAM.
L'erreur peut aussi se produire si service est non NULL et
hints.ai_socktype est egal a SOCK_RAW (un type de socket qui ne
gere pas le concept de service).
EAI_SOCKTYPE
Le type de socket demande n'est pas gere. Cela peut se produire,
par exemple si hints.ai_socktype et hints.ai_protocol sont
inconsistants (par exemple, SOCK_DGRAM et IPPROTO_TCP,
respectivement).
EAI_SYSTEM
Autre erreur systeme, voir errno pour plus de details.
La fonction gai_strerror() traduit ces codes d'erreur en une chaine de
caracteres comprehensible, utilisable pour rendre compte du probleme.
FICHIERS
/etc/gai.conf
CONFORMIT'E
POSIX.1-2001. La fonction getaddrinfo() est documentee dans la
RFC 2553.
NOTES
getaddrinfo() gere la notation address%scope-id pour indiquer
l'identifiant scope de IPv6.
AI_ADDRCONFIG, AI_ALL et AI_V4MAPPED sont disponibles depuis la
glibc 2.3.3. AI_NUMERICSERV est disponible depuis glibc 2.3.4.
Selon POSIX.1-2001, definir hints comme NULL devrait supposer que
ai_flags soit egal a 0. La bibliotheque GNU C suppose a la place que
ai_flags est egal a of (AI_V4MAPPED | AI_ADDRCONFIG) dans ce cas,
puisque cette valeur est consideree comme une amelioration de la
specification.
EXEMPLE
Le programme suivant explique l'utilisation de getaddrinfo(),
gai_strerror(), freeaddrinfo(), et getnameinfo(3). Les programmes sont
des clients et serveurs
Programme du serveur
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc != 2) {
fprintf(stderr, "Usage: %s port\n", argv[0]);
exit(EXIT_FAILURE);
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully bind(2).
If socket(2) (or bind(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not bind\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Read datagrams and echo them back to sender */
for (;;) {
peer_addr_len = sizeof(struct sockaddr_storage);
nread = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &peer_addr, &peer_addr_len);
if (nread == -1)
continue; /* Ignore failed request */
char host[NI_MAXHOST], service[NI_MAXSERV];
s = getnameinfo((struct sockaddr *) &peer_addr,
peer_addr_len, host, NI_MAXHOST,
service, NI_MAXSERV, NI_NUMERICSERV);
if (s == 0)
printf("Received %ld bytes from %s:%s\n",
(long) nread, host, service);
else
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
if (sendto(sfd, buf, nread, 0,
(struct sockaddr *) &peer_addr,
peer_addr_len) != nread)
fprintf(stderr, "Error sending response\n");
}
}
Programme du client
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s, j;
size_t len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc < 3) {
fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Obtain address(es) matching host/port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
s = getaddrinfo(argv[1], argv[2], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully connect(2).
If socket(2) (or connect(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Send remaining command-line arguments as separate
datagrams, and read responses from server */
for (j = 3; j < argc; j++) {
len = strlen(argv[j]) + 1;
/* +1 for terminating null byte */
if (len + 1 > BUF_SIZE) {
fprintf(stderr,
"Ignoring long message in argument %d\n", j);
continue;
}
if (write(sfd, argv[j], len) != len) {
fprintf(stderr, "partial/failed write\n");
exit(EXIT_FAILURE);
}
nread = read(sfd, buf, BUF_SIZE);
if (nread == -1) {
perror("read");
exit(EXIT_FAILURE);
}
printf("Received %ld bytes: %s\n", (long) nread, buf);
}
exit(EXIT_SUCCESS);
}
VOIR AUSSI
gethostbyname(3), getnameinfo(3), inet(3), hostname(7), ip(7)
COLOPHON
Cette page fait partie de la publication 3.27 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent etre trouvees a l'adresse
<URL:http://www.kernel.org/doc/man-pages/>.
TRADUCTION
Depuis 2010, cette traduction est maintenue a l'aide de l'outil po4a
<URL:http://po4a.alioth.debian.org/> par l'equipe de traduction
francophone au sein du projet perkamon
<URL:http://perkamon.alioth.debian.org/>.
Christophe Blaess <URL:http://www.blaess.fr/christophe/> (1996-2003),
Alain Portal <URL:http://manpagesfr.free.fr/> (2003-2006). Florentin
Duneau et l'equipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en ecrivant a
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir acces a la version anglaise de ce document
en utilisant la commande << man -L C <section> <page_de_man> >>.