Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use getnameinfo instead of gethostbyname?

in code :

if ((host = (struct hostent*) gethostbyname(address) ) == 0) // address is a string

I've got warning when cross compiling (generic arm architecture) on 4.5.x gcc :

(.text+0x1558): warning: gethostbyname is obsolescent, use getnameinfo() instead.

getnameinfo is:

int WSAAPI getnameinfo(
  __in   const struct sockaddr FAR *sa,
  __in   socklen_t salen,
  __out  char FAR *host,
  __in   DWORD hostlen,
  __out  char FAR *serv,
  __in   DWORD servlen,
  __in   int flags
);

And it got more parameters... And I'm confused with it, I just need it work as gethostbyname were working. What parameter to pass to keep it simple stupid as it was with gethostbyname?

Finally here is my try:

struct sockaddr_in servAddr;
struct hostent *host;        /* Structure containing host information */

/* open socket */
if ((handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    return LILI_ERROR;

memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family      = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(address.ptr());
servAddr.sin_port        = htons(port);

char servInfo[NI_MAXSERV];
if ( ( host = (hostent*) getnameinfo(
                 (struct sockaddr *) &servAddr
                 ,sizeof (struct sockaddr)
                 ,address.ptr(), address.size()
                 ,servInfo, NI_MAXSERV
                 ,NI_NUMERICHOST | NI_NUMERICSERV )  ) == 0)
    return LILI_ERROR;

if (::connect(handle, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
    return LILI_ERROR;

It compiles well and no segmentation fault on start up but I can't connect my server with it :(

like image 454
cnd Avatar asked Apr 27 '12 07:04

cnd


People also ask

What does gethostbyname do?

The gethostbyname function returns a pointer to a hostent structure—a structure allocated by Windows Sockets. The hostent structure contains the results of a successful search for the host specified in the name parameter.

Should I use Getaddrinfo?

The getaddrinfo function and associated addrinfo structure should be used if IPv6 addresses for the host are required or if both IPv4 and IPv6 addresses for the host are required.


2 Answers

gethostbyname() does a name→IP lookup. It should be replaced with getaddrinfo(), which can do the same.

This means the warning is completely wrong. getnameinfo() is the replacement of gethostbyaddr(), both for IP→name lookups. The reverse.

name→IP: gethostbyname(), getaddrinfo()
IP→name: gethostbyaddr(), getnameinfo()

The newer functions can do more: they handle IPv6 and can translate strings like 'http' to 80 (port). In the future they can also determine if e.g. TCP should be used for the service in question or SCTP. The interface is ready.

like image 171
Robert Siemer Avatar answered Oct 19 '22 14:10

Robert Siemer


Beej's explains it pretty good. gethostbyname() does not works well with IPV6 and thus you should use getnameinfo() instead. All you have to do is to fill in the required informations, i.e.

getnameinfo(
    &sa,             // Pointer to your struct sockaddr
    sizeof sa,       // Size of this struct
    host,            // Pointer to hostname string
    sizeof host,     // Hostname string buffer length
    service,         // Pointer to service name string
    sizeof service,  // Service name string buffer length
    0                // No flags given
);

Edit: After some research, I've found that

getnameinfo(&sa, sizeof(sa), hostname, size_hostname, NULL, 0, 0);

should be sufficient.

Edit #2 I've noticed you are trying to use the return value of getnameinfo as hostname. But that is not correct, the hostname is saved within the provided host pointer. The return value indicates whether the operation was sufficient. Also have a look at the man page.

like image 43
Sebastian Dressler Avatar answered Oct 19 '22 13:10

Sebastian Dressler