getaddrinfo et IPv6
J'essaie de comprendre ce que la fonction getaddrinfo retourne :
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
int main (int argc, char *argv[])
{
struct addrinfo *res = 0 ;
getaddrinfo("localhost", NULL ,NULL,&res);
printf("ai_flags -> %i\n", res->ai_flags) ;
printf("ai_family -> %i\n", res->ai_family) ;
printf("ai_socktype -> %i\n", res->ai_socktype) ;
printf("ai_protocol -> %i\n", res->ai_protocol) ;
printf("ai_addrlen -> %i\n", res->ai_addrlen) ;
struct sockaddr_in* saddr = (struct sockaddr_in*)res->ai_addr;
printf("ai_addr hostname -> %s\n", inet_ntoa(saddr->sin_addr));
freeaddrinfo(res);
return 0 ;
}
résultats :
ai_flags -> 40
ai_family -> 2
ai_socktype -> 1
ai_protocol -> 6
ai_addrlen -> 16
ai_addr hostname -> 127.0.0.1
Dans /etc/hosts, je 'ai :
127.0.0.1 localhost
::1 localhost
Getaddrinfo renvoie uniquement 127.0.0.1 et non pas ::1 ? Je ne comprends pas pourquoi ?
La deuxième question est: où puis-je trouver la signification de ces ints (40,2,1,6 etc) ? J'ai lu l'homme, mais il n'y a rien à ce sujet.
Je voulais aussi savoir si il est possible de donner une adresse IPv6 (par exemple ::1), et la fonction retourne le nom : localhost ?
Merci beaucoup !!
- Selon la page de manuel, getaddrinfo alloue de l'espace et remplit une liste liée début at &res. Je pense qu'il serait de retour plus qu'une seule entrée, et vous devez parcourir la liste liée par res->ainext
Vous devez vous connecter pour publier un commentaire.
@jwodder et @onteria_ couvert de l'IPv6 partie bien, donc je vais juste aborder le numéros de partie:
C'est probablement va être la somme de deux
/usr/include/netdb.h
:C'est le famille de protocole, inet, inet6, apx, unix, etc.:
C'est le type de socket, des flux, de la dgram, paquet, rdm, seqpacket:
Au plus haut niveau de protocole, TCP, UDP, TCP6, UDP6, UDPlite, ospf, icmp, etc:
Assez drôle, dans
/etc/protocols
:La taille de la
struct sockaddr
. (Varie en fonction de l'adresse de la famille! Arf.)C'est parce que vous êtes de retour d'une
struct sockaddr_in
, voirlinux/in.h
:Et la dernière, de
/etc/hosts
🙂res
contient également un champstruct addrinfo *ai_next;
, qui est un pointeur à d'autres entrées trouvées pargetaddrinfo
, ou NULL si il n'y avait pas d'autres entrées. Si vous examinezres->ai_next
, vous devriez trouver l'IPv6 entrée.Comme pour les champs de type entier dans un
struct addrinfo
, ils correspondent à des constantes prédéfinies avec la mise en œuvre définies par les valeurs, et les valeurs entières eux-mêmes ne sont pas d'intérêt général. Si vous voulez savoir ce qu'est un champ donné les moyens, de le comparer à l'une des constantes qui peuvent être affectés à ce domaine (SOCK_STREAM
,SOCK_DGRAM
, etc. pourai_socktype
;IPPROTO_TCP
,IPPROTO_UDP
, etc. pourai_protocol
; et ainsi de suite) ou, pourai_flags
, test de chaque bit correspondant à une constante prédéfinie (par exemple,if (res->ai_flags & AI_NUMERICHOST) {printf("ai_flags has AI_NUMERICHOST\n"); }
).Voici un code qui l'explique. Fondamentalement, sauf si vous donnez getaddrinfo quelques conseils pour lui dire de ne travailler qu'avec IPV6, il donne aussi IPV4 résultats. C'est pourquoi vous devez effectuer une boucle sur les résultats comme indiqué.
D'autres réponses ont été donné à la plupart des régions, mais pour répondre à cette dernière partie:
La fonction que vous voulez il ya
getnameinfo()
; donné une adresse de socket, il retourne une chaîne de caractères nom.