Tuesday, 21 July 2015

Introduction to Network Programming using TCP/IP !

The client server programming is the most common type(other is P2P network) of network applications. A server is a program(like Google,Yahoo) that provides services to client(like You). A client is a program that access these services by connecting to a server program.
A socket is the mechanism that most popular operating systems provide to give programs access to the network. It allows messages to be sent and received between applications on different networked machines. There are several different types of sockets that determine the structure of the transport layer .The most common types are stream sockets(TCP) and datagram sockets(UDP). Sockets are created using a system call, and each socket created by the operating system is identified by a small integer called a socket descriptor.The system calls for establishing a connection are somewhat different for the client and the server, but both involve the basic construct of a socket. When an application calls a socket, the operating system allocates a new data structure to hold the information needed for client server communication. Once a socket has been created, it either waits for an incoming connection, called a passive socket,or initiates a connection, called an active socket. A server creates passive socket and a client creates an active socket.
Server Examples : web server(port 80) , FTP server(port 21), Mail server(port 25)
Client Examples : Web-browsers.

Socket Functions :
These functions have their prototypes defined in /usr/include/sys/sockets.h.
1. socket() : create an endpoint for communication
SYNOPSIS : socket(int domain, int type, int protocol);

2. connect() : initiate a connection on a socket.
SYNOPSIS : connect(int fd, struct sockaddr *remote_host, int addr_length);

3.bind() : bind a name to a socket
SYNOPSIS :bind(int fd, struct sockaddr *local_addr, socklen_t addr_length);

4. listen() : listen for connections on a socket.
SYNOPSIS : listen(int fd, int backlog_queue_size);

5.accept(): accept a connection on a socket.
SYNOPSIS : accept(int fd, sockaddr *remote_host, socklen_t *addr_length);

6. send() : Sends n bytes from *buffer to socket fd.
SYNOPSIS :send(int fd, void *buffer, size_t n, int flags)

7. recv() : Receives n bytes from socket fd into *buffer.
SYNOPSIS :recv(int fd, void *buffer, size_t n, int flags)

The steps involved in establishing a socket on the client side are as follows:
1.Create a socket with the socket() system call
2.Connect the socket to the address of the server using the connect() system call
3.Send and receive data. There are a number of ways to do this, but the simplest is to use the read() and write() system calls.

The steps involved in establishing a socket on the server side are as follows:
1.Create a socket with the socket() system call
2.Bind the socket to an address using the bind() system call. For a server socket on the Internet, an address consists of a port number on the host machine.
3.Listen for connections with the listen() system call
4.Accept a connection with the accept() system call. This call typically blocks until a client connects with the server.
5. Send and receive data

This can be understood by a simple diagram :

                                                      



Socket Addresses :
Many of the socket functions reference a sockaddr structure to pass address information that defines a host.
Generic socket addresses :
struct sockaddr {
    uint8_t sa_len;                /* total length of address  */
    sa_family_t sa_family;         /*  family of address */
    char sa_data[14];              /*   the address itself*/
};

sa_data contain a destination address and port number for socket.

To deal with struct sockaddr, programmer created a parallel structure i.e. struct  sockaddr_in(IPv4)

struct sockaddr_in {
    uint8_t sin_len;               /*  total length of adress */
    sa_family_t sin_family;         /*   family of address */
    in_port_t sin_port;             /*  port to connect to */
    struct in_addr sin_addr;         /*  host's IP address */
    char sin_zero[8];                 /* padding, ignored  */
};


Here we deal with Internet Protocol version 4, which is the protocol family PF_INET,  using the address family AF_INET.

                                           


.
Network Byte Order:
The internet protocols specify a format in which binary numbers are passed around between hosts.This format is called network byte order.The port number and IP address used in the AF_INET socket address structure are expected to follow the network byte ordering, which is big-endian. This is the opposite of x86’s little-endian byte ordering, so these values must be converted.
There are several functions specifically for these conversions.

htonl(long value) : Host-to-Network Long
Converts a 32-bit integer from the host’s byte order to network byte order.

htons(short value):  Host-to-Network Short
Converts a 16-bit integer from the host’s byte order to network byte order

ntohl(long value) :Network-to-Host Long
Converts a 32-bit integer from network byte order to the host’s byte order

ntohs(long value)
: Network-to-Host Short
Converts a 16-bit integer from network byte order to the host’s byte order

Internet Address Conversion :

ASCII to Network : inet_aton(char *ascii_addr, struct in_addr *network_addr)

This function converts an ASCII string containing an IP address in dottednumber

format into an in_addr structure.

Network to ASCII : inet_ntoa(struct in_addr *network_addr)

This function converts the other way. It is passed a pointer to an in_addr structure containing an IP address.

Reference : "Hacking: The art of exploitation"
                   "Google"

In the next tutorials we will learn how to write server-client programs.
Note : All the codes given in this blog have been tested under Kali-linux using gcc C compiler.
If you're stuck somewhere, Please feel free to comment !
Facebook Twitter Google+

 
Back To Top