2011-09-12 18 views
1

我下面这个链接教程创建原始套接字数据包嗅探器ntoa():使用的NTOP(),而不是在一个较旧的原始套接字教程

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

在我的系统(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’ 

所以我知道我需要使用结构组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)); 
+0

'__be32'是Big Endian,32位。如果你看看'struct in_addr'的声明,你会发现它基本上是一样的。 – asveikau

回答

7

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

注意,如果你需要保持字符串后,你应该使用单独的缓冲区。

0

应该在大多数Linux发行版(包括x86和x64版本),这些工作包括:如果

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

不知道100%所有的人都是强制性的,但。