strlen()拒绝从struct hostent读取字符串*

时间:2010-07-28 00:55:44

标签: c string segmentation-fault strlen

我一直在编写一个关于如何为Linux构建基本数据包嗅探器的小教程。我把一切都搞定了,现在我想添加IP到主机的映射。

在添加此功能之前,一切正常:

void IPtoHostname(char *ipaddress, char *hostname){
    struct hostent *host;
    in_addr_t ip = inet_addr(ipaddress);
    if (!hostname){
        puts("Can't allocate memory...");
        exit(-1);
    }
    host = gethostbyaddr((char *)&ip, 32, AF_INET);
    hostname = strdup(host->h_name);
}

这基本上需要一个字符串IP地址(“192.168.28.18”) ipaddress ,并将该IP的主机名(“who.cares.com”)填入主机名

strlen REFUSES 给我提供了什么(我知道 strdup 如何工作,我自己测试了这个)段错误。我使用过GDB,字符串以null结尾 字符,它不是NULL。

我还测试了使用静态结构的原始字符串赋值:

void IPtoHostname(char *ipaddress, char *hostname){
    static struct hostent *host;
    in_addr_t ip = inet_addr(ipaddress);
    if (!hostname){
        puts("Can't allocate memory...");
        exit(-1);
    }
    host = gethostbyaddr((char *)&ip, 32, AF_INET);
    hostname = host->h_name;
}

仍然没有骰子。

那么, strlen 是什么?

2 个答案:

答案 0 :(得分:4)

strlen没有任何结果。您需要传入char **主机名,然后将* hostname设置为host-> h_name,假设您在IPToHostName之外执行strlen。您正在设置主机名指针的本地副本。

所以你有这样的事情:

char myip[]  = "123.45.67.89";
char *myhost = NULL;

IPToHostname(myip, myhost); /* this sets its own local copy of myhost, which is on the stack */

/* At this point, myhost is still null!! */

如果你把它改成下面的代码那么它可能会做你想要的。

void IPtoHostname(char *ipaddress, char **hostname)
{
    assert(hostname); /* you'll need to include assert.h for this - it'll abort your program in debug mode if hostname is null */

    struct hostent *host;
    in_addr_t ip = inet_addr(ipaddress);
    if (!hostname)
    {
        puts("Can't allocate memory...");
        exit(-1);
    }
    host = gethostbyaddr((char *)&ip, 32, AF_INET);
    *hostname = strdup(host->h_name);
}

char myip[]  = "123.45.67.89";
char *myhost = NULL;

IPtoHostname(myip, &myhost);

答案 1 :(得分:0)

哇...永远不要打POSIX。我最终写了我的功能:

#define MAXHOST 256

char *IPtoHostname(char *ipaddress){
    struct in_addr iaddr;
    inet_pton(AF_INET, ipaddress, &iaddr);
    struct sockaddr_in saddr;
    saddr.sin_family =  AF_INET;
    saddr.sin_addr = iaddr;

    char *hostname = (char *)malloc(sizeof(char) * MAXHOST);
    if (getnameinfo((struct sockaddr*)&saddr, 32, hostname, MAXHOST, NULL, 0, 0) == -1){
        puts("Cannot reverse engineer IP");
        return;
    }
    return hostname;
}

它有效!