Loading

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  (voir
   feature_test_macros(7)) :

       getaddrinfo(), freeaddrinfo(), gai_strerror() : _POSIX_C_SOURCE>= 1 ||
       _XOPEN_SOURCE || _POSIX_SOURCE

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

       Le paramètre hints pointe sur une structure addrinfo qui  spécifie  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. Les valeurs valides de ce champ inclues  AF_INET
                   et  AF_INET6. 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 plus
                   loin.   Divers  attributs  peuvent  être  indiqués  en  les
                   regroupant 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).

       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))  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
       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 (voir 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 « multi-homed » ; 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 le drapeau 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.

       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 res. 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 res. AI_ALL est
       ignoré si AI_V4MAPPED n’est pas aussi spécifié.

       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
              hints.ai_flags    contient    des    drapeaux   invalides ;   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é  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
              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é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.

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 GNU C suppose à  la  place  que
       ai_flags  est  égal  à  of  (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 %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");
           }
       }

   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 %ld bytes: %s\n", (long) nread, buf);
           }

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       gethostbyname(3), getnameinfo(3), inet(3), hostname(7), ip(7)

COLOPHON

       Cette  page  fait  partie  de  la  publication 3.23 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> ».