## Tuesday, July 12, 2011

### socket - Network Byte Order

Different CPU architectures have different arrangements for grouping multiple bytes of data together to form integers of 16, 32, or more bits. The two most basic byte orderings are
• big-endian
• little-endian
Other combinations are possible, but they need not be considered here.

The value illustrated in Figure is decimal value 4660, which, in hexadecimal, is the value 0x1234. The value requires that 2 bytes be used to represent it. It can be seen that you can either place the most significant byte first (big-endian) or you can place the least significant byte value first (little-endian.) The choice is rather arbitrary and it boils down to the design of the CPU.

You might already know that the Intel CPU uses the little-endian byte order. Other CPUs like the Motorola 68000 series use the big-endian byte order. The important thing to realize here is that CPUs of both persuasions exist in the world and are connected to a common Internet.
What happens if a Motorola CPU were to write a 16-bit number to the network and is received by an Intel CPU? ''Houston, we have a problem!" The bytes will be interpreted in the reverse order for the Intel CPU, causing it to see the value as 0x3412
in hexadecimal. This is the value 13330 in decimal, instead of 4660!
For agreement to exist over the network, it was decided that big-endian byte order would be the order used on a network. As long as every message communicated over the network obeys this
sequence, all software will be able to communicate in harmony.
This brings you back to AF_INET addresses. The TCP/IP port number (sin_port) and the IP number (sin_addr) must be in network byte order. The BSD socket interface requires that you as the programmer consider this when forming the address.

Performing Endian Conversions:

A few functions have been provided to help simplify this business of endian conversions. There are
two directions of conversion to be considered:
• Host ordering to network ordering
• Network ordering to host ordering
By "host order" what is meant is the byte ordering that your CPU uses. For Intel CPUs, this will mean little-endian byte order. Network order, as you learned earlier, is big-endian byte order. There are also two categories of conversion functions:
• Short (16-bit) integer conversion
• Long (32-bit) integer conversion
The following provides a synopsis of the conversion functions that you have at your

#include <netinet/in.h>

unsigned long htonl(unsigned long hostlong);
unsigned short htons(unsigned short hostshort);
unsigned long ntohl(unsigned long netlong);
unsigned short ntohs(unsigned short netshort);

Sample codes:
TIP
These functions are all described in the byteorder(3) man page.

NOTE
In the context of these conversion functions, "short" refers to a 16-bit value and "long" refers to a 32-bit value. Do not confuse these terms with what might be different sizes of the C data types. For example, a long data type on some CPUs running Linux could conceivably be 64-bits in length.

Example
Use of these functions is quite simple. For example, to convert a short integer to network order, the
following code can be used:

short host_ short = 0x1234;
short netw_short;
netw_short = htons(host_short);

The value netw_short will receive the appropriate value from the conversion to network order. To convert a value from network order back into host order is equally simple:

host_short = ntohs(netw_short);

TIP
The h in the function name refers to "host," whereas n refers to "network." Similarly, s refers to "short" and 1 refers to "long." Using these conventions, it is a simple matter to pick the name of the conversion function you need.

CAUTION
The byteorder(3) functions may be implemented as macros on some systems. Linux systems that run on CPUs using the big-endian byte ordering might provide a simple macro instead, because no conversion of the value is required.

Reference Books: