In regards to htonl and ntohl. When would either of these two lines of code evaluate to false.
htonl(x) == ntohl(x);
htonl(ntohl(x)) == htonl(htonl(x));
In other words, when are these two operations not equivalent on the same machine? The only scenario I can think of is a machine that does not work on 2's complement for representing integers.
Is the reason largely historical, for coding clarity, or for something else?
Do any modern architectures or environments exists today where these converting to and from network byte order on the same machine is not the same code in either direction?
I wrote a TCP/IP stack for a UNIVAC 1100 series mainframe many years ago. This was a 36 bit, word addressable computer architecture with 1's complement arithmetic.
When this machine did communications I/O, 8 bit bytes arriving from the outside world would get put into the lower 8 bits of each 9 bit quarter-word. So on this system, ntohl() would squeeze 8 bits in each quarter word down into the lower 32 bits of the word (with the top 4 bits zero) so you could do arithmetic on it.
Likewise, htonl() would take the lower 32 bits in a word and undo this operation to put each 8 bit quantity into the lower 8 bits of each 9 bit quarter word.
So to answer the original question, the ntohl() and htonl() operations on this computer architecture were very different from each other.
For example:
COMP* . COMPRESS A WORD
LSSL A0,36 . CLEAR OUT A0
LSSL A1,1 . THROW AWAY TOP BIT
LDSL A0,8 . GET 8 GOOD ONE'S
LSSL A1,1 .
LDSL A0,8 .
LSSL A1,1 .
LDSL A0,8 .
LSSL A1,1 .
LDSL A0,8 .
J 0,X9 .
.
DCOMP* . DECOMPRESS A WORD
LSSL A0,36 . CLEAR A0
LSSL A1,4 . THROW OUT NOISE
LDSL A0,8 . MOVE 8 GOOD BITS
LSSL A0,1 . ADD 1 NOISE BIT
LDSL A0,8 . MOVE 8 GOOD BITS
LSSL A0,1 . ADD 1 NOISE BIT
LDSL A0,8 . MOVE 8 GOOD BITS
LSSL A0,1 . ADD 1 NOISE BIT
LDSL A0,8 . MOVE 8 GOOD BITS
J 0,X9 .
COMP is the equivalent to ntohl() and DCOMP to htonl(). For those not familiar with UNIVAC 1100 assembly code :-) LSSL is "Left Single Shift Logical" a registers by a number of positions. LDSL is "Left Double Shift Logical" a pair of registers by the specified count. So LDSL A0,8 shifts the concatenated A0, A1 registers left 8 bits, shifting the high 8 bits of A1 into the lower 8 bits of A0.
This code was written in 1981 for a UNIVAC 1108. Some years later, when we had an 1100/90 and it grew a C compiler, I started a port of the BSD NET/2 TCP/IP implementation and implemented ntohl() and htonl() in a similar way. Sadly, I never completed that work..
If you wonder why some of the Internet RFCs use the term "octet", its because some computers in the day (like PDP-10s, Univacs, etc.) had "bytes" that were not 8 bits. An "octet" was defined specifically to be an 8 bit byte.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With