gethostbyname出了什么问题?

时间:2011-07-13 09:53:04

标签: c linux gethostbyname

我正在使用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 个答案:

答案 0 :(得分:18)

这不是bug,而是inet_aton()函数的一个特性:

  

说明

     

inet_aton()函数转换指定的字符串   Internet标准点表示法,到网络地址,并存储   提供的结构中的地址。

     

使用点表示法指定的值采用以下形式之一:

     

a.b.c.d 当指定了四个部分时,每个部分都被解释为一个数据字节,并从左到右分配到一个互联网地址的四个字节。

     

<强> A.B.C       当指定三部分地址时,最后一部分被解释为16位数量并放在网络地址的最右边两个字节中。这使得三部分地址格式便于将B类网络地址指定为128.net.host。

例如,您可以阅读有关此there的更多信息。

答案 1 :(得分:7)

POSIX.2004说:

  
    

gethostbyname()的name参数应为节点名称;传递数字地址字符串时gethostbyname()的行为未指定。对于IPv4,数字地址字符串应采用inet_addr()中描述的点分十进制表示法。

  

因此,从POSIX的角度来看,在传递IP地址时你不能指望任何事情。

在我的系统上,man page说明了这一点:

  
    

如果name是IPv4或IPv6地址,则不执行查找,gethostbyname()只是将name复制到h_name字段,并将其结构in_addr等效到返回的hostent结构的h_addr_list [0]字段中。

  

如果你传递一个不完整的IP地址,它没有说明会发生什么,所以任何事情都可能发生,包括你观察到的行为。

有关如何在系统上实施gethostbyname的更多信息,您可以查看文档中的功能和/或源代码(如果有)。