我一直在编写一个关于如何为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 是什么?
答案 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)
#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;
}
它有效!