I am following the tutorial at this link to create a raw socket packet sniffer:
http://www.security-freak.net/raw-sockets/sniffer_eth_ip.c
The code uses the ntoa() function to get the dot-notation version of the source/destination IP Addresses, but from what I understand that function is deprecated and so these lines are causing problems.
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);
On my system (Ubuntu 11.04) I could only find the inet_ntoa() function in arpa/inet.h but the tutorial doesn't even use that header. When I included arpa/inet.h I get this compilation error:
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’
So I understand I need to use struct in_addr but I'm not familiar with this type '__be32'. Can anyone assist?
EDIT - Actually got this to work doing some fairly complicated casting, but is there a better way?
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));
inet_ntoa
is not officially deprecated, but a bit old style since it uses a static buffer. Normally I recommend using getnameinfo
to convert at binary address to dotted char, but in this case inet_ntop
would work better:
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)));
Note that you should use separate buffers if you need to keep the strings for later.