Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert struct in_addr to text

Tags:

c

sockets

just wondering if I have a struct in_addr, how do I convert that back to a host name?

like image 838
hookenz Avatar asked Dec 22 '22 20:12

hookenz


2 Answers

You can use getnameinfo() by wrapping your struct in_addr in a struct sockaddr_in:

int get_host(struct in_addr addr, char *host, size_t hostlen)
{
    struct sockaddr_in sa = { .sin_family = AF_INET, .sin_addr = my_in_addr };

    return getnameinfo(&sa, sizeof sa, host, hostlen, 0, 0, 0);
}
like image 75
caf Avatar answered Jan 11 '23 01:01

caf


Modern code should not use struct in_addr directly, but rather sockaddr_in. Even better would be to never directly create or access any kind of sockaddr structures at all, and do everything through the getaddrinfo and getnameinfo library calls. For example, to lookup a hostname or text-form ip address:

struct addrinfo *ai;
if (getaddrinfo("8.8.8.8", 0, 0, &ai)) < 0) goto error;

And to get the name (or text-form ip address if it does not reverse-resolve) of an address:

if (getnameinfo(ai.ai_addr, ai.ai_addrlen, buf, sizeof buf, 0, 0, 0) < 0) goto error;

The only other time I can think of when you might need any sockaddr type structures is when using getpeername or getsockname on a socket, or recvfrom. Here you should use sockaddr_storage unless you know the address family a priori.

I give this advice for 3 reasons:

  1. It's a lot easier doing all of your string-to-address-and-back conversion with these two functions than writing all the cases (to handle lookup failures and trying to parse the address as an ip, etc.) separately.
  2. Coding this way makes it trivial to support IPv6 (and potentially other non-IPv4) protocols.
  3. The old functions gethostbyname and gethostbyaddr were actually removed from the latest version of POSIX because they were considered so obsolete/deprecated/broken.
like image 37
R.. GitHub STOP HELPING ICE Avatar answered Jan 10 '23 23:01

R.. GitHub STOP HELPING ICE