Provided by: manpages-fr-dev_2.64.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

       La fonction getaddrinfo(3) combine les possibilités  offertes  par  les
       fonctions  getipnodebyname(3), getipnodebyaddr(3), getservbyname(3), et
       getservbyport(3) en une unique interface. La  fonction  getaddrinfo(3),
       adaptée  aux  contextes multi-threads, crée une ou plusieurs structures
       d’adresses de socket, utilisables par bind(2) et connect(2) pour  créer
       une socket de client ou de serveur.

       La  fonction getaddrinfo(3) n’est pas limitée aux structures d’adresses
       IPv4, elle permet également  la  création  de  structures  IPv6  si  le
       support  en  est  disponible.  Ces  structures  peuvent  être utilisées
       directement par bind(2) ou connect(2),  pour  préparer  une  socket  de
       client ou de serveur.

       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(3)  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).

       Les   membres   ai_family,  ai_socktype  et  ai_protocol  ont  la  même
       signification que leurs homologues de  l’appel  système  socket(2).  La
       fonction  getaddrinfo(3) renvoie les adresses de sockets autant en IPv4
       qu’en IPv6 (ai_family contiendra AF_INET ou AF_INET6).

       L’argument hints permet de préciser le type préféré  de  socket  ou  de
       protocole. Un argument hints NULL indique que tout type d’adresse ou de
       protocole est acceptable. 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.

       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(3)  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.  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.

       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 le membre ai_flags de l’argument hints. 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(3)  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(3) 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
              Pas assez de mémoire.

       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(3) 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 */

             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().
                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().
                If socket() (or connect()) 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

       getipnodebyaddr(3), getipnodebyname(3)  getnameinfo(3),

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