Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

printf'ing multiple variables yields different output than printf'ing these variables separately

Considering I have a

struct iphdr *ip_hdr;

and want to print saddr/daddr using printf.

Using two separate printf calls:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    printf("received packet from %s\n",
                    inet_ntoa(*(struct in_addr*)&ip_hdr->saddr));

    printf("received packet to %s\n",
                    inet_ntoa(*(struct in_addr*)&ip_hdr->daddr));

correctly prints the source/destination addr.

Why does

    printf("received packet from %s to %s\n",
                    inet_ntoa(*(struct in_addr*)&ip_hdr->saddr),
                    inet_ntoa(*(struct in_addr*)&ip_hdr->daddr));

print use the source address for both the first and second placeholder (leading to incorrect output), and how can this be fixed?

>Solution :

The inet_ntoa call returns a pointer to a static buffer, so the results of one call overwrite the results of a prior call.

The man page states as much:

The inet_ntoa() function converts the Internet host address in, given
in network byte order, to a string in IPv4 dotted-decimal notation.
The string is returned in a statically allocated buffer, which
subsequent calls will overwrite.

So when you do this:

printf("received packet from %s to %s\n",
                inet_ntoa(*(struct in_addr*)&ip_hdr->saddr),
                inet_ntoa(*(struct in_addr*)&ip_hdr->daddr));

The two calls to inet_ntoa both return the same pointer value, and whichever call happens to be done last (the C standard doesn’t specify the order in which parameters are specified) will be the result printed for both cases.

You can either make two separate printf calls as your first example does to work around this, or you can copy the results to one or more local buffers and print from those buffers.

char srcaddr[16], dstaddr[16];
strcpy(srcaddr, inet_ntoa(*(struct in_addr*)&ip_hdr->saddr));
strcpy(dstaddr, inet_ntoa(*(struct in_addr*)&ip_hdr->daddr));
printf("received packet from %s to %s\n", srcaddr, dstaddr);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading