The addr and addrlen arguments to bind() require some further explanation. Looking at Table 56-1, we see that each socket domain uses a different address format. For example, UNIX domain sockets use pathnames, while Internet domain sockets use the combination of an IP address plus a port number. For each socket domain, a different structure type is defined to store a socket address. However, because system calls such as bind() are generic to all socket domains, they must be able to accept address structures of any type. In order to permit this, the sockets API defines a generic address structure, struct sockaddr. The only purpose for this type is to cast the various domain-specific address structures to a single type for use as arguments in the socket system calls. The sockaddr structure is typically defined as follows:
struct sockaddr { sa_family_t sa_family; /* Address family (AF_* constant) */ char sa_data[14]; /* Socket address (size varies according to socket domain) */ };
This structure serves as a template for all of the domain-specific address structures. Each of these address structures begins with a family field corresponding to the sa_family field of the sockaddr structure. (The sa_family_t data type is an integer type specified in SUSv3.) The value in the family field is sufficient to determine the size and format of the address stored in the remainder of the structure.