dwww Home | Manual pages | Find package

getaddrinfo(3)             Library Functions Manual             getaddrinfo(3)

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

BIBLIOTHÈQUE
       Bibliothèque C standard (libc, -lc)

SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       #include <netdb.h>

       int getaddrinfo(const char *restrict node,
                       const char *restrict service,
                       const struct addrinfo *restrict hints,
                       struct addrinfo **restrict 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() :
           Depuis la glibc 2.22 :
               _POSIX_C_SOURCE >= 200112L
           glibc 2.21 et antérieure :
               _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  getad-
       drinfo() combine la fonctionnalité fournie par les fonctions gethostby-
       name(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  ren-
              voyé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 so-
              cket.

       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-des-
              sous.  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_pro-
       tocol à 0, ai_family à AF_UNSPEC et ai_flags à  (AI_V4MAPPED | AI_ADDR-
       CONFIG).  (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_NUME-
       RICHOST 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 com-
       muniquer avec des correspondants s'exécutant sur la même machine.

       service  définit  le  port  dans chacune des structures d'adresses ren-
       voyé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 so-
       cket 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_canon-
       name 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 initia-
       lisés de la façon suivante :

       •  Les champs ai_family, ai_socktype et ai_protocol renvoient  les  pa-
          ramètres  de  création de la socket (c'est-à-dire que ces champs ont
          la même signification  que  les  paramètres  correspondants  de  so-
          cket(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  sys-
       tè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 ren-
       voyées dans la liste pointée par res. Si AI_V4MAPPED et AI_ALL sont in-
       diqué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 dynami-
       quement 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  enco-
              dé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  compo-
              santes  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  at-
              tributs « IDNA_ALLOW_UNASSIGNED » (permettre des caractères Uni-
              code 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) uti-
              lisé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 deman-
              dé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  à  IP-
              PROTO_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 in-
              consistants (par exemple, SOCK_DGRAM et IPPROTO_TCP, respective-
              ment).

       EAI_SYSTEM
              Autre  erreur  système,  la valeur de retour est -1 et errno est
              défini pour indiquer l'erreur.

       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()            │                      │                    │
       └──────────────────────────┴──────────────────────┴────────────────────┘

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

NOTES
       getaddrinfo() gère la notation address%scope-id pour indiquer l'identi-
       fiant scope de IPv6.

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

       Selon POSIX.1, 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 va-
       leur est considérée comme une amélioration de la spécification.

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 <netdb.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/socket.h>
       #include <sys/types.h>
       #include <unistd.h>

       #define BUF_SIZE 500

       int
       main(int argc, char *argv[])
       {
           int                      sfd, s;
           char                     buf[BUF_SIZE];
           ssize_t                  nread;
           socklen_t                peer_addrlen;
           struct addrinfo          hints;
           struct addrinfo          *result, *rp;
           struct sockaddr_storage  peer_addr;

           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 (;;) {
               char host[NI_MAXHOST], service[NI_MAXSERV];

               peer_addrlen = sizeof(peer_addr);
               nread = recvfrom(sfd, buf, BUF_SIZE, 0,
                                (struct sockaddr *) &peer_addr, &peer_addrlen);
               if (nread == -1)
                   continue;               /* Ignore failed request */

               s = getnameinfo((struct sockaddr *) &peer_addr,
                               peer_addrlen, 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_addrlen) != nread)
               {
                   fprintf(stderr, "Error sending response\n");
               }
           }
       }

   Programme du client

       #include <netdb.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/socket.h>
       #include <sys/types.h>
       #include <unistd.h>

       #define BUF_SIZE 500

       int
       main(int argc, char *argv[])
       {
           int              sfd, s;
           char             buf[BUF_SIZE];
           size_t           len;
           ssize_t          nread;
           struct addrinfo  hints;
           struct addrinfo  *result, *rp;

           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 (size_t 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 %zu\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)

TRADUCTION
       La traduction française de cette page de manuel a été créée par  Chris-
       tophe  Blaess  <https://www.blaess.fr/christophe/>, Stéphan Rafin <ste-
       phan.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.cou-
       lon@wanadoo.fr>,  Julien  Cristau <jcristau@debian.org>, Thomas Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François  <nicolas.francois@centra-
       liens.net>,  Florentin  Duneau <fduneau@gmail.com>, Simon Paillard <si-
       mon.paillard@resel.enst-bretagne.fr>,   Denis   Barbier    <barbier@de-
       bian.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⟩.

Pages du manuel de Linux 6.03   5 février 2023                  getaddrinfo(3)

Generated by dwww version 1.15 on Sat Jun 29 01:41:56 CEST 2024.