Categories
WAND

Printing IP addresses in C

Printing out IP addresses in C isn’t too hard- you can use inet_ntoa for easy results. inet_ntoa uses a static buffer however, so trying to use it more than once in the same printf statement causes problems. You can split each inet_ntoa call into a new printf, or you can write some macros to do the job

[code lang=”cpp”]

#define IPFMT “%i.%i.%i.%i”
#define IP(a) ((ntohl(a.s_addr) >> 24) & 0xff),\
((ntohl(a.s_addr) >> 16) & 0xff),\
((ntohl(a.s_addr) >> 8) & 0xff),\
(ntohl(a.s_addr) & 0xff) [/code]

You might use this like:
[code lang=”cpp”]
printf(IPFMT ” -> ” IPFMT “\n”, IP(ipptr->ip_src), IP(ipptr->ip_dst));
[/code]

The preprocessor turns this into something like the following:

[code lang=”cpp”]

printf(“%i.%i.%i.%i” ” -> ” “%i.%i.%i.%i” “\n”,
((ntohl(ipptr->ip_src.s_addr) >> 24) & 0xff),
((ntohl(ipptr->ip_src.s_addr) >> 16) & 0xff),
((ntohl(ipptr->ip_src.s_addr) >> 8) & 0xff),
(ntohl(ipptr->ip_src.s_addr) & 0xff),
((ntohl(ipptr->ip_dst.s_addr) >> 24) & 0xff),
((ntohl(ipptr->ip_dst.s_addr) >> 16) & 0xff),
((ntohl(ipptr->ip_dst.s_addr) >> 8) & 0xff),
(ntohl(ipptr->ip_dst.s_addr) & 0xff));
[/code]

Looks a bit messy, and the IPFMT macro might throw a few people off at first, but anyone familiar with PRIu64 and the like should manage it ok. I’ll probably through this into libtrace at some point, as a helper function.