Provided by: manpages-fr-dev_2.80.1-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);

DESCRIPTION

       Pour un noeud node et  un  service  donné,  getaddrinfo()  renvoie  une
       structure  (ou  plus)  contenant les valeurs qui peuvent être utilisées
       par les appels système bind(2) et connect(2) pour créer une socket d’un
       client   ou   d’un   serveur.  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 cette fonction 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;
           };

       La fonction getaddrinfo() fait pointer res vers une liste de structures
       addrinfo  nouvellement allouées, chaînées par leurs membres ai_next. La
       liste  peut  contenir  plusieurs  structures  addrinfo  pour  plusieurs
       raisons,  par exemple : l’hôte fonctionne en « multi-home », ou le même
       service est disponible sur  plusieurs  types  de  sockets  (une  socket
       SOCK_STREAM et une socket SOCK_DGRAM par exemple).

       Le  paramètre hints pointe vers une structure addrinfo qui spécifie des
       critères pour la sélection des structures d’adresse de socket renvoyées
       dans  la liste pointée par res. Si ce paramètre n’est pas NULL, il doit
       pointer  sur  une  structure  addrinfo  dont  les  membres   ai_family,
       ai_socktype,  et  ai_protocol  indiquent  les types de socket préférés.
       AF_UNSPEC dans  le  membre  ai_family  indique  que  toute  famille  de
       protocole  (IPv4  ou  IPv6,  par exemple) est acceptable. De même, un 0
       dans les membres ai_socktype ou ai_protocol indique que  tout  type  de
       socket  ou  de  protocole  est  admis.  Le  membre ai_flags indique des
       options supplémentaires  décrites  ci-dessous.  Divers  attributs  sont
       regroupés  par  un  OU  binaire.  Tous les autres membres de l’argument
       hints doivent contenir 0 ou être des pointeurs NULL.  Une  valeur  NULL
       pour  hints   est équivalente à configurer ai_socktype et ai_protocol à
       0 ;      ai_family      à      AF_UNSPEC ;      et      ai_flags      à
       (AI_V4MAPPED | AI_ADDRCONFIG).

       L’argument  node  ou l’argument service peuvent être NULL, mais pas les
       deux. node indique soit une adresse réseau en format numérique (décimal
       pointé  pour l’IPv4, hexadécimal pour l’IPv6), 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 le paramètre 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.

       La   fonction  getaddrinfo()  crée  une  liste  chaînée  de  structures
       addrinfo, une pour  chaque  adresse  réseau  soumise  aux  restrictions
       imposées par l’argument hints. Le membre ai_canonname de la première de
       ces structures addrinfo pointera vers le  nom  officiel  de  l’hôte  si
       hints.ai_flags contient l’attribut AI_CANONNAME. Les membres ai_family,
       ai_socktype, et ai_protocol indiquent les paramètres de création de  la
       socket  (c’est-à-dire  qu’ils  ont  la  même  signification  que  leurs
       homologues de l’appel système socket(2)). Un pointeur vers l’adresse de
       la socket est placé dans le membre ai_addr, et la longueur de l’adresse
       de la socket, en octets, est inscrite dans le membre ai_addrlen  de  la
       structure.

       La  fonction  getaddrinfo()  renvoie  les adresses de sockets autant en
       IPv4 qu’en IPv6 (ai_family contiendra AF_INET ou AF_INET6).

       Si l’argument node est  NULL,  l’adresse  réseau  de  chaque  structure
       socket  est  initialisée  en  fonction de l’attribut AI_PASSIVE, défini
       dans hints.ai_flags. L’adresse réseau  de  chaque  structure  sera  non
       spécifiée si l’attribut AI_PASSIVE est défini. Ceci est utilisé par les
       serveurs qui désirent accepter les connexions depuis  n’importe  quelle
       adresse.  L’adresse réseau sera remplie avec l’adresse de boucle locale
       si l’attribut AI_PASSIVE n’est pas utilisé. Ceci est  utilisé  par  les
       clients  qui  désirent  se connecter sur un serveur fonctionnant sur le
       même hôte.

       Si hints.ai_flags inclut le drapeau AI_ADDRCONFIG, alors  des  adresses
       IPv4  sont  renvoyées  dans la liste pointée par result 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 result. Si AI_V4MAPPED et AI_ALL
       sont spécifiés dans hints.ai_family, des adresses IPv6 et des  adresses
       IPv4  au  format  IPv6 sont renvoyées dans la liste pointée par result.
       AI_ALL est ignoré si AI_V4MAPPED n’est pas aussi spécifié.

       service définit le  numéro  de  port  de  l’adresse  réseau  de  chaque
       structure  socket.  Si  service  est  NULL, le numéro de port n’est pas
       initialisé. Si AI_NUMERICSERV est spécifié dans  hints.ai_flags  et  si
       service  n’est  pas  NULL,  alors  service doit pointer vers une chaîne
       contenant le numéro de port. Ce drapeau est  utilisé  pour  inhiber  le
       service de résolution des noms  dans le cas où il ne serait pas requis.

       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
              ai_flags contient des attributs invalides.

       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 du tout.

       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
              réclamé. Il peut être disponible pour un autre type de socket.

       EAI_SOCKTYPE
              Le type de socket demandé n’est pas supporté.

       EAI_SYSTEM
              Autre erreur système, voir errno pour plus de détail.

       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.

CONFORMITÉ

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

NOTES

       AI_ADDRCONFIG,   AI_ALL  et  AI_V4MAPPED  sont  disponibles  depuis  la
       glibc 2.3.3. AI_NUMERICSERV est disponible depuis glibc 2.3.4.

EXEMPLE

       Le  programme  suivant   explique   l’utilisation   de   getaddrinfo(),
       gai_strerror(),  freeaddrinfo(), et getnameinfo(3). Les programmes sont
       des clients et serveurs

       C’est le 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");
             }
         }

       C’est le 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

       getnameinfo(3)

COLOPHON

       Cette page fait partie de  la  publication  2.80  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      être       trouvées       à       l’adresse
       http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Cette  page  de  manuel  a  été  traduite et mise à jour par Christophe
       Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003, puis  par
       Alain  Portal  <aportal AT univ-montp2 DOT fr> jusqu’en 2006, et mise à
       disposition sur http://manpagesfr.free.fr/.

       Les mises à jour et corrections de la version présente dans Debian sont
       directement gérées par Florentin Duneau <fduneau@gmail.com> et l’équipe
       francophone de traduction de Debian.

       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> ».