Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with gethostbyname?

I am using this snippet of code I found in http://www.kutukupret.com/2009/09/28/gethostbyname-vs-getaddrinfo/ to perform dns lookups

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[ ]) {
    struct hostent *h;

    /* error check the command line */
    if(argc != 2) {
        fprintf(stderr, "Usage: %s hostname\n", argv[0]);
        exit(1);
    }

    /* get the host info */
    if((h=gethostbyname(argv[1])) == NULL) {
        herror("gethostbyname(): ");
        exit(1);
    }
    else     
        printf("Hostname: %s\n", h->h_name);

    printf("IP Address: %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));     
    return 0;
}

I am facing a weird fact

./test www.google.com
Hostname: www.l.google.com
IP Address: 209.85.148.103

works fine, but if I try to resolve an incomplete IP address I get this

./test 10.1.1
Hostname: 10.1.1
IP Address: 10.1.0.1

I would expect an error like the following

./test www.google
gethostbyname(): : Unknown host

but the program seems to work.

Any idea why?

like image 688
Ottavio Campana Avatar asked Jul 13 '11 09:07

Ottavio Campana


2 Answers

It is not a bug but rather a feature of inet_aton() function:

DESCRIPTION

The inet_aton() function converts the specified string, in the Internet standard dot notation, to a network address, and stores the address in the structure provided.

Values specified using dot notation take one of the following forms:

a.b.c.d When four parts are specified, each is interpreted as a byte of data and assigned, from left to right, to the four bytes of an internet address.

a.b.c When a three-part address is specified, the last part is interpreted as a 16-bit quantity and placed in the rightmost two bytes of the network address. This makes the three-part address format convenient for specifying Class B network addresses as 128.net.host.

You can read more about this there, for example.

like image 51
Igor Korkhov Avatar answered Sep 19 '22 06:09

Igor Korkhov


POSIX.2004 says :

The name argument of gethostbyname() shall be a node name; the behavior of gethostbyname() when passed a numeric address string is unspecified. For IPv4, a numeric address string shall be in the dotted-decimal notation described in inet_addr().

So, when looking at it from the POSIX point of view, you cannot expect anything when passing it an IP address.

On my system, the man page says this :

If name is an IPv4 or IPv6 address, no lookup is performed and gethostbyname() simply copies name into the h_name field and its struct in_addr equivalent into the h_addr_list[0] field of the returned hostent structure.

It does not say anything about what happens if you pass it an incomplete IP address, so anything could happen, including the behavior you observed.

For more information on how gethostbyname is implemented on your system, you can check the documentation for the function and/or the source code (if available).

like image 36
Sander De Dycker Avatar answered Sep 21 '22 06:09

Sander De Dycker