Different system architectures use different byte ordering, either little endian (least significant bit first) or big endian (most significant byte first). IA-32 is an example of an architecture that implements little endian byte ordering. PowerPC and most Network Protocols (including TCP and IP) use big endian.

When transferring data between systems of different endianness, the programmer must take care to reverse the byte ordering before they interpret the data.

Noncompliant Code Example

In this noncompliant code example, the programmer tries to read an integer off a previously connected network socket.

/* sock is a connected TCP socket */

int num;

if (recv(sock, (void *)&num, sizeof(int), 0) < 0) {
  /* Handle error */
}

printf("We received %d from the network!\n", num);

This program prints out the number received off the socket using an incorrect byte ordering. For example, if the value 4 is sent from a 32 bit little endian system, the value 536,870,912 is read. This problem can be corrected by reversing the byte ordering.

Compliant Code Example

In this compliant code example, the programmer uses the ntohl() function to convert the integer from network byte order to host byte ordering.

/* sock is a connected TCP socket */

int num;

if (recv(sock, (void *)&num, sizeof(int), 0) < 0) {
  /*handle error*/
}

num = ntohl(num);
printf("We recieved %d from the network!\n", num);

The ntohl() function (network to host long) translates a long type (which is the same size as an int), into the host byte ordering from the network byte ordering. This function is always appropriate to use because its implementation depends upon the specific systems byte ordering. Consequently, on a big endian architecture, ntohl() does nothing.

The reciprocal function htonl() (host to network long) should be used before sending any data to another system over network protocols.

Notes:

Risk Assessment

If the programmer is careless then this bug is likely. However it will immediately break the program by printing the incorrect result and therefore should be caught by the programmer during the early stages of debugging and testing. Recognizing a value as in reversed byte ordering, however, can be difficult depending on the type and magnitude of the data.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

POS39-C

medium

high

low

P3

L3

References

POSIX ntohl man page
FIO09-C. Be careful with binary data when transferring data across systems