table of contents
GETADDRINFO(3) | Manuel du programmeur Linux | GETADDRINFO(3) |
NOM¶
getaddrinfo, freeaddrinfo, gai_strerror - Traduction d'adresses et de services réseauSYNOPSIS¶
#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)) :
_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 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; 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 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 ci-dessous. Plusieurs attributs peuvent être indiqués en les groupant par un OU binaire.
- *
- 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.
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.
- 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.
- 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étails.
FICHIERS¶
/etc/gai.confCONFORMITɶ
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.EXEMPLE¶
Le programme suivant explique l'utilisation de getaddrinfo(), gai_strerror(), freeaddrinfo(), et getnameinfo(3). Les programmes sont des clients et serveursProgramme 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¶
getaddrinfo_a(3), gethostbyname(3), getnameinfo(3), inet(3), hostname(7), ip(7)COLOPHON¶
Cette page fait partie de la publication 3.44 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> ».29 avril 2012 | GNU |