1

我一直在学习一个关于如何为 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") 填充到hostname中。

发生的事情是strlen 拒绝给我任何东西(我知道strdup是如何工作的,我自己已经测试过了)和段错误。我使用过 GDB,字符串以空字符结尾,并且不是 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怎么了?

4

2 回答 2

4

strlen 没有任何问题。您需要传入 char **hostname,然后设置 *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);
于 2010-07-28T01:00:47.070 回答
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;
}

它有效!

于 2010-07-28T13:05:18.983 回答