Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Same output for htonl() and ntohl() on an integer

Tags:

c

endianness

I ran the following program on little-endian [LE] machine [Linux, Intel processor]. I am unable to explain the 3 outputs in below code snippet. Since machine is LE, the value of a is stored as 0x78563412. When printing, it is displaying its actual value. Since its an LE machine, I expect ntohl() to be a no-op and display 0x78563412, which it is doing. However, I expect 0x12345678 for 2nd print statement containing htonl(). Can someone please help me understand why they are same?

int main() 
{
    int a = 0x12345678; 

    printf("Original - 0x%x\n", (a)); 
    printf("Network - 0x%x\n", htonl(a)); 
    printf("Host - 0x%x\n", ntohl(a)); 

    return 0;
}

Output:

Original - 0x12345678
Network - 0x78563412
Host - 0x78563412
like image 442
Bhaskar Avatar asked Jul 10 '12 23:07

Bhaskar


People also ask

Are Htonl and Ntohl the same?

The function htons converts an integer short number from the byte order accepted on the computer into the network byte order. The function ntohl converts an integer number from the network byte order into the byte order accepted on the computer.

What are the purposes of the Ntohs () Htons () Nothl () and Htonl () functions in a socket program?

The htonl() and htons() functions shall return the argument value converted from host to network byte order. The ntohl() and ntohs() functions shall return the argument value converted from network to host byte order.

What does Ntohl return?

Returned value ntohl() returns the translated long integer.

What is Ntohl in C?

The ntohl function returns the value supplied in the netlong parameter with the byte order reversed. If netlong is already in host byte order, then this function will reverse it. It is up to the application to determine if the byte order must be reversed.


1 Answers

Since its an LE machine, I expect ntohl() to be a no-op

That's the mistake. Network byte order is big-endian, host byte order is little-endian. Therefore, both ntohl and htonl return a byte-swapped version of their input.

Remember, the point of htonl is that you can take an integer on the host, then write:

int i = htonl(a);

and the result is that the memory of i, when interpreted using network byte order, has the same value that a does. Hence, if you write the object representation of i to a socket and the reader at the other end expects a 4-byte integer in network byte order, it will read the value of a.

and display 0x78563412

Is this what you intended to write? If ntohl were a no-op (or rather, an identity function), then your third line necessarily would print the same thing as your first line, because you would have ntohl(a) == a. This is what happens on big-endian implementations, where your program prints:

Original - 0x12345678
Network - 0x12345678
Host - 0x12345678
like image 108
Steve Jessop Avatar answered Sep 22 '22 11:09

Steve Jessop