kadina
kadina

Reputation: 5372

gethostbyname_r is giving ip address in little endian format

I am trying to get my machine IP address using gethostbyname_r(). It should give the ip address in network byte order which is big endian. But I think I am getting the address in little endian format.

For example, if my machine IP address is 10.80.0.200, Big endian integer should be 173015240 ((10 * 256 * 256 * 256) + (80 * 256 * 256) + 0 + 200) and Little endian integer should be 3355463690 ((200 * 256 * 256 * 256) + 0 + (80 * 256) + 10) and I am always getting the value as 3355463690 (Little endian)

Below is my C++ program

   rc = gethostbyname_r(hostname_.c_str(),
                        &h, buf, sizeof(buf),
                        &result, &local_errno);

   if (rc) {
      std::cout << "Failed to get the ip" << std::endl;
      ipaddr_ = 0;
   }

   ipaddr_ = *reinterpret_cast<uint32_t *>(h.h_addr_list[0]);

Can some one please let me know why gethostbyname_r() is giving the IP address in little endian format where it is supposed to be big endian. Or doing reinterpret_cast is changing the endianness. But as per my knowledge reinterpret_cast won't change the endianness.

Note: My machine format is little endian.

import sys
sys.byteorder // 'little'

Upvotes: -2

Views: 78

Answers (2)

n. m. could be an AI
n. m. could be an AI

Reputation: 120059

The IP address 10.80.0.200 corresponds to the integer

10×2563 + 80×2562 + 0×2561 + 200×2560

Note this is not a "big endian integer" nor a "little endian integer". There are no such things. It's just an integer. It equals 173015240 on a big endian machine, on a little endian machine, or on a 127 qubit quantum computer.

"Big endian" and "little endian" are integer storage formats. The little endian storage format means that the least significant byte is stored first (lowest address), and the most significant byte is stored last (highest address). The big endian storage format means just the opposite.

The integer 173015240, stored in the big-endian format, will have its most significant byte (which equals 10) stored first, and its least significant byte (which equals 200) stored last. On your little-endian machine, however, the first byte is the least significant one, so these four bytes, when interpreted as an integer, look like 3355463690.

Upvotes: 2

nneonneo
nneonneo

Reputation: 179677

All of the networking APIs produce and consume addresses in big-endian order, which means that they are stored in memory with the most-significant bytes at the lowest addresses.

You’re taking the address and attempting to interpret it as a uint32_t, which on your platform is little endian.

The bytes of your address are (in decimal, from lowest to highest memory address):

10 80 0 200

Interpreted as a little-endian number, this will be 200*256^3 + 80*256 + 10 = 3355463690.

If you want a string representation of the address, use inet_ntoa - it will save you from having to interpret the bytes yourself.

Upvotes: 2

Related Questions