Sockets – Using ntop() instead of ntoa() on an older raw socket tutorial

cpacket-sniffersraw-socketssockets

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

Best Answer

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.

Related Topic