Что не так с gethostbyname? - PullRequest
7 голосов
/ 13 июля 2011

Я использую этот фрагмент кода, который я нашел в http://www.kutukupret.com/2009/09/28/gethostbyname-vs-getaddrinfo/ для выполнения поиска DNS

#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;
}

Я сталкиваюсь со странным фактом

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

работает нормально,но если я попытаюсь разрешить неполный IP-адрес, я получу

./test 10.1.1
Hostname: 10.1.1
IP Address: 10.1.0.1

. Я ожидаю ошибку, подобную следующей

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

, но программа, похоже, работает.

Есть идеи, почему?

Ответы [ 2 ]

18 голосов
/ 13 июля 2011

Это не ошибка, а скорее функция inet_aton ():

ОПИСАНИЕ

Функция inet_aton () преобразует указанную строку в стандартную нотацию Интернета., к сетевому адресу и сохраняет адрес в предоставленной структуре.

Значения, указанные с помощью точечной нотации, принимают одну из следующих форм:

abcd Когда четыре частиуказано, что каждый интерпретируется как байт данных и присваивается слева направо четырем байтам интернет-адреса.

abc Когда указан адрес из трех частей,последняя часть интерпретируется как 16-битная величина и помещается в крайние правые два байта сетевого адреса.Это делает формат адреса из трех частей удобным для указания сетевых адресов класса B как 128.net.host.

Вы можете узнать больше об этом там , например.

7 голосов
/ 13 июля 2011

POSIX.2004 говорит:

Аргумент имени gethostbyname () должен быть именем узла;поведение gethostbyname () при передаче числовой адресной строки не определено.Для IPv4 строка числового адреса должна быть в точечно-десятичной записи, описанной в inet_addr ().

Так что, глядя на нее с точки зрения POSIX, вы не можете ожидать ничегопри передаче ему IP-адреса.

В моей системе справочная страница сообщает:

Если имя является адресом IPv4 или IPv6,поиск не выполняется, и gethostbyname () просто копирует имя в поле h_name и его эквивалент struct in_addr в поле h_addr_list [0] возвращенной структуры hostent.

Он ничего не говорито том, что произойдет, если вы передадите ему неполный IP-адрес, чтобы могло произойти что угодно, включая поведение, которое вы наблюдали.

Для получения дополнительной информации о том, как gethostbyname реализован в вашей системе, вы можете проверить документацию дляфункция и / или исходный код (если имеется).

...