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)
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)
请注意,如果需要保留字符串以供日后使用,则应使用单独的缓冲区.