I'm trying to understand what the getaddrinfo function returns :
#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 ;
}
results :
ai_flags -> 40
ai_family -> 2
ai_socktype -> 1
ai_protocol -> 6
ai_addrlen -> 16
ai_addr hostname -> 127.0.0.1
In /etc/hosts, I 've got :
127.0.0.1 localhost
::1 localhost
Getaddrinfo returns only 127.0.0.1 and not ::1 ? I don't understand why ?
The second question is where can I find the meaning of those ints (40,2,1,6 etc) ? I've read the man but there is nothing about that.
I also wanted to know if it's possible to give a IPv6 adress (for example ::1) and the function returns the name : localhost ?
Thanks a lot !!
@jwodder and @onteria_ covered the IPv6 portion well, so I'll just tackle the numbers portion:
ai_flags -> 40
Probably this is going to be the sum of the following two in /usr/include/netdb.h
:
# define AI_V4MAPPED 0x0008 /* IPv4 mapped addresses are acceptable. */
# define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose
This is the protocol family, inet, inet6, apx, unix, etc.:
ai_family -> 2
bits/socket.h:78:#define PF_INET 2 /* IP protocol family. */
bits/socket.h:119:#define AF_INET PF_INET
This is the socket type, stream, dgram, packet, rdm, seqpacket:
ai_socktype -> 1
bits/socket.h:42: SOCK_STREAM = 1, /* Sequenced, reliable, connection-based
The higher-level protocol, TCP, UDP, TCP6, UDP6, UDPlite, ospf, icmp, etc:
ai_protocol -> 6
Funny enough, in /etc/protocols
:
tcp 6 TCP # transmission control protocol
The size of the struct sockaddr
. (Differs based on the address family! Ugh.)
ai_addrlen -> 16
This is because you're getting back a struct sockaddr_in
, see linux/in.h
:
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
struct sockaddr_in {
sa_family_t sin_family; /* Address family */
__be16 sin_port; /* Port number */
struct in_addr sin_addr; /* Internet address */
/* Pad to size of `struct sockaddr'. */
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
sizeof(unsigned short int) - sizeof(struct in_addr)];
};
And the last one, from /etc/hosts
:)
ai_addr hostname -> 127.0.0.1