get host name by IP address

I'm trying to write a function to get the host name of any given IP address.

I'm trying to follow this manual but I'm stuck. I'm using gcc and Linux. Any ideas?

getnameinfo()

#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>

char *GETHOSTBYADDR(const char *INADDR_ANY)
{
    struct sockaddr_in
    {
        short        sin_family;    // e.g. AF_INET, AF_INET6
        unsigned short    sin_port;    // e.g. htons(80)
        struct in_addr    sin_addr;    // see struct in_addr, below
        char        sin_zero[8];    // zero this if you want to
    };

    struct in_addr
    {
        unsigned long s_addr;    // load with inet_pton()
    };

    struct sockaddr_in *SA;

    SA.sin_addr.s_addr = INADDR_ANY; // set the local IP address
    SA.sin_port = htons(80); // set the port number

    static char HOSTNAME[128] = "";

    getnameinfo(SA, sizeof(SA), HOSTNAME, sizeof(HOSTNAME), NULL, 0, NI_NAMEREQD);

    return HOSTNAME;
}

int main(void)
{
    puts(GETHOSTBYADDR("209.85.229.106")); // testing on google's IP

    return 0;
}

for starters -

sizeof(SA)

This returns what? the size of a pointer or the size of the struct? Hint: SA is a __ not a struct.

gcc complains about these errors but I do not understand how to solve them. In other sites I see sin_addr and sin_port not inside a structure. Passing an int to argument 1 of getnameinfo does not solve the warning.

Anybody can help?

Why are you re-defining sockaddr_in and in_addr? the definitions are already in the header files. Besides that there is no need for the structures. The only structure you need is hostent.

The way your handling SA is not correct. You define it as a pointer but never allocate memory for it. You should also be using the -> operator instead of . when accessing structure members.

Why are you calling getnameinfo()? You should call gethostbyaddr().

I know what your trying to do but you are way off. The majority of the code does not apply to what your doing.

NAME
       gethostbyaddr, gethostbyname - network host database functions

SYNOPSIS
       #include <netdb.h>

       struct hostent *gethostbyaddr(const void *addr, socklen_t len,
              int type);
       struct hostent *gethostbyname(const char *name);

I finally got it working:

char *IPtoHOST(const char *IP) // returns host name from IP address. If failure, returns IP address.
{
	static char BUFFER[65] = "";

	struct sockaddr_in SIN; // create a struct of sockaddr_in type
	memset(&SIN, 0, sizeof(SIN)); // zero SIN struct before use
	SIN.sin_family		= AF_INET; // specify address family
	SIN.sin_addr.s_addr	= inet_addr(IP); // pass the IP
	SIN.sin_port		= 0; // specify port: 0 is chosen by the system. htons(port) is for manual specification (it seems to work specifying any port so I let system choose)

	getnameinfo( (struct sockaddr *)&SIN /* type cast sockaddr_in to sockaddr */, sizeof(SIN), BUFFER, 64, NULL, 0, 0); // If the last parameter (flags) is 0 and if getnameinfo fails, then the IP is written into BUFFER instead of the host name

	return BUFFER;
}

I am curious - why would you do it this way instead of using gethostbyaddr()?

gethostbyaddr() is deprecated in favor of getnameinfo().