Provided by: manpages-fr-dev_4.13-4_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   (consulter
   feature_test_macros(7)) :

       getaddrinfo(), freeaddrinfo(), gai_strerror():
           Since glibc 2.22: _POSIX_C_SOURCE >= 200112L
           Glibc 2.21 and earlier: _POSIX_C_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.

       If the AI_PASSIVE flag is specified in hints.ai_flags, and node is NULL, then the returned
       socket   addresses   will  be  suitable  for  bind(2)ing  a  socket  that  will  accept(2)
       connections. The returned socket address will contain the "wildcard  address"  (INADDR_ANY
       for  IPv4  addresses,  IN6ADDR_ANY_INIT for IPv6 address). The wildcard address is used by
       applications (typically servers)  that intend to accept connections on any of  the  host's
       network addresses. If node is not NULL, then the AI_PASSIVE flag is ignored.

       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 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é 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

ATTRIBUTS

       Pour une explication des termes utilisés dans cette section, consulter attributes(7).

       ┌────────────────┬──────────────────────┬────────────────────┐
       │InterfaceAttributValeur             │
       ├────────────────┼──────────────────────┼────────────────────┤
       │getaddrinfo()   │ Sécurité des threads │ MT-Safe env locale │
       ├────────────────┼──────────────────────┼────────────────────┤
       │freeaddrinfo(), │ Sécurité des threads │ MT-Safe            │
       │gai_strerror()  │                      │                    │
       └────────────────┴──────────────────────┴────────────────────┘

CONFORMITÉ

       POSIX.1-2001, POSIX.1-2008. The getaddrinfo()  function is documented in 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.

       According to POSIX.1, specifying hints as NULL should cause ai_flags to be assumed  as  0.
       The  GNU C library instead assumes a value of (AI_V4MAPPED | AI_ADDRCONFIG) for this case,
       since this value is considered an improvement on the specification.

EXEMPLES

       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(hints));
           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);
           }

           freeaddrinfo(result);           /* No longer needed */

           if (rp == NULL) {               /* No address succeeded */
               fprintf(stderr, "Could not bind\n");
               exit(EXIT_FAILURE);
           }

           /* Read datagrams and echo them back to sender */

           for (;;) {
               peer_addr_len = sizeof(peer_addr);
               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;
           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(hints));
           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);
           }

           freeaddrinfo(result);           /* No longer needed */

           if (rp == NULL) {               /* No address succeeded */
               fprintf(stderr, "Could not connect\n");
               exit(EXIT_FAILURE);
           }

           /* Send remaining command-line arguments as separate
              datagrams, and read responses from server */

           for (int j = 3; j < argc; j++) {
               len = strlen(argv[j]) + 1;
                       /* +1 for terminating null byte */

               if (len > 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 5.10 du projet man-pages Linux.  Une  description
       du  projet et des instructions pour signaler des anomalies et la dernière version de cette
       page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION

       La traduction française de cette  page  de  manuel  a  été  créée  par  Christophe  Blaess
       <https://www.blaess.fr/christophe/>,  Stéphan  Rafin  <stephan.rafin@laposte.net>, Thierry
       Vignaud <tvignaud@mandriva.com>, François Micaux, Alain  Portal  <aportal@univ-montp2.fr>,
       Jean-Philippe    Guérard   <fevrier@tigreraye.org>,   Jean-Luc   Coulon   (f5ibh)   <jean-
       luc.coulon@wanadoo.fr>,   Julien    Cristau    <jcristau@debian.org>,    Thomas    Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,  Denis
       Barbier <barbier@debian.org> et David Prévot <david@tilapin.org>

       Cette  traduction  est  une  documentation libre ; veuillez vous reporter à la GNU General
       Public  License  version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   concernant   les
       conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un
       message à debian-l10n-french@lists.debian.org ⟨⟩.