Sunday, November 16, 2014

Unix Prog: Socket Addressing(1)

1. Basic Concept

The machine's network address helps us identify the computer on the network. And the service helps us identify the particular process on that computer

2. Byte Ordering
The byte order is a characteristic of the processor architecture, dictating how bytes are ordered within larger data types, such as integers.

big-endian: for value 0x04030201, 4 occupies lowest memory address, 1 occupies highest memory address

little-endian: for value 0x04030201, 4 occupies highest memory address, 1 occupies lowest memory address

Network protocols specify a byte ordering so that heterogeneous computer systems can exchange protocol information without confusing the byte ordering. So applications need to translate processor's byte order to the network byte order or in reverse.

System Calls:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/netinet/in.h  
 ......  
 /* Functions to convert between host and network byte order.  
   
   Please note that these functions normally take `unsigned long int' or  
   `unsigned short int' values as arguments and also return them. But  
   this was a short-sighted decision since on different systems the types  
   may have different representations but the values are always the same. */  
   
 extern uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__));  
 extern uint16_t ntohs (uint16_t __netshort)  
    __THROW __attribute__ ((__const__));  
 extern uint32_t htonl (uint32_t __hostlong)  
    __THROW __attribute__ ((__const__));  
 extern uint16_t htons (uint16_t __hostshort)  
    __THROW __attribute__ ((__const__));  
 ......  

n represents network, h represents host, l represents long, s represents short.
ntohl represents: Convert network byte order to host byte order, unsigned long
ntohs represents: Convert network byte order to host byte order, unsigned short
htonl represents: Convert host byte order to network byte order, unsigned long
htons represents: Convert host byte order to network byte order, unsigned short

3. Address Formats:
1) Generic sockaddr structure
An address identifies a socket endpoint in a particular communication domain. The  address format is specific to the particular domain.

In order to let different socket address structure to be passed to general socket functions, unix has one generic sockaddr address structure, which can be generated by casting domain specific address structure.

 ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/bits/socket.h  
 ......  
 /* Structure describing a generic socket address. */  
 struct sockaddr  
  {  
   __SOCKADDR_COMMON (sa_);  /* Common data: address family and length. */  
   char sa_data[14];      /* Address data. */  
  };  
 ......  

2) IPV4 Address Structure
IPV4 Address can be converted to generic sockaddr structure
 ubuntu@ip-172-31-23-227:~$ less /usr/include/netinet/in.h  
 ......  
 /* Internet address. */  
 typedef uint32_t in_addr_t;  
 struct in_addr  
  {  
   in_addr_t s_addr;  
  };  
 ......  
 /* Structure describing an Internet socket address. */  
 struct sockaddr_in  
  {  
   __SOCKADDR_COMMON (sin_);  
   in_port_t sin_port;         /* Port number. */  
   struct in_addr sin_addr;      /* Internet address. */  
   
   /* Pad to size of `struct sockaddr'. */  
   unsigned char sin_zero[sizeof (struct sockaddr) -  
               __SOCKADDR_COMMON_SIZE -  
               sizeof (in_port_t) -  
               sizeof (struct in_addr)];  
  };  
 ......  

3) IPV6 Address Structure
IPV6 address can also be converted to generic sockaddr structure
 ubuntu@ip-172-31-23-227:~$ less /usr/include/netinet/in.h  
 ......  
 /* IPv6 address */  
 struct in6_addr  
  {  
   union  
    {  
     uint8_t __u6_addr8[16];  
 #if defined __USE_MISC || defined __USE_GNU  
     uint16_t __u6_addr16[8];  
     uint32_t __u6_addr32[4];  
 #endif  
    } __in6_u;  
 #define s6_addr         __in6_u.__u6_addr8  
 #if defined __USE_MISC || defined __USE_GNU  
 # define s6_addr16       __in6_u.__u6_addr16  
 # define s6_addr32       __in6_u.__u6_addr32  
 #endif  
  };  
 ......  
 struct sockaddr_in6  
  {  
   __SOCKADDR_COMMON (sin6_);  
   in_port_t sin6_port;    /* Transport layer port # */  
   uint32_t sin6_flowinfo;   /* IPv6 flow information */  
   struct in6_addr sin6_addr; /* IPv6 address */  
   uint32_t sin6_scope_id;   /* IPv6 scope-id */  
  };  
 ......  

4) Conversion between the binary address format and a string dotted-decimal notation(for example, 127.0.0.1)

 ubuntu@ip-172-31-23-227:~$ less /usr/include/arpa/inet.h  
 ......  
 /* Convert from presentation format of an Internet number in buffer  
   starting at CP to the binary network format and store result for  
   interface type AF in buffer starting at BUF. */  
 extern int inet_pton (int __af, const char *__restrict __cp,  
            void *__restrict __buf) __THROW;  
   
 /* Convert a Internet address in binary network format for interface  
   type AF in buffer starting at CP to presentation form and place  
   result in buffer of length LEN astarting at BUF. */  
 extern const char *inet_ntop (int __af, const void *__restrict __cp,  
                char *__restrict __buf, socklen_t __len)  
    __THROW;  
 ......  

the first argument, af, represents the domain type, only following 2 domains are supported:
AF_INET, AF_INET6 (Only 2 domains are supported: AF_INET, AF_INET6)

No comments:

Post a Comment