Provided by: manpages-fr-dev_3.65d1p1-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
       gethostbyname(3) et getservbyname(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;
               socklen_t        ai_addrlen;
               struct sockaddr *ai_addr;
               char            *ai_canonname;
               struct addrinfo *ai_next;
           };

       Le paramètre hints pointe sur une structure addrinfo qui indique 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.  AF_INET
                   et  AF_INET6  font  partie  des  valeurs  valables  pour  ce  champ. 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). (POSIX spécifie d'autres valeurs
       par défaut pour ai_flags ; consultez les NOTES.) 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)) une 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  « multihomed » ;  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 l'attribut 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. Dans ce cas, l'adresse de boucle n'est  pas  considérée
       comme  une adresse configurée valable. Cet attribut est par exemple utile sur les systèmes
       uniquement en IPv4, pour s’assurer que getaddrinfo() ne renvoie pas  d’adresse  de  socket
       IPv6 qui échouerait toujours dans connect(2) ou bind(2).

       Si hints.ai_flags indique le drapeau AI_V4MAPPED, et si hints.ai_family a été indiqué 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 indiqué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 indiqué.

       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é indiqué,
              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  incorrects ;  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é indiqué 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 C   de   GNU   suppose   à   la   place   que   ai_flags   est   égal  à
       (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 %zd bytes from %s:%s\n",
                           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 %zd bytes: %s\n", nread, buf);
           }

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       getaddrinfo_a(3), gethostbyname(3),  getnameinfo(3),  inet(3),  gai.conf(5),  hostname(7),
       ip(7)

COLOPHON

       Cette  page  fait partie de la publication 3.65 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

       Depuis    2010,    cette   traduction   est   maintenue   à   l'aide   de   l'outil   po4a
       <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du  projet
       perkamon <http://perkamon.alioth.debian.org/>.

       Christophe    Blaess    <http://www.blaess.fr/christophe/>   (1996-2003),   Alain   Portal
       <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> ».