Provided by: manpages-fr-dev_3.27fr1.4-1_all bug

NOM

       getaddrinfo,  freeaddrinfo,  gai_strerror - Traduction d'adresses et de
       services réseau

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 fonctionnalités  pour  la  glibc  (consultez
   feature_test_macros(7)) :

       getaddrinfo(), freeaddrinfo(), gai_strerror() :
           _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

DESCRIPTION

       Étant  donnés  node  et service, qui identifient un hôte Internet et un
       service, getaddrinfo() renvoie une  ou  plusieurs  structure  addrinfo,
       chacune  d'entre  elles  contenant une adresse Internet qui puisse être
       indiquée  dans  un  appel  à  bind(2)  ou   connect(2).   La   fonction
       getaddrinfo()  combine  la  fonctionnalité  fournie  par  les fonctions
       getservbyname(3) et getservbyport(3) en une interface  unique,  mais  à
       l'inverse  de ces fonctions, getaddrinfo() est réentrante et permet aux
       programmes d'éliminer la dépendance envers IPv4 ou IPv6.

       La structure addrinfo utilisée 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  paramètre  hints pointe sur une structure addrinfo qui spécifie les
       critères de sélection des structures d'adresses  de  sockets  renvoyées
       dans la liste pointée 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  critères limitant l'ensemble d'adresses de
       sockets renvoyées par getaddrinfo(), de la façon suivante :

       ai_family   Ce champ indique la famille d'adresse désirée des  adresses
                   renvoyées.  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 être
                   utilisées avec node et service.

       ai_socktype Ce  champ  indique  le  type préféré 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
                   renvoyées. 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  supplémentaires, décrites
                   ci-dessous. Plusieurs attributs peuvent  être  indiqués  en
                   les groupant par un OU binaire.

       Tous  les  autres  membres  de  la  structure pointée par hints doivent
       contenir 0 ou être des pointeurs  NULL.  Spécifier  hints  à  NULL  est
       équivalent  à  définir  ai_socktype  et  ai_protocol  à  0, ai_family à
       AF_UNSPEC et ai_flags à (AI_V4MAPPED | AI_ADDRCONFIG).

       node indique soit une  adresse  réseau  en  format  numérique  (décimal
       pointé   pour   l'IPv4,   comme  prise  en  charge  par  inet_aton(3) ;
       hexadécimal pour l'IPv6, comme prise en charge par inet_pton(3)),  soit
       un  nom  d'hôte,  dont l'adresse réseau est alors résolue. Si le membre
       hints.ai_flags contient l'attribut AI_NUMERICHOST alors node devra être
       une  adresse  réseau numérique. L'attribut AI_NUMERICHOST empêche toute
       tentative, éventuellement longue, de résolution de nom d'hôte.

       Si l'attribut AI_PASSIVE est indiqué dans hints.ai_flags,  et  si  node
       est NULL, les adresses de socket renvoyées seront pertinentes pour lier
       (bind(2)) un socket  qui  acceptera  (accept(2))  les  connexions.  Les
       adresses de socket renvoyées contiendront l'« adresse joker » (wildcard
       adress) (INADDR_ANY pour les adresses IPv4, IN6ADDR_ANY_INIT  pour  les
       adresses  IPv6).  L'« adresse joker » est utilisée par des applications
       (typiquement  des  serveurs)  qui  ont   l'intention   d'accepter   des
       connexions  de  n'importe quel hôte. Si node n'est pas NULL, l'attribut
       AI_PASSIVE est ignoré.

       Si l'attribut AI_PASSIVE n'est pas positionné dans hints.ai_flags,  les
       adresses  de  socket  renvoyées  seront pertinentes pour être utilisées
       avec connect(2), sendto(2) ou sendmsg(2). Si node est  NULL,  l'adresse
       réseau  sera définie avec l'adresse de l'interface de boucle (loopback)
       (INADDR_LOOPBACK pour les adresses IPv4, IN6ADDR_LOOPBACK_INIT pour les
       adresses  IPv6) ;  cela  est  utilisé  par les applications qui doivent
       communiquer avec des correspondants s'exécutant sur la même machine.

       service  définit  le  port  dans  chacune  des  structures   d'adresses
       renvoyées.   Si   cet   argument  est  un  nom  de  service  (consultez
       services(5)), il est convertit en son numéro de port correspondant. Cet
       argument  peut  également  être  indiqué  sous  forme décimale, qui est
       simplement converti en binaire. Si service est NULL, le numéro de  port
       des   adresses   de   socket   renvoyées   n'est   pas  initialisé.  Si
       AI_NUMERICSERV est indiqué dans hints.ai_flags et si service n'est  pas
       NULL,  service  doit  pointer  vers  une  chaîne  contenant  une valeur
       numérique de port. Cet attribut est utilisé pour  inhiber  l'invocation
       du service de résolution des noms dans les cas où l'on sait qu'il n'est
       pas nécessaire.

       node ou service peuvent être NULL, mais pas les deux à la fois.

       La fonction getaddrinfo() alloue et initialise  une  liste  chaînée  de
       structures  addrinfo,  une  pour  chaque adresse réseau correspondant à
       node et service,  soumise  aux  restrictions  imposées  par  l'argument
       hints,  et  renvoie  dans res un pointeur sur le début de la liste. Les
       éléments de la liste sont chaînés par le champ ai_next.

       Il y a plusieurs raisons pour lesquelles la liste  chaînée  peut  avoir
       plus  d'une structure addrinfo : l'hôte réseau est « multi-homed » ; le
       même 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 où elles sont renvoyées. La fonction de tri utilisée  dans
       getaddrinfo() est définie dans la RFC 3484 ; le tri peut être configuré
       pour un système 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 première structure addrinfo de la liste renvoyée est
       défini pour pointer vers le nom officiel de l'hôte.

       Les   champs  restants  de  chaque  structure  addrinfo  renvoyée  sont
       initialisés de la façon suivante :

       * Les  champs  ai_family,  ai_socktype  et  ai_protocol  renvoient  les
         paramètres  de création de la socket (c'est-à-dire que ces champs ont
         la  même  signification  que   les   paramètres   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 placé 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 renvoyées dans la liste  pointée  par  res  seulement  si  le
       système  local  possède  au  moins  une  adresse  IPv4  configurée. Des
       adresses IPv6 sont seulement renvoyées si le système local  possède  au
       moins une adresse IPv6 configurée.

       Si hint.ai_flags spécifie le drapeau AI_V4MAPPED, et si hints.ai_family
       a été spécifié avec AF_INET6 et qu'aucune adresse  IPv6  correspondante
       n'a  pu  être  trouvée,  alors  des  adresses  IPv4 au format IPv6 sont
       renvoyées dans la liste pointée par res. Si AI_V4MAPPED et AI_ALL  sont
       spécifiés  dans  hints.ai_flags, des adresses IPv6 et des adresses IPv4
       au format IPv6 sont renvoyées dans la liste pointée par res. AI_ALL est
       ignoré si AI_V4MAPPED n'est pas aussi spécifié.

       La  fonction  freeaddrinfo()  libère  la  mémoire  qui  a  été  allouée
       dynamiquement pour la liste chaînée res.

   Extensions de getaddrinfo() pour les noms de domaines internationalisés
       Depuis la glibc 2.3.4, getaddrinfo() a été modifié  pour  sélectivement
       permettre que les noms d'hôtes entrant et sortant soient convertis vers
       ou depuis le format  des  noms  de  domaines  internationalisés  (IDN).
       Consultez  la RFC 3490, Internationalizing Domain Names in Applications
       (IDNA). Quatre nouveaux attributs ont été ajoutés :

       AI_IDN Si cet attribut est défini, alors le nom du  nœud  contenu  dans
              node  est  converti  dans le format IDN si nécessaire. Le format
              d'encodage choisi est celui de la locale du système.

              Si le nom du nœud contient des caractères non  ASCII,  alors  le
              format IDN est utilisé. Ces parties du nom du nœud (séparées par
              des  points)  qui  contiennent  des  caractères  non  ASCI  sont
              encodées  avec  « ASCII Compatible Encoding (ACE) » avant d'être
              transférées aux fonctions de résolution de noms.

       AI_CANONIDN
              À la suite d'une résolution de nom réussie et si AI_CANONNAME  a
              été  spécifié, getaddrinfo() retournera le nom canonique du nœud
              correspondant à la valeur de la structure  addrinfo  passée.  La
              valeur  renvoyée est une copie exacte de la valeur retournée par
              la fonction de résolution de noms.

              Si  le  nom  est  encodé  avec  ACE,  alors  une  ou   plusieurs
              composantes  de  son nom sont préfixées par xn--. Pour convertir
              ces composantes dans un format lisible,  l'attribut  AI_CANONIDN
              peut  être utilisé en plus de AI_CANONNAME. La chaîne résultante
              est encodée selon la locale du système.

       AI_IDN_ALLOW_UNASSIGNED, AI_IDN_USE_STD3_ASCII_RULES
              Utiliser  ces  attributs  permet  d'activer  respectivement  les
              attributs  « IDNA_ALLOW_UNASSIGNED »  (permettre  des caractères
              Unicode non assignés) et « IDNA_USE_STD3_ASCII_RULES » (vérifier
              la  sortie  pour être sûr que le nom d'hôte est conforme à STD3)
              utilisés dans la gestion de l'IDNA.

VALEUR RENVOYÉE

       getaddrinfo() renvoie 0 si elle réussit, ou l'un des codes d'erreur non
       nuls suivants :

       EAI_ADDRFAMILY
              L'hôte   indiqué  n'a  pas  d'adresse  dans  la  famille  réseau
              demandée.

       EAI_AGAIN
              Le serveur de noms a renvoyé une  erreur  temporaire.  Réessayez
              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 renvoyé une erreur définitive.

       EAI_FAMILY
              La famille d'adresse réclamée n'est pas supportée.

       EAI_MEMORY
              Plus de mémoire disponible.

       EAI_NODATA
              L'hôte existe mais n'a pas d'adresse réseau définie.

       EAI_NONAME
              node ou service sont inconnus ou ils sont tous les  deux  NULL ;
              ou  AI_NUMERICSERV  a  été  spécifié  dans  hints.ai_flags  mais
              service n'est pas un numéro de port.

       EAI_SERVICE
              Le service demandé n'est pas disponible pour le type  de  socket
              demandé.  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  égal   à
              IPPROTO_UDP  ou soit si hints.ai_socktype est égal à SOCK_DGRAM.
              L'erreur peut aussi se produire  si  service  est  non  NULL  et
              hints.ai_socktype  est égal à SOCK_RAW (un type de socket qui ne
              gère pas le concept de service).

       EAI_SOCKTYPE
              Le type de socket demandé n'est pas géré. 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 système, voir errno pour plus de détails.

       La  fonction gai_strerror() traduit ces codes d'erreur en une chaîne de
       caractères compréhensible, utilisable pour rendre compte du problème.

FICHIERS

       /etc/gai.conf

CONFORMITÉ

       POSIX.1-2001.  La  fonction  getaddrinfo()  est  documentée   dans   la
       RFC 2553.

NOTES

       getaddrinfo()   gère   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,  définir  hints  comme  NULL  devrait supposer que
       ai_flags soit égal à 0. La bibliothèque GNU C suppose à  la  place  que
       ai_flags  est  égal  à  of  (AI_V4MAPPED | AI_ADDRCONFIG)  dans ce cas,
       puisque cette valeur  est  considérée  comme  une  amélioration  de  la
       spécification.

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       être       trouvées      à      l'adresse
       <URL:http://www.kernel.org/doc/man-pages/>.

TRADUCTION

       Depuis 2010, cette traduction est maintenue à l'aide  de  l'outil  po4a
       <URL:http://po4a.alioth.debian.org/>   par   l'équipe   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'équipe francophone de traduction de Debian (2006-2009).

       Veuillez   signaler   toute   erreur   de   traduction  en  écrivant  à
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous  pouvez  toujours avoir accès à la version anglaise de ce document
       en utilisant la commande « man -L C <section> <page_de_man> ».