This SAS is between application and kernal. An address conversion function translates between text representation of an address and binary value that makes up SAS. IPv4 uses inet_addr and inet_ntoa.
Socket Address Structure SAS:
This SAS is between application and kernal. An address conversion function translates between text representation of an address and binary value that makes up SAS. IPv4 uses inet_addr and inet_ntoa. But inet_pton and inet_ntop handle IPv4 and IPv6. Above functiuons are protocol dependent. However the functions starting with sock are protocol independent. Most socket functions require a pointer to a socket address structure as an argument.
IPv4 Socket AS: It is defined as follows:
# include <netinet / in.h>
sin_len, added in 4.3 BSD, is not normally supported by many vendors. It facilitates handling of variable length socket address structures.
Various data types that are commonly used are listed below:
Length field is never used and set. It is used within the kernal before routines that deal with socket address structures from various protocol families.
Four socket functions � bind(), connect(), sendto(), sendmsg() -pass socket address structures from application to kernal. All invoke sockargs() in Berkley derived implementation. This function copies socket address structures and explicitly set the sin_len member to the size of the structure that was passed. The other socket functions that pass socket address to the application from kernal accept(), recvfrom(), recvmsg(), getpeername() and getsockname() all set the sin_lenmember before returning to the process.
sin_port, sin_family and sin_addr are the only required for Posix.1g. sin_zero is implemented to keep the structure length to 16 byte.
Generic Socket Address Structure.
Socket address structures are always passed by reference when passed as an arguments to any of the socket functions.
int bind (int sockfd, struct sockaddr *, socklen_t);
But the socket function that accept these address structures as pointers must deal with any of these supported protocols. This calls for the any functions must cast the pointer to the protocol specific socket address structure to be a pointer to a generic socket address structure. For example
struct sockaddr_in serv;
bind (sockfd, (struct sockaddr *) &serv, sizeof(serv));
If we omit the cast, the C compiler generates a warning of the form incompatible pointer type.
Different socket address structures are :
IPv4 (24 bytes), IPv6 (24 bytes), Unix variable length and Data link variable length.
IPv6 SAS:
Defined by # include<netinet/in.h> header. The structure is shown below:
Important points to note are:
� The SIN_LEN constant must be defined if the system supports the length members for socket address structures.
The IPv6 family is AF_INET6
The members in this structure are ordered so that if the sockaddr_in6 structure is 64 bit aligned, so is the 128 bit sin6_addr member.
� The sin6_flowinfo member is divided into three fields o The low order 24 bits are the flow label
o The next 4 bits are the priority o The next 4 bits are reserved.
Comparison of socket address structure:
Following figure shows the comparison of the four socket address structures that are encountered.
Value Result Arguments: The socket address structure is passed to any of the socket function byreference. The length of the structure is also passed as argument to the function. But the way the length is passed depends on which direction it is being passed. From the process to the kernal or kernal to the process.
1. The three functions bind(), connect() and sendto() pass a socket address structure from the process to the kernal. One argument to these three function is the pointer to the socket address structure and another argument is the integer size of the structure.
struct sockaddr_in serv;
connect (sockfd, (SA *) & serv, sizeof(serv));
Since the kernal is passed both pointer and the size of what the pointer points to, it knows exactly how much data to copy from the process into the kernal. Following figures shows this scenario:
The four functions accept(), recvmsg(), getsockname() and getpeername() pass a socket address structure from kernal to the process, the reverse direction form the precious scenario. In this case the length is passed as pointer to an integer containing the size of structure as in
struct sockaddr_un cli; // Unix domain// socklen_t len;
len = sizeof (cli);
getpeername (unixfd, (SA *) &cli, & len );
The reason that the size changes from an integer to be a pointer to an integer is because the size is both value when the function is called ( it tells the kernal the size of the structure so that the kernal does not write past the end of the4 structure when filling it ) and it is the result when the function results (It tells the process how much information the kernal actually stored in the structure). This type of argument is called value � result arguments.
With variable length socket address structure, the value returned can be less than the maximum size of the structure.
Byte Order functions: There are two ways to store the 2 bytes in the memory. With the low orderbyte at the starting address known little endian byte order a or with high order byte at the starting address known as big endian byte order.
The terms little endian or big endian indicate which end of the multi byte value , the little end or the big end is stored at the starting address of the value. Different systems use different orderings. For example, PowerPC of IB, sparc of Sun Soloaris, Happal of HP all use big endian while i386 PC of BSDi and i586 pc of Linux use little endian. The byte order used by a given system is known as the host byte order. As network programmer, one need to deal with the different byte orders. That is the sending and receiving protocol stack must agree on the order in which the bytes of these multibyte fields are transmitted. Internet protocol uses big endian byte ordering for these multibyte system.
Normally, the address structure may be maintained in the host byte order system. Then it may be converted into network byte order as per requirement. However, Posix.1g specifies that the certain files in socket address structure be maintained in network byte order . Therefore, there are function that convert between these two byte orders.
# include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);
uint32_t htons(uint32_t host32bitvalue);
Return value in network byte order.
uint16_t ntohs(uint16_t net16bitvalue);
uint32_t ntohs(uint32_t net16bitvalue);
Returns value in host byte order.
Appropriate function are called to convert a given value between the host and network byte order. On those systems that have the same byte order as the Internet protocols (big endian), these four functions are usually defined as null macros.