【问题标题】:strlen() Refuses to Read String from struct hostent *strlen() 拒绝从 struct hostent 读取字符串 *
【发布时间】:2010-07-28 00:55:44
【问题描述】:

我一直在学习一个关于如何为 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 拒绝 给我任何东西(我知道 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 是怎么回事?

【问题讨论】:

  • 错误可能在调用此函数的代码中,正如乔治的回答所建议的那样。以后发MCVE

标签: c string segmentation-fault strlen


【解决方案1】:

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);

【讨论】:

  • 实际上,事实证明,gethostbyaddr 在这里有问题。不过,感谢您的提示。
  • if (!hostname) 是多余的,如果你已经有 assert(hostname) (或者断言是多余的,无论哪种方式)
【解决方案2】:

哇...永远不要与 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;
}

而且它有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多