When using value-result arguments for the length of socket address structures, if the socket address structure is fixed-length, the value returned by the kernel will always be that fixed size: 16 for an IPv4 sockaddr_in and 28 for an IPv6 sockaddr_in6, for example. But with a variable-length socket address structure (e.g., a Unix domain sockaddr_un), the value returned can be less than the maximum size of the structure.
With network programming, the most common example of a value-result argument is the length of a returned socket address structure. But, we will encounter other value-result arguments in this text:
- The middle three arguments for the select function
- The length argument for the getsockopt function
- The msg_namelen and msg_controllen members of the msghdr structure, when used with recvmsg
- The ifc_len member of the ifconf structure
- The first of the two length arguments for the sysctl function
Byte Ordering Functions
Consider a 16-bit integer that is made up of 2 bytes. There are two ways to store the two bytes in memory: with the low-order byte at the starting address, known as little-endian byte order, or with the high-order byte at the starting address, known as big-endian byte order.
The terms “little-endian” and “big-endian” indicate which end of the multibyte value, the little end or the big end, is stored at the starting address of the value.
Unfortunately, there is no standard between these two byte orderings and we encounter systems that use both formats. We refer to the byte ordering used by a given system as the host byte order.
#include "unp.h"
int main(int argc, char **argv)
{
union
{
short s;
char c[sizeof(short)];
}un;
un.s=0x0102;
printf("%s: ", CPU_VENDOR_OS);
if(sizeof(short)==2)
{
if(un.c[0]==1&&un.c[1]==2)
printf("big-endian\n");
else if(un.c[0]==2&&un.c[1]==1)
printf("little-endian\n");
else
printf("unknown\n");
}
else
printf("sizeof(short)=%d\n",sizeof(short));
return 0;
}
We store the two-byte value 0x0102 in the short integer and then look at the two consecutive bytes, c[0] and c[1], to determine the byte order.
The string CPU_VENDOR_OS is determined by the GNU autoconf program when the software in this book is configured, and it identifies the CPU type, vendor, and OS release.
We have talked about the byte ordering of a 16-bit integer; obviously, the same discussion applies to a 32-bit integer.
There are currently a variety of systems that can change between little-endian and big-endian byte ordering, sometimes at system reset, sometimes at run-time.