Reputation: 103
Im using getnameinfo() function from the BSD socket API to get addresses from a host, i want get all kind of address available:
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_ALL;
struct addrinfo *peer_address;
if (getaddrinfo(argv[1], NULL, &hints, &peer_address)) {
fprintf(stderr, "getaddrinfo() ERROR.\n");
return EXIT_FAILURE;
}
printf("Remote address(es):\n");
struct addrinfo *address = peer_address;
while((address = address->ai_next)) {
char address_buffer[100];
getnameinfo(address->ai_addr, address->ai_addrlen,
address_buffer, sizeof(address_buffer), 0, 0, NI_NUMERICHOST);
printf("\t> %s\n", address_buffer);
}
freeaddrinfo(peer_address);
and building and running this code i get that output:
$lookup google.com
Remote address(es):
> 172.217.203.100
> 172.217.203.100
> 172.217.203.102
> 172.217.203.102
> 172.217.203.102
.
.
.
> 2607:f8b0:400c:c07::8a
> 2607:f8b0:400c:c07::8a
> 2607:f8b0:400c:c07::8a
why every IP address is printed two or three times?
Upvotes: 1
Views: 425
Reputation: 4247
You're seeing the effect of an overly-unspecified hints
variable, which would normally narrow down the list to just what you're asking for.
When you ask for everything, it appears that for each IP address, there's an entry for tcp (SOCK_STREAM
), udp (SOCK_DGRAM
), plus just IP (SOCK_RAW
), but in the case of just looking up IP addresses--as opposed to services--I don't see how this is useful.
Easy way to fix this is to update your hints:
struct addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_ALL;
hints.ai_socktype = SOCK_RAW; // ADD ME
Also, your loop does skip the first entry, so an alternate could be:
for (struct addrinfo *address = peer_address
; address != 0
; address = address->ai_next )
{
// do stuff
A helpful reference: What's the "hints" mean for the addrinfo name in socket programming
Upvotes: 1