0

I'm trying to get hostname of a remote system and the gethostbyaddr fails with error number 22 which according to errno.h is EINVAL .I'm trying to get the hostname of an windows system and its failing and the same is for linux system.But the same function works well on windows.I had gone through the thread as per them a reverse dns record must be present for the function to work .Is there any other alternative function to get the remote system name ? I have posted the code below ,please let me know the method to get the same.

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



int main(void)
{

    struct hostent *hp;
    in_addr_t ipaddr;
    char Ipaddr[20];

    printf("\n Enter the ip address : ");
    scanf("%s",Ipaddr);

    ipaddr=inet_addr(Ipaddr);

    printf("Converted ip address : %zu",ipaddr);

    printf("\n Hostname is : %s",hname);   
    hp=gethostbyaddr((void *)&ipaddr,4,AF_INET);
    if(hp==NULL)
    {
        printf("\n The hostname could not be found ");
        perror("gethostbyaddr"); // error printed as "gethostbyaddr: Success"
        printf("Error Number : %d",errno); //error number is : 22 which is EINVAL as per the header file

        return 0;
    }
    printf("\n The hostname by gethostbyaddr : %s",hp->h_name);

}

EDIT

#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    int dwRetval;

    struct sockaddr_in saGNI;
    char hostname[NI_MAXHOST];
    char servInfo[NI_MAXSERV];
    u_short port = 27015;

    char Ip_Address[18];

    // Validate the parameters

    printf("enter the ip address : ");
    scanf("%s",Ip_Address);


    //-----------------------------------------
    // Set up sockaddr_in structure which is passed
    // to the getnameinfo function
    saGNI.sin_family = AF_INET;
    saGNI.sin_addr.s_addr = inet_addr(Ip_Address);
    saGNI.sin_port = htons(port);

    //-----------------------------------------
    // Call getnameinfo
    dwRetval = getnameinfo((struct sockaddr *) &saGNI,
                           sizeof (struct sockaddr),
                           hostname,
                           NI_MAXHOST, servInfo, NI_MAXSERV,NI_NOFQDN);

    if (dwRetval != 0) {
        perror("getnameinfo");
        printf("getnameinfo returned herror = %d\n", errno);

        return 1;
    } else {
        printf("getnameinfo returned hostname = %s\n", hostname);
        return 0;
    }
}
Community
  • 1
  • 1
blitz
  • 84
  • 9

1 Answers1

1

The resolving code seems to be OK, but the error reporting part is wrong. At least on Unix, gethostbyaddr() does not set errno. In the case of an error, h_errno is set, and herror() can be used to print a text error message:

if (hp == NULL) {
    herror("Could not resolve address");
    printf("Error Number : %d", h_errno);

    return 0;
}

Remark: The more modern interface to convert an IP address to a host name is getnameinfo(). It works with IPv4 and IPv6, and should work identically on Unix and Windows.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Hi i'm getting the hostname as ip-address of the machine . – blitz Oct 12 '13 at 08:26
  • @blitz: I am confused now. Your question seems to imply that `hp == NULL`, therefore I focused on that part. Is `gethostbyaddr()` successful or not? – Martin R Oct 12 '13 at 08:29
  • I wrote the code with getnameinfo with flags as NI_NOFQDN and NI_NUMERICSERV but still the same , its returning the ip address – blitz Oct 12 '13 at 08:31
  • @blitz: Perhaps I misunderstood your question. You said that the (original) code *fails* on Linux and the `if(hp==NULL) ...` part is executed. Now you say that the function succeeds, but returns the hostname as numeric IP address. – Martin R Oct 12 '13 at 08:35
  • as per your suggestion i tried to use getnameinfo , the function is returning an ipaddress but not the hostname .Sorry for the bad english . – blitz Oct 12 '13 at 08:38
  • @blitz: It seems that I misunderstood your main problem. My answer was how to use gethostbyaddr correctly. But both gethostbyaddr and getnameinfo can only work if the host has a reverse DNS entry. I don't know alternative methods. If that is your main problem, you may have to wait for more answers ... – Martin R Oct 12 '13 at 08:43
  • i tried getnameinfo using windows sockets , it is able to get the hostname of the remote system correctly . – blitz Oct 12 '13 at 10:28
  • @blitz: See http://support.microsoft.com/kb/172218/en-us: It seems that Windows uses NetBIOS (the Windows name resolution protocol) if the DNS lookup fails. I don't think there is an easy way to implement that in Linux, but Samba does it (the nmbd daemon). – Martin R Oct 12 '13 at 11:19