Search code examples
c++network-programmingtcpinet

inet_ntoa() returns IP in the wrong order


I'm trying to solve a bug in which I try to print the IP adress of my machine. The machine is using a RedHat OS. The goal is to obtain the host id using gethostid(), and then use the function inet_ntoa to convert its value to a string.

The problem is that the result is showing the address in a wrong order. The IP address has the following order a.b.c.d, but the result of inet_ntoa shows it like this b.a.d.c. I'm aware of the endianess issue when using these functions, but I thought that by not respecting the endianess the result was a reversed IP address

I think that the issue could be in the value returned by the gethostid(). But if this is the case then I'm not sure why it's giving me a wrong id.

My ip adress is 172.30.223.27

gethostid() returns 514595807 which in hexadecimal is 1EAC1BDF, and then converted to bytes 30.172.27.223

#include <arpa/inet.h>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h> 

int main() {
  long hostId = gethostid();
  std::cout << "Host ID: " << hostId << std::endl;

  struct in_addr addr = inet_makeaddr(hostId,0 );

  ::std::string ipv4_addr_str = inet_ntoa(addr);

  std::cout << "IP using inet_ntoa: " << ipv4_addr_str << std::endl;

  char ipString[INET_ADDRSTRLEN];
  inet_ntop(AF_INET, &addr, ipString, INET_ADDRSTRLEN);

  std::cout << "IP using using inet_ntop: " << ipString << std::endl;

  return 0;
}

And the output is:

Host ID: 514595807
IP using inet_ntoa: 30.172.27.223
IP using using inet_ntop: 30.172.27.223

I tried using inet_ntoa and inet_ntop to see if the issue is at the moment of printing the IP, but it seems that the problem is located in the value obtained by gethostid()

Why does this occur?


Solution

  • Don't try to use gethostid as an IP address; that's simply not what it is.

    Check the man page:

    This normally resembles the Internet address for the local
    machine, as returned by gethostbyname(3), and thus usually never
    needs to be set.
    
    ...
    
    In the glibc implementation, the hostid is stored in the file
    /etc/hostid.  (Before glibc 2.2, the file /var/adm/hostid was
    used.)
    
    In the glibc implementation, if gethostid() cannot open the file
    containing the host ID, then it obtains the hostname using
    gethostname(2), passes that hostname to gethostbyname_r(3) in
    order to obtain the host's IPv4 address, and returns a value
    obtained by bit-twiddling the IPv4 address.  (This value may not
    be unique.)
    

    Note the "normally" in the first paragraph (indicating that it can be something entirely unrelated), the fact that it can be set, and the "bit-twiddling" in the last paragraph.

    If you want an IP address of the machine (there may be more than one), use something else.