Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

inet_ntoa gives the same result when called with two different addresses

Tags:

c

printf

//
char ip1[] = "127.0.0.1";
char ip2[] = "211.100.21.179";
printf("ip1: %s\nip2: %s\n", ip1, ip2);

// 
long l1 = inet_addr(ip1);
long l2 = inet_addr(ip2);
printf("ip1: %ld\nip2: %ld\n", l1, l2);

//
struct in_addr addr1, addr2;
memcpy(&addr1, &l1, 4);
memcpy(&addr2, &l2, 4);
printf("%u\n", addr1.s_addr);
printf("%u\n", addr2.s_addr);

//
printf("%s\n", inet_ntoa(addr1));
printf("%s\n", inet_ntoa(addr2));

//
printf("%u,%s\n", addr1.s_addr, inet_ntoa(addr1));
printf("%u,%s\n", addr2.s_addr, inet_ntoa(addr2));
printf("%s <--> %s\n", inet_ntoa(addr1), inet_ntoa(addr2));

The output is:

ip1: 127.0.0.1
ip2: 211.100.21.179
ip1: 16777343
ip2: 3004523731
16777343
3004523731
127.0.0.1
211.100.21.179
16777343,127.0.0.1
3004523731,211.100.21.179
211.100.21.179 <--> 211.100.21.179    // why the same??

I know printf parse arg from right to left or vise versa is platform-dependent, but why the output is the same value, please help to explain.

like image 889
leewi9 Avatar asked Feb 15 '18 03:02

leewi9


2 Answers

From the Linux man pages : https://linux.die.net/man/3/inet_ntoa

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.

It seems the two calls the inet_nota() share a buffer, so calling the function twice overwrites whats in the buffer and replaces it with the next call, thus you get the same output

like image 70
Mitch Avatar answered Sep 29 '22 12:09

Mitch


inet_ntoa() uses an internal buffer to convert an address to a string. Every time you call it it rewrites the same buffer with the new address. So both calls to inet_ntoa() are returning the same pointer, and thus printf() prints the same string twice. inet_ntoa() does this so that you don't have to free() a string every time you call it. If you want your output to look the way you expect you can do this:

 printf("%s <--> ", inet_ntoa(addr1))
 printf("%s\n", inet_ntoa(addr2));

That way printf() will have printed the first address before the second call to inet_ntoa() overwrites it.

like image 32
Whilom Chime Avatar answered Sep 29 '22 13:09

Whilom Chime