Skip to content

Instantly share code, notes, and snippets.

@jirihnidek
Last active October 31, 2023 20:09
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save jirihnidek/bf7a2363e480491da72301b228b35d5d to your computer and use it in GitHub Desktop.
Save jirihnidek/bf7a2363e480491da72301b228b35d5d to your computer and use it in GitHub Desktop.
Example of getaddrinfo() program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int
lookup_host (const char *host)
{
struct addrinfo hints, *res, *result;
int errcode;
char addrstr[100];
void *ptr;
memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
errcode = getaddrinfo (host, NULL, &hints, &result);
if (errcode != 0)
{
perror ("getaddrinfo");
return -1;
}
res = result;
printf ("Host: %s\n", host);
while (res)
{
inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100);
switch (res->ai_family)
{
case AF_INET:
ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
break;
}
inet_ntop (res->ai_family, ptr, addrstr, 100);
printf ("IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4,
addrstr, res->ai_canonname);
res = res->ai_next;
}
freeaddrinfo(result);
return 0;
}
int main (void)
{
char inbuf[256];
int len;
do {
bzero(inbuf, 256);
printf("Type domain name:\n");
fgets(inbuf, 256, stdin);
len = strlen(inbuf);
inbuf[len-1] = '\0';
if(strlen(inbuf) > 0)
lookup_host (inbuf);
else
return EXIT_SUCCESS;
} while(1);
}
@modelorona
Copy link

Hi, I am new to C and networks, so I have a question (and please correct me if I am wrong). On line 32, you use inet_ntop to get the human readable address and then under have a switch statement which determines if the res family is ipv4 or ipv6. My question is could you not remove that first inet_ntop and have the switch be the first statement in the while loop?

I am curious as to why you have two calls to inet_ntop, because when I tried locally and removed the call on line 32, it worked the same way I believe.

@deluxor
Copy link

deluxor commented Oct 21, 2020

This is perfect to test /etc/gai.conf changes!
Thank you.

@jirihnidek
Copy link
Author

Hi, I am new to C and networks, so I have a question (and please correct me if I am wrong). On line 32, you use inet_ntop to get the human readable address and then under have a switch statement which determines if the res family is ipv4 or ipv6. My question is could you not remove that first inet_ntop and have the switch be the first statement in the while loop?

I am curious as to why you have two calls to inet_ntop, because when I tried locally and removed the call on line 32, it worked the same way I believe.

Sorry for late response. I just missed your question. No clue why.
And yeah, you are right. It is possible to delete line 32 (caused probably by some copy-paste). I will update this example.

@jirihnidek
Copy link
Author

This is perfect to test /etc/gai.conf changes!
Thank you.

You are welcome! 😃

@pcx436
Copy link

pcx436 commented Nov 22, 2020

Hey, just wanted to say this really helped me out, thanks for posting it!

@saiprasad2210
Copy link

This is quite handy, But there is memory leak in the above API, we are not freeing the response structure returned getaddrinfo. Need to add below to avoid leaking memory

freeaddrinfo(res);

@jirihnidek
Copy link
Author

Using freeaddrinfo(res); should not be necessary according comments in man page, but it is good idea to add it there, when you are saying that it's causing memory leaks in some cases.

@chkoreff
Copy link

I am curious as to why you have two calls to inet_ntop, because when I tried locally and removed the call on line 32, it worked the same way I believe.

Yes, I just noticed the same thing. That first call to inet_ntop is useless. In fact, it looks flawed, because if you pound out the second call to inet_ntop, you see IP address that are shifted right, such as 0.0.74.207 instead of the full 74.207.231.33.

@lanurmi
Copy link

lanurmi commented Jun 5, 2023

Calling perror() is not the correct way to get an error message, because getaddrinfo() does not set errno (on most platforms anyway). gai_strerror(errcode) should be called instead on line 25.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment