在较旧的原始套接字教程上使用ntop()而不是ntoa()

Sea*_*man 2 c sockets raw-sockets packet-sniffers

我按照此链接的教程创建一个原始套接字数据包嗅探器:

http://www.security-freak.net/raw-sockets/sniffer_eth_ip.c

代码使用ntoa()函数来获取源/目标IP地址的点符号版本,但据我所知,该函数已被弃用,因此这些行导致了问题.

ip_header = (struct iphdr*)(packet + sizeof(struct ethhdr));

/* print the Source and Destination IP address */

printf("Dest IP address: %d\n", inet_ntoa(ip_header->daddr));
printf("Source IP address: %d\n", inet_ntoa(ip_header->saddr));
printf("TTL = %d\n", ip_header->ttl);   
Run Code Online (Sandbox Code Playgroud)

在我的系统(Ubuntu 11.04)上,我只能在arpa/inet.h中找到inet_ntoa()函数,但教程甚至没有使用该头文件.当我包含arpa/inet.h时,我得到了这个编译错误:

sniffer.c:154:4: error: incompatible type for argument 1 of ‘inet_ntoa’
/usr/include/arpa/inet.h:54:14: note: expected ‘struct in_addr’ but argument is of type     ‘__be32’
Run Code Online (Sandbox Code Playgroud)

所以我理解我需要使用struct in_addr,但我不熟悉这种类型'__be32'.有人可以帮忙吗?

编辑 - 实际上让这个工作做一些相当复杂的铸造,但有更好的方法吗?

printf("Dest IP address: %s\n", inet_ntoa(*(struct in_addr*)&ip_header->daddr));
printf("Source IP address: %s\n", inet_ntoa(*(struct in_addr*)&ip_header->saddr));
Run Code Online (Sandbox Code Playgroud)

Per*_*son 9

inet_ntoa由于它使用静态缓冲区,因此没有正式弃用,但有点旧样式.通常我建议使用getnameinfo二进制地址转换为点状字符,但在这种情况下inet_ntop会更好用:

char ipbuf[INET_ADDRSTRLEN];
printf("Dest IP address: %s\n", inet_ntop(AF_INET, &ip_header->daddr, ipbuf, sizeof(ipbuf)));
printf("Source IP address: %s\n", inet_ntop(AF_INET, &ip_header->saddr, ipbuf, sizeof(ipbuf)));
Run Code Online (Sandbox Code Playgroud)

请注意,如果需要保留字符串以供日后使用,则应使用单独的缓冲区.