Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Different system architectures use different byte ordering, either little endian (least significant bit byte first) or big endian (most significant byte first).   IA_-32 is an example of an architecture that implements little endian byte ordering. In contrast, 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 before interpreting the data. 

The functions htonl(), htons(), ntohl(), and ntohs() can be used to transfer between network byte ordering (big endian) and the host's byte ordering. On big endian systems, these functions do nothing. They may also be implemented as macros rather than functions.

Noncompliant Code Example

In this non-compliant noncompliant code example, the programmer tries to read an unsigned 32-bit integer off a previously connected network socket: (assume 32 bit little endian system) .

It is important to know the sizes of your data types lest they be different on architectures that are accessible over the network. Hence, we transfer a uint32_t rather than an int. For more information, see FIO09-C. Be careful with binary data when transferring data across systems.

Code Block
bgColor#FFcccc
langc

/* sock is a connected TCP socket */

intuint32_t num;

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

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

This program will print prints out the number received off from the socket in the using an incorrect byte ordering, therefore (assuming an x86 system). For example, if the number value 4 was sentis sent from a big endian machine, and the receiving system is little endian, the number value 536,870,912 will be read. To remediate this, the programmer must reverse the byte ordering:

...

is read. This problem can be corrected by sending and receiving using network byte ordering.

Compliant Solution

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

Code Block
bgColor#ccccff
langc

/* sock is a connected TCP socket */

intuint32_t num;

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

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

The ntohl() function (network to host long) translates a long type (which is the same size as an int), uint32_t value into the host byte ordering from the network byte ordering. This function is always appropiate appropriate to use since it is implementation defined on systems per that systems because its implementation depends on the specific system's byte ordering. Thus Consequently, on a PowerPC systembig endian architecture, ntohl() does nothing.

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

Portability Details

  • ntohs(), ntohl(), htons(), and htonl() are not part of the C Standard and are consequently not guaranteed to be portable to non-POSIX systems.
  • The POSIX implementations of ntohs(), ntohl(), htons(), and htonl() take arguments of types uint16_t and uint32_t and can be found in the header file <arpa/inet.h>.
  • The Windows implementations use unsigned short and unsigned long and can be found in the header file <winsock2.h>.
  • Other variants of ntoht() and htont(), such as ntohi()/htoni() or ntohll()/htonll(), may exist on some systems.

Risk Assessment

If the programmer is careless then , this bug is very 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

Detectable

Remediation Cost

Repairable

Priority

Level

POS39-C

Medium

Likely

Yes

No

P12

L1

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V

taint_sink

Soundly supported
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-POS39
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF4906, DF4907, DF4908
Klocwork
Include Page
Klocwork_V
Klocwork_V
BYTEORDER.NTOH.RECV
BYTEORDER.NTOH.READ
BYTEORDER.HTON.SEND
BYTEORDER.HTON.WRITE

Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_C

high

unlikely

low

P3

L3

References

-POS39-a

Use the correct byte ordering when transferring data between systems

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule POS39-CChecks for missing byte reordering when transferring data (rule fully covered)

Bibliography


...

Image Added Image Added Image AddedPOSIX ntohl man page