Computer Network Lab Manual
Computer Network Lab Manual
Table of Contents
Syllabus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Course Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6
Expt.1: Getting started with Basics of Network configurations files and Networking
Commands in Linux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Expt. 2: To familiarize and understand the use and functioning of System Calls used for
Operating system and network programming in Linux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Expt. 3: Familiarization and implementation of programs related to Process and thread. . . . . 15
Expt. 4: Implementation of first readers writers problem. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Expt. 5: Implementation of second readers writers problem. . . . .. . . . . . . . . . . . . . . . . . . . . . .25
Expt. 6: Inter-process Communication using Pipes, Message queues, and Shared Memory. . 36
.
Expt. 7: Implementation of Client-Server communication using Socket Programming and
TCP as transport layer protocol. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Expt. 8: Implementation of Client-Server communication using Socket Programming and
UDP as transport layer protocol. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Expt. 9: Implementation of a multi user chat server using TCP as transport layer protocol. . 58
Expt. 10: Implementation of concurrent time server using UDP.. . . . . . . . . . . . . . . . . . . . . . . 69
Expt. 11: Implementation and simulation of algorithm for Distance vector routing protocol . 74
Expt. 12: Implementation and simulation of link state protocol. . . . . . . . . . . . . . . . . . . . . . . . 87
Expt. 13: Implementation of Simple Mail Transfer Protocol. . . . . . . . . . . . . . . . . . . . . . . . . . .93
Expt. 14: Implementation of simple file server. . . . . . . . . . . . . . . . . . . . . . 109
Expt. 15: UDP datagram in client server communication using Wireshark. . . . . . . . . . . . . . . 124
Expt. 16: 3 way handshake during TCP connection establishment using Wireshark. . . . . . . . 126
Expt. 17: Packet capturing and filtering application using raw sockets. . . . . . . . . . . . . . . . . . .129
Expt. 18: Design and Configuration of network and services. . . . . . . . . . . . . . . . . . . . . . . . .134
Expt. 19: Simulation using NS2 simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Syllabus
List of Exercises/ Experiments (12 Exercises/ Experiments are to be completed . Exercises/
Experiments marked with * are mandatory)
1. Getting started with Basics of Network configurations files and Networking Commands in Linux.
2. To familiarize and understand the use and functioning of System Calls used for Operating
system and network programming in Linux.
3. Familiarization and implementation of programs related to Process and thread.
4. Implement the First Readers-Writers Problem.
5. Implement the Second Readers-Writers problem.
6. Implement programs for Inter Process Communication using PIPE, Message Queue and Shared
Memory.
7. Implement Client-Server communication using Socket Programming and TCP as transport layer
protocol.*
8. Implement Client-Server communication using Socket Programming and UDP as transport layer
protocol.*
9. Implement a multi user chat server using TCP as transport layer protocol.*
10. Implement Concurrent Time Server application using UDP to execute the program at remote
server. Client sends a time request to the server, server sends its system time back to the client.
Client displays the result.*
11. Implement and simulate algorithm for Distance vector routing protocol.
12. Implement and simulate algorithm for Link state routing protocol.
13. Implement Simple Mail Transfer Protocol.*
14. Develop concurrent file server which will provide the file requested by client if it exists. If
not server sends appropriate message to the client. Server should also send its process ID (PID)
to clients for display along with file or the message.*
15. Using Wireshark observe data transferred in client server communication using UDP and identify
the UDP datagram.
16.Using Wireshark observe Three Way Handshaking Connection Establishment, Data Transfer and
Three Way Handshaking Connection Termination in client server communication using TCP.
17. Develop a packet capturing and filtering application using raw sockets.
18.Design and configure a network with multiple subnets with wired and wireless LANs using
required network devices. Configure the following services in the network- TELNET, SSH, FTP
server, Web server, File server, DHCP server and DNS server.*
19. Install network simulator NS-2 in any of the Linux operating system and simulate wired
and wireless scenarios.
Experiment 1
1. /etc/hosts
This file is used to resolve hostnames on small networks with no DNS server. This text file contains
a mapping of an IP address to the corresponding host name in each line. This file also contains a line
specifying the IP address of the loopback device i.e, 127.0.0.1 is mapped to localhost.
127.0.0.1 localhost
127.0.1.1 anil-300E4Z-300E5Z-300E7Z
2. /etc/resolv.conf
This configuration file contains the IP addresses of DNS servers and the search domain.
nameserver 127.0.1.1
3. /etc/sysconfig/network
This configuration file specifies routing and host information for all network interfaces. It contains
directives that are global specific. For example if NETWORKING=yes, then /etc/init.d/network
activates network devices.
4. /etc/nsswitch.conf
This file includes database search entries. The directive specifies which database is to be searched first.
1. ifconfig
This gives the IP address, subnet mask, and broadcast address of the wireless LAN adapter.
If eth0 is given as the parameter, the command gives the details of the Ethernet adapter.
2. netstat
Netstat -i
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
As shown above, the command with -i flag provides information on the interfaces. lo stands for
loopback interface.
3. ping
ping www.google.com
^C
A healthy connection is determined by a steady stream of replies with consistent times. Packet loss is
shown by discontinuity of sequence numbers. Large scale packet loss indicates problem along the
path.
Experiment 2
To familiarize and understand the use and functioning of System Calls used for
Operating system and network programming in Linux.
1. ps
This command tells which all processes are running on the system when ps runs.
ps -ef
This command gives processes running on the system, the owners of the processes and the names of
the processes. The above result is an abridged version of the output.
2. fork
This system call is used to create a new process. When a process makes a fork system call, a new
process is created which is identical to the process creating it. The process which calls fork is called
the parent process and the process that is created is called the child process. The child and parent
processes are identical, i.e, child gets a copy of the parent's data space, heap and stack, but have
different physical address spaces. Both processes start execution from the line next to fork. Fork
returns the process id of the child in the parent process and returns 0 in the child process.
#include<stdio.h>
void main()
int pid;
pid = fork();
if(pid > 0)
else
printf(“Iam child\n”);
The parent process prints the first statement and the child prints the next statement.
3. exec
New programs can be run using exec system call. When a process calls exec, the process is
completely replaced by the new program. The new program starts executing from its main function.
A new process is not created, process id remains the same, and the current process's text, data, heap,
and stack segments are replaced by the new program. exec has many flavours one of which is execv.
execv takes two parameters. The first is the pathname of the program that is going to be executed. The
second is a pointer to an array of pointers that hold the addresses of arguments. These arguments are
the command line arguments for the new program.
4. wait
When a process terminates, its parent should receive some information reagarding the process like the
process id, the termination status, amount of CPU time taken etc. This is possible only if the parent
process waits for the termination of the child process. This waiting is done by calling the wait system
call. When the child process is running, the parent blocks when wait is called. If the child terminates
normally or abnormally, wait immedaitely returns with the termination status of the child. The wait
system call takes a parameter which is a pointer to a location in which the termination status is stored.
5. exit
6. open
This system call is used to open a file whose pathname is given as the first parameter of the function.
The second parameter gives the options that tell the way in which the file can be used.
open(filepathname , O_RDWR);
This causes the file to be read or written. The function returns the file descriptor of the file.
7. read
The above function reads sizeof(buffer) bytes into the array named buffer. If the end of file is
encountered, 0 is returned, else the number of bytes read is returned.
8. write
1. Creating a socket
This sytem call creates a socket and returns a socket descriptor. The domain parameter specifies a
communication domain; this selects the protocol family which will be used for communication. These
families are defined in <sys/socket.h>. In this program the AF_INET family is used. The type
parameter indicates the communication semantics. SOCK_STREAM is used for tcp connection while
SOCK_DGRAM is used for udp connection. The protocol parameter specifies the protocol used and is
always 0. The header files used are <sys/types.h> and <sys/socket.h>.
Experiment 3
Process
A process is an active entity which has a text section which contains the program code, data section
which contains global variables, a heap that is dynamically allocated during process run time, and a
process stack which contains temporary data. A process is created when an executable program is
loaded into memory. Two or more processes can be associated with the same program and even
though they may share the same text section, they have different stack, data and heap sections.
Threads
A thread is a basic unit of CPU utilization. It has an ID, register set and a stack. Normally a process
has a single thread of control. However, processes can have multiple threads of control which will
allow them to perform more than one task at a time. Threads within a process share the same code
section, data section and operating system resources like open files and signals. Since process creation
is time consuming and resource intensive, it is often advantageous to use one process that contains
multiple threads to do the same task.
Thread libraries provide users with an API for creating and managing threads. A thread library may be
created at the user level or at the kernel level. In the former case, invoking a function in the library
results in a local function call, while in the latter case such an invocation will be a system call. One
important thread library is the POSIX Pthreads. POSIX standard gives a specification for thread
creation and its behaviour. Operating systems, mostly UNIX type systems implement this standard in
different ways.
1. pthread_init_attr(&attr)
This function sets the attributes of the thread like stack size, scheduling information etc.
3. pthread_join(tid, NULL)
The parent thread waits till the child threads terminate and join with the parent. Afterwards, the parent
continues execution.
Example:
This program shows how a child process is created to do a task. The program in expt2.c creates a child
process for finding the sum of two numbers.
expt2.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
pid = fork();
wait(NULL);
exit(0);
prog2.c
#include<stdio.h>
a = atoi(argv[1]);
b = atoi(argv[2]);
sum = a + b;
printf("sum = %d\n", sum);
}
will give 7 as the sum. The path for execv should be substituted with your path.
After the fork system call, the child process executes the prog2 program. The parent process waits for
the termination of the child process.
#include<stdio.h>
#include<pthread.h>
void * func_sum(void*);
int sum ;
./expt3 3 4
Experiment 4
Description
Readers writers problem is a synchronization problem. There are two types of processes:- writers and
readers which are sharing a common resource. A reader process can share the process with other
readers but not writers. A writer process requires exclusive access to the resource. A very good
example is a file being shared among a set of processes. As long as a reader holds the resource and
there are new readers arriving, any writer must wait for the resource to become available.
The first reader accessing the resource must compete with any writers, but once a writer succeeds the
other readers can pass directly into the critical section provided that at least one reader is still in the
critical section. The readCount variable gives the number of readers in the critical section. Only when
the last reader leaves the critical section can the writers enter the critical section one at a time which
will based on writeBlock variable.
Algorithm
The algorithm for the readers writers problem is given below (Gary Nutt)
reader() {
while(TRUE) {
<other computing>
P(mutex);
readCount = readCount +1;
if(readCount == 1)
P(writeBlock);
V(mutex);
/* critical section */
access resource
P(mutex);
readCount = readCount – 1;
if(readCount == 0)
V(writeBlock);
V(mutex);
}
}
writer() {
while(TRUE) {
<other computing>;
P(writeBlock);
/* critical section */
access resource
V(writeBlock);
}
}
The above algorithm is implemented using threads. Mutex and writeBlock are two semaphores. The
first semaphore guards the readCount variable while the latter protects the critical section where the
resource is shared.
Program
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdlib.h>
sem_t mutex;
sem_t writeBlock;
writers_num[k] = k;
if(sem_init(&mutex, 0, 1) < 0)
{
perror("Could not init semaphore mutex");
exit(1);
}
if(sem_init(&writeBlock, 0, 1) < 0)
{
perror("Could not init semaphore writeBlock");
exit(1);
}
sem_destroy(&mutex);
sem_destroy(&mutex);
while(1)
{
sleep(1);
if(sem_wait(&mutex) < 0)
{
perror("cannot decrement the semaphore mutex");
exit(1);
}
readCount = readCount + 1;
if(readCount == 1)
{
if(sem_wait(&writeBlock) < 0)
{
perror("cannot decrement the semaphore writeBlock");
exit(1);
}
}
// READ RESOURCES
printf("READER %d is READING \n", i);
sleep(1);
if(sem_wait(&mutex) < 0)
{
perror("cannot decrement the semaphore mutex");
exit(1);
readCount = readCount - 1;
if(readCount == 0)
{
while(1)
{
sleep(1);
if(sem_wait(&writeBlock) < 0)
{
perror("cannot decrement the semaphore writeBlock");
exit(1);
}
// WRITE RESOURCES
printf("WRITER %d IS WRITING \n", i);
if( sem_post(&writeBlock) < 0)
{
Output
anil@anil-300E4Z-300E5Z-300E7Z:~/NetworkLab$ ./expt4
READER 0 is READING
READER 1 is READING
READER 2 is READING
READER 4 is READING
READER 3 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
WRITER 2 IS WRITING
READER 2 is READING
READER 3 is READING
READER 0 is READING
READER 1 is READING
READER 4 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
WRITER 2 IS WRITING
READER 2 is READING
READER 4 is READING
READER 3 is READING
READER 1 is READING
READER 0 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
WRITER 2 IS WRITING
READER 4 is READING
READER 3 is READING
READER 0 is READING
READER 1 is READING
READER 2 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
WRITER 2 IS WRITING
READER 1 is READING
READER 2 is READING
READER 0 is READING
READER 4 is READING
READER 3 is READING
Experiment 5
Description
In the first readers writers problem, readers can dominate the resource and it will not be possible for a
writer to access the resource. In order to give preference to writers, it is necessary to prevent a
subsequent reader process from gaining access to the shared resource till the writer accesses the shared
resource and releases it. An algorithm to achieve this task is given below (Gary Nutt).
Here a stream of readers can enter the critical section till a writer arrives. When a writer arrives, it
takes access of the resource after all existing readers leave the critical section. When the first writer
arrives, it will obtain the readBlock semaphore. Then it blocks on the writeBlock semaphore, waiting
for all readers to clear the critical section. The next reader to arrive will obtain the writePending
semaphore and then block on the readBlock semaphore. If another writer arrives during this time, it
will block on the writeBlock semaphore. If a second reader arrives, it will block on the writePending
semaphore.
Algorithm
reader() {
while(TRUE) {
<other computing>
P(writePending);
P(readBlock);
P(mutex1);
if(readCount == 1)
P(writeBlock);
V(mutex1);
V(readBlock);
V(writePending);
/* critical section */
access resource
P(mutex1);
readCount = readCount – 1;
if(readCount == 0)
V(writeBlock);
V(mutex1);
writer() {
while(TRUE) {
<other computing>;
P(mutex2);
writeCount = writeCount + 1;
if(writeCount == 1)
P(readBlock);
V(mutex2);
P(writeBlock);
/* critical section */
access resource
V(writeBlock);
P(mutex2);
writeCount = writeCount - 1;
if(writeCount == 0)
V(readBlock);
V(mutex2);
The above algorithm is implemented using threads. Mutex1, mutex2, writeBlock, readBlock
and writePending are the semaphores used.
Program
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdlib.h>
sem_t writeBlock;
sem_t readBlock;
sem_t writePending;
int i, j, k;
scanf("%d", &N_readers);
scanf("%d", &N_writers);
readers_num[k] = k;
writers_num[k] = k;
if(sem_init(&mutex1, 0, 1) < 0)
exit(1);
if(sem_init(&mutex2, 0, 1) < 0)
exit(1);
if(sem_init(&writeBlock, 0, 1) < 0)
exit(1);
if(sem_init(&readBlock, 0, 1) < 0)
exit(1);
if(sem_init(&writePending, 0, 1) < 0)
exit(1);
exit(1);
exit(1);
pthread_join(tid_readers[i], NULL);
pthread_join(tid_writers[j], NULL);
sem_destroy(&mutex1);
sem_destroy(&mutex2);
sem_destroy(&readBlock);
sem_destroy(&writeBlock);
sem_destroy(&writePending);
while(1)
sleep(1);
if(sem_wait(&writePending) < 0)
exit(1);
if(sem_wait(&readBlock) < 0)
exit(1);
if(sem_wait(&mutex1) < 0)
exit(1);
readCount = readCount + 1;
if(readCount == 1)
if(sem_wait(&writeBlock) < 0)
exit(1);
exit(1);
exit(1);
exit(1);
// READ RESOURCES
sleep(1);
if(sem_wait(&mutex1) < 0)
exit(1);
readCount = readCount - 1;
if(readCount == 0)
exit(1);
exit(1);
while(1)
sleep(1);
if(sem_wait(&mutex2) < 0)
exit(1);
if(writeCount == 1)
if(sem_wait(&readBlock) < 0)
exit(1);
exit(1);
if(sem_wait(&writeBlock) < 0)
exit(1);
// WRITE RESOURCES
exit(1);
if(sem_wait(&mutex2) < 0)
exit(1);
writeCount = writeCount - 1;
if(writeCount == 0)
exit(1);
exit(1);
Output
anil@anil-300E4Z-300E5Z-300E7Z:~/NetworkLab$ ./expt5
READER 2 is READING
READER 0 is READING
READER 1 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
READER 2 is READING
READER 0 is READING
READER 1 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
READER 2 is READING
READER 0 is READING
READER 1 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
READER 2 is READING
READER 0 is READING
READER 1 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
READER 2 is READING
READER 0 is READING
READER 1 is READING
WRITER 0 IS WRITING
WRITER 1 IS WRITING
READER 2 is READING
READER 1 is READING
READER 0 is READING
Experiment 6
Aim: To communicate between two processes using pipes and message queues.
Description:
In this experiment a pipe is used to connect a client with the server. The client reads the name of a file
from the standard input. It then writes the name of the file on to the pipe. The server reads the file from
the read end of the pipe. After that, the server opens the file and reads the contents of the file line by
line. Each line that it reads is sent to the client and written to the standard output. The data is
transferred using the message structure. It has a header, which gives the length of the message and the
type of the message which is a positive integer. The data is carried in an array within the message
structure. The data flow through pipes is as shown in the figure.
PICTURE
Algorithm
1. Read the filename from the standard input into the data portion of the message
2. Construct the message structure
3. Write the message to pipe 1
4. Read the message from the client on pipe2 and write to the standard output
Program
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include “pipe.h”
// creation of pipes
if(pipe(fd1) < 0)
{
perror(“pipe creation error”);
exit(1);
}
if(pipe(fd2) < 0)
{
perror(“pipe creation error”);
exit(1);
}
server(fd1[0], fd2[1]);
exit(0);
}
else // parent process (client process)
{
close( fd1[0]);
close(fd2[1]);
client(fd2[0], fd1[1]);
if(waitpid(childpid, NULL,0) < 0)
{
perror(“waitpid error”);
exit(1);
}
exit(0);
}
}
length = strlen(mesg.message_data);
mesg.message_length = length;
mesg.message_type = 1;
while(1)
{
if(n = read(readfd, &mesg, MESGHDRSIZE)) == -1)
{
perror(“read error”);
exit(1);
}
length = mesg.message_length;
if(length == 0) break;
mesg.message_type = 1;
n = read(readfd, &mesg, MESGHDRSIZE);
if( n!=MESGHDRSIZE)
{
fprintf(stderr, “header size not same \n”);
exit(1);
}
length =mesg.message_length;
n = read(readfd, mesg.message_data, length);
mesg.message_data[n] = '\0';
fclose(fp);
}
mesg.message_length = 0;
Header file
#ifndef _PIPE
#define _PIPE
#include<stdio.h>
#include<limits.h>
struct message
{
long message_length;
long message_type;
char message_data[MAXMESSAGEDATA];
};
#endif
Output
Using pipes send a filename from a client to a server. Open the file in the server and send the contents
of the
file to
the
client
using
pipe
and
displa
y it on
the
consol
e.
Experiment 7
Implementation of Client-Server communication using Socket Programming and
TCP as transport layer protocol
Aim: Client sends a string to the server using tcp protocol. The server reverses the string and returns
it to the client, which then displays the reversed string.
Description:
This function call creates a socket and returns a socket descriptor. The domain parameter specifies a
communication domain; this selects the protocol family which will be used for communication. These
families are defined in <sys/socket.h>. In this program, the domain AF_INET is used. The socket has
the indicated type, which specifies the communication semantics. SOCK_STREAM type provides
sequenced, reliable, two-way, connection based byte streams. The protocol field specifies the protocol
used. We always use 0. If the system call is a failure, a -1 is returned. The header files used are
sys/types.h and sys/socket.h.
struct sockaddr_in {
u_short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8]; /*unused, always zero*/
};
struct in_addr
{
u_long s_addr;
};
Example
Why htons is used ?. Numbers on different machines may be represented differently ( big-endian
machines and little-endian machines). In a little-endian machine the low order byte of an integer
appears at the lower address; in a big-endian machine instead the low order byte appears at the higher
address. Network order, the order in which numbers are sent on the internet is big-endian. It is
necessary to ensure that the right representation is used on each machine. Functions are used to convert
from host to network form before transmission- htons for short integers and htonl for long integers.
The binary value of the dotted decimal IP address is stored in the field when the function returns.
This is optional in the case of client and we usually do not use the bind function on the client side.
A server is identified by an IP address and a port number. The connection operation is used on
the client side to identify and start the connection to the server.
6. writing to a socket
In the case of TCP connection writing to a socket can be done using the write system call
This system call creates a socket and returns a socket descriptor. The domain field used is AF_INET.
The socket type is SOCK_STREAM. The protocol field is 0. If the system call is a failure, a -1 is
returned. Header files used are sys/types.h and sys/socket.h.
This call is used to specify for a socket the protocol port number where it will wait for messages. A
call to bind is optional on the client side, but required on the server side. The first field is the socket
descriptor of local socket. Second is a pointer to protocol address structure of this socket. The third is
the length in bytes of the structure referenced by addr. This system call returns an integer. It is 0
for success and -1 for failure. The header files are sys/types.h and sys/socket.h.
The listen function is used on the server in the connection oriented communication to prepare a socket
to accept messages from clients.
The accept function is used on the server in the case of connection oriented communication to accept a
connection request from a client.
The first field is the descriptor of server socket that is listening. The second parameter addressp points
to a socket address structure that will be filled by the address of calling client when the function
returns. The third parameter addrlen is an integer that will contain the actual length of address
structure of client. It returns an integer that is a descriptor of a new socket called the connection socket.
Server sockets send data and read data from this socket. The header files used are sys/types.h and
sys/socket.h.
Algorithm
Client
1. Create socket
2. Connect the socket to the server
3. Read the string to be reversed from the standard input and send it to the server
Read the matrices from the standard input and send it to server using socket
4. Read the reversed string from the socket and display it on the standard output
Read product matrix from the socket and display it on the standard output
5. Close the socket
Server
6. Read the string using the connection socket from the client
Client Program
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
bzero(&server, sizeof(server) );
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET, argv[1], &server.sin_addr);
printf("%s\n", buffer);
close(fd);
}
Server Program
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
char buffer[100];
bzero(&server, sizeof(server) );
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
server.sin_addr.s_addr = htonl(INADDR_ANY);
listen(sd,5);
read(data,buffer, sizeof(buffer));
len = strlen(buffer);
for( i =0; i<= len/2; i++)
{
temp = buffer[i];
buffer[i] = buffer[len - 1-i];
buffer[len-1-i] = temp;
}
close(data);
close(sd);
}
Output
Server
Client
Experiment 8
Aim: Client sends two matrices to the server using udp protocol. The server multiplies the matrices
and sends the product to the client, which then displays the product matrix.
Description:
The domain parameter specifies a communication domain; this selects the protocol family which will
be used for communication. These families are defined in <sys/socket.h>. In this program, the domain
AF_INET is used. The next field type has the value SOCK_DGRAM. It supports datagrams
(connectionless, unreliable messages of a fixed maximum length). The protocol field specifies the
protocol used. We always use 0. If the socket function call is successful, a socket descriptor is
returned. Otherwise -1 is returned. The header files necessary for this function call are sys/types.h and
sys/socket.h.
struct sockaddr_in {
u_short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8]; /*unused, always zero*/
};
struct in_addr
{
u_long s_addr;
};
The binary value of the dotted decimal IP address is stored in the field when the function returns.
This call is used to specify for a socket the protocol port number where it will wait for messages. A
call to bind is optional in the case of client and compulsory on the server side.
The first field is the socket descriptor. The second is a pointer to the address structure of this socket.
The third field is the length in bytes of the size of the structure referenced by addr. The header files are
sys/types.h and sys/socket.h. This function call returns an integer, which is 0 for success and -1 for
failure.
4. Receiving data
ssize_t recvfrom(int s, void * buf, size_t len, int flags, struct sockaddr * from, socklen_t *
fromlen);
The recvfrom calls are used to receive messages from a socket, and may be used to receive data on a
socket whether or not it is connection oriented. The first parameter s is the socket descriptor to read
from. The second parameter buf is the buffer to read information into. The third parameter len is the
maximum length of the buffer. The fourth parameter is flag. It is set to zero. The fifth parameter from
is a pointer to struct sockaddr variable that will be filled with the IP address and port of the
orginating machine. The sixth parameter fromlen is a pointer to a local int variable that should be
initialized to sizeof(struct sockaddr). When the function returns, the integer variable that fromlen
points to will contain the actual number of bytes that is contained in the socket address structure. The
header files required are sys/types.h and sys/socket.h. When the function returns, the number of bytes
received is returned or -1 if there is an error.
5. Sending data
ssize_t sendto(int s, const void * buf, size_t len, int flags, const struct sockaddr * to, socklen_t
tolen);
The first parameter s is the socket descriptor of the sending socket. The second parameter buf is the
array which stores data that is to be sent. The third parameter len is the length of that data in bytes. The
fourth parameter is the flag parameter. It is set to zero. The fifth parameter to points to a variable that
contains the destination IP address and port. The sixth parameter tolen is set to sizeof(struct
sockaddr). This function returns the number of bytes actually sent or -1 on error. The header files used
are sys/types.h and sys/socket.h.
Algorithm
Client
1. Create socket
2. Read the matrices from the standard input and send it to server using socket
3. Read product matrix from the socket and display it on the standard output
Server
1. Create socket
Client program
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
main(int argc, char * argv[])
{
int i,j,n;
int sock_fd;
if(argc != 3)
{
fprintf(stderr, "Usage: ./client IPaddress_of_server port\n");
exit(1);
}
size[0][0] = num_rows_1;
size[0][1] = num_cols_1;
scanf("%d", &matrix_2[i][j]);
}
size[1][0] = num_rows_2;
size[1][1] = num_cols_2;
bzero((char*)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
if( n < 0)
{
perror("error in matrix 1 sending");
exit(1);
}
// SENDING MATRIX 1
n = sendto(sock_fd, matrix_1, sizeof(matrix_1),0, (struct sockaddr*)&servaddr, sizeof(servaddr));
if( n < 0)
{
perror("error in matrix 1 sending");
exit(1);
}
// SENDING MATRIX 2
if( n < 0)
{
perror("error in matrix 2 sending");
exit(1);
close(sock_fd);
Server Program
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
int n;
int sock_fd;
int i,j,k;
if(argc != 2)
{
fprintf(stderr, "Usage: ./server port\n");
exit(1);
}
bzero((char*)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[1]));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
// MATRICES RECEIVE
// RECEIVE MATRIX 1
// RECEIVE MATRIX 2
row_1 = size[0][0];
col_1 = size[0][1];
row_2 = size[1][0];
col_2 = size[1][1];
if( n < 0)
{
perror("error in matrix product sending");
exit(1);
}
close(sock_fd);
}
Output
Server
Client
Experiment 9
Implementation of a multi user chat server using TCP as transport layer protocol
Aim: To implement a chat server so that multiple users can chat simultaneously
Description
To implement chat server the select function is used. It is a function called by a process. When a
process calls this function , the process goes to sleep and wakes up only when one or more events
occur or when a specified amount of time has passed.
int select (int maxfdp1, fd_set * readset, fd_set * writeset, fd_set * exceptset, const struct timeval
* timeout);
Usage:
fd_set rset;
FD_ZERO(&rset); // all bits off
FD_SET(1, &rset); // turn on bit for fd 1
FD_SET(4, &rset); // turn on bit for fd 4
Initially you have to initialize the set. If we are not interested in a condition we can set that argument
of select to NULL, i.e; for readset, writeset or exceptset.
maxfdp1 argument specifies the number of descriptors to be tested. It is equal to value of max
descriptor to be tested plus one. This is because descriptor starts with 0. When we call select we
specify the values of the descriptors that we are interested in and on return the result indicates which
descriptors are ready. We turn on all the bits in the descriptor sets that we are interested in. On return
of the call, descriptors that are not ready will have the corresponding bit cleared in the descriptor set.
Department of Computer Science & Engineering, CEP
Network Programming Lab Manual P a g e | 55
We can use select to create a server which can handle clients without forking process for each client.
rset
Client
-1
-1
-1
-1
.
.
.
-1
Descriptors 0, 1, 2 are respectively for standard input, output and error. Next available descriptor is 3
which is set for listening socket. Client is an array that contains the connected socket descriptor for
each client. All elements are initialized to -1. The first non zero for descriptor set is that for the
listening socket. When the first client establishes a connection with the server, the listening descriptor
becomes readable and server calls accept. The new connected descriptor will be 4. The arrays are
updated.
rset
Client
4
-1
-1
-1
.
.
.
-1
rset
Client
4
5
-1
-1
.
.
.
-1
If the first client terminates connection by sending a FIN segment, descriptor 4 becomes readable and
read returns 0. This socket is closed by the server and data structures are updated.
rset
Client
-1
5
-1
-1
.
.
.
-1
The descriptor 4 in rset is set to zero. When clients arrive the connected socket descriptor is placed in
the first available entry, i.e; first entry with value equal to -1.
Program
client
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
{
int i,j,n;
int sock_fd, max_fd, nready, fd[2];
if(argc != 3)
{
fprintf(stderr, "Usage: ./client IPaddress_of_server port\n");
exit(1);
}
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Cannot create socket\n");
exit(1);
}
bzero((char*)&servaddr, sizeof(servaddr));
bzero(line, sizeof(line));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
fd[0] = 0;
fd[1] = sock_fd;
for(; ; )
{
FD_ZERO(&rset);
FD_SET(0, &rset);
FD_SET(sock_fd, &rset);
bzero(line, sizeof(line));
max_fd = sock_fd;
if(FD_ISSET(fd[j], &rset))
{
if(j == 0)
{
n = write(fd[j+1], line, strlen(line));
}
else
{
printf("%s \n", line);
}
if(--nready == 0)
break;
}
}
}
}
server
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
{
int n, i, maxi, max_fd, k;
int sock_fd, listen_fd, connfd, client_no;
int nready, num_q, client[100], chat[100], conn[1000];
client_no = 0;
if(argc != 2)
{
fprintf(stderr, "Usage: ./server port\n");
exit(1);
}
bzero((char*)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[1]));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
listen(listen_fd, num_q);
max_fd = listen_fd;
maxi = -1;
FD_SET(listen_fd, &allset);
for(; ;)
{
rset = allset;
nready = select(max_fd + 1, &rset, NULL, NULL, NULL);
if(FD_ISSET(listen_fd, &rset))
{
if((connfd = accept(listen_fd, (struct sockaddr *) &cliaddr, &len))<0)
{
perror("accept failed");
exit(1);
}
chat[++client_no] = connfd;
conn[connfd] = client_no;
k = client_no;
sprintf(buffer, "Client %d has joined chat\n", k);
while(k > 0 )
{
if(chat[k] >0)
n = write(chat[k--], buffer, strlen(buffer));
}
}
FD_SET(connfd, &allset);
if(connfd > max_fd)
max_fd = connfd;
if(--nready <= 0)
continue;
}
bzero(buffer, sizeof(buffer));
sprintf(buffer, "Client %d has left chat\n", conn[sock_fd]);
k = client_no;
while(k > 0 )
{
if(chat[k] > 0)
n = write(chat[k--], buffer, strlen(buffer));
}
}
else
{
if(chat[line[0] - 48] > 0)
write(chat[line[0] - 48], line, strlen(line));
}
if(--nready <= 0)
break;
}
}
}
Output
The server is started first. Each client then starts. The clients are numbered consecutively. If client x
wants to send message to client y, client x writes
y From x: “contents of message”
The screenshots show 3 clients chatting with each other through the server running on port 5500.
Server
Client 1
Client 2
Client 3
Experiment 10
Aim: Client sends a time request to the server, server sends its system time back to the client.
Description:
A concurrent server handles multiple clients at the same time. The simplest technique for a concurrent
server is to call the Unix fork function, i.e; creating one child process for each client.
The current time and date is obtained by the library function time which returns the number of seconds
since the Unix Epoch: 00:00:00 January 1, 1970, UTC (Coordinated Universal Time). ctime is a
function that converts this integer value into a human readable string.
Algorithm:
Client
4. Display the
result Server
3. while (1)
Program
Client
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
if(argc != 3)
{
fprintf(stderr, "Usage: ./client IPaddress_of_server port\n");
exit(1);
}
bzero((char*)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
Server
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
#include<time.h>
time_t curtime;
struct sockaddr_in servaddr, cliaddr;
int len = sizeof(cliaddr);
if(argc != 2)
{
fprintf(stderr, "Usage: ./server port\n");
exit(1);
}
bzero((char*)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[1]));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
while(1)
{
if((n = recvfrom(sock_fd,buffer , sizeof(buffer), 0, (struct sockaddr *)&cliaddr, &len)) == -1)
{
perror("size not received:");
exit(1);
}
childpid = fork();
if(childpid == 0)
{
time(&curtime);
sprintf( buffer, "= %s", ctime(&curtime));
n = sendto(sock_fd, buffer, sizeof(buffer),0, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
if( n < 0)
{
perror("error in sending");
exit(1);
}
exit(1);
}
}
Output
Server
client
Experiment 11
Aim: To implement and simulate algorithm for Distance vector routing protocol
Description:
This algorithm is iterative, and distributed. Each node receives information fromits directly attached
neighbours, performs some calculations and returns the result the result to its neighbouring nodes. This
process of updating the information goes on until there is no exchange of information between
neighbours.
Algorithm:
(adapted from Computer Networking – A top down approach by Kurose and Rose)
Let dx(y) be the cost of the least cost path from node x to node y. Then Bellman Ford equation states
that
dx(y) = min{ c(x,v) + dv(y) }
v
where v is a neighbour of node x. dv(y) is the cost of the least cost path from v to y. c(x,v) is the cost
from x to neighbour v. The least cost path has a value equal to minimum of c(x,v) + dv(y) over all its
neighbours v. The solution of Bellman Ford equation provides entries in node x's forwarding table.
At each node x
Initialization:
loop:
for each y in N:
Dx(y) = min { c(x,v) + Dv(y) }
Program
The simulation is done on the principle of a chat server given in Expt 9. Each node is considered as a
client that connects to a server. Each node reads the cost matrix and constructs the distance vector
matrix which is a 3D matrix (RT), where the first element denotes the number of the node. After
entering the cost matrix for each node, each node exchanges its distance vector matrix with its
neighbours. This process goes on till there are no changes in the dsitance vector matrix table for each
node. In the cost matrix infinite cost between two nodes is represented by 999.
client.c
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
struct message {
int to_node;
int from_node;
int RT[20][20][20];
};
int node, p;
int from_node_it;
int to_node_it, t;
int prev[20];
int cost[10][10];
int N[20][20];
temp1 = 999;
h=0;
printf("Enter number of nodes:");
scanf("%d", &num_nodes);
// NEIGHBOURS
// COST MATRIX
{
N[i][j] = j;
}
}
if(argc != 3)
{
fprintf(stderr, "Usage: ./client IPaddress_of_server port\n");
exit(1);
}
bzero((char*)&servaddr, sizeof(servaddr));
bzero(line, sizeof(line));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
fd[0] = 0;
fd[1] = sock_fd;
for(; ; )
{
FD_ZERO(&rset);
FD_SET(0, &rset);
FD_SET(sock_fd, &rset);
bzero(line, sizeof(line));
max_fd = sock_fd;
getchar();
getchar();
t++;
}
}
else
{
read(fd[j], &mesg_from, sizeof(mesg_from));
to_node_it = mesg_from.to_node;
from_node_it = mesg_from.from_node;
mesg.RT[to_node_it][to_node_it][to_node_it] = 0;
i = from_node_it;
while(N[to_node_it][h] != -1)
{
if(N[to_node_it][h] != 0)
{
if(N[to_node_it][h] == from_node_it)
{
node_sel = from_node_it;
if (temp1 > cost[to_node_it][N[to_node_it][h]] +
mesg_from.RT[node_sel][N[to_node_it][h]][i])
temp1 = cost[to_node_it][N[to_node_it][h]] +
mesg_from.RT[node_sel][N[to_node_it][h]][i];
}
else
{
node_sel = to_node_it;
if (temp1 > cost[to_node_it][N[to_node_it][h]] +
mesg.RT[node_sel][N[to_node_it][h]][i])
temp1 = cost[to_node_it][N[to_node_it][h]] +
mesg.RT[node_sel][N[to_node_it][h]][i];
}
} h+
+;
}
mesg.RT[to_node_it][to_node_it][i] = temp1;
h=0;
temp1 =999;
}
if(--nready == 0)
break;
}
}
server.c
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
struct message {
int to_node;
int from_node;
int RT[20][20][20];
};
bzero(line, sizeof(line));
client_no = 0;
if(argc != 2)
{
fprintf(stderr, "Usage: ./server port\n");
exit(1);
}
bzero((char*)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[1]));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
listen(listen_fd, num_q);
max_fd = listen_fd;
maxi = -1;
FD_ZERO(&allset);
FD_SET(listen_fd, &allset);
for(; ;)
{
rset = allset;
nready = select(max_fd + 1, &rset, NULL, NULL, NULL);
if(FD_ISSET(listen_fd, &rset))
{
if((connfd = accept(listen_fd, (struct sockaddr *) &cliaddr, &len))<0)
{
perror("accept failed");
exit(1);
}
chat[++client_no] = connfd;
conn[connfd] = client_no;
k = client_no;
// sprintf(buffer, "Client %d has joined chat\n", k);
FD_SET(connfd, &allset);
if(connfd > max_fd)
max_fd = connfd;
maxi = i;
if(--nready <= 0)
continue;
// client closing
if( n == 0)
{
close(sock_fd);
FD_CLR(sock_fd, &allset);
client[i] = -1;
}
else
{
// writing to another client
write(chat[mesg.to_node +1], &mesg, sizeof(mesg));
}
if(--nready <= 0)
break;
}
}
Output
client (Node 0)
anil@anil-300E4Z-300E5Z-300E7Z:~/NetworkLab/EXPT 11$ ./client 127.0.0.1 5080
Enter number of nodes:3
Enter the cost matrix, For infinity enter 999
027
201
710
027
999 999 999
999 999 999
ITERATION RESULT FOR ROUTING TABLE
027
201
999 999 999
ITERATION RESULT FOR ROUTING TABLE
023
201
710
ITERATION RESULT FOR ROUTING TABLE
023
201
310
ITERATION RESULT FOR ROUTING TABLE
client (Node 1)
client (Node 2)
201
710
ITERATION RESULT FOR ROUTING TABLE
023
201
310
ITERATION RESULT FOR ROUTING TABLE
Experiment 12
Description:
Routing algorithms can be classified as global or centralized. A global routing algorithm computes the
least cost path between a source and destination using knowledge about the entire network. Global
algorithm has complete information about connectivity and link costs. Such algorithms are called link
state algorithms.
Algorithm:
(adapted from
It is the Dijkstra algorithm. This algorithm finds the shortest (least cost paths) from the source u to
every other node in the network.
D(v) : cost of the least cost path fromthe source node to the destination node v as of this iteration of the
algorithm
p(v): previous node of v along the current least cost path from the source to v
N' : subset of nodes. v is in N' if the least cost path from the source to v is definitely known
Iniltialization :
N' = {u}
do {
} while ( N' != N)
Program
#include<stdio.h>
int cost[10][10];
int dist[10];
int arr[20];
void djikstra(int);
int search(int);
int length_of( int * );
void print_route(int, int);
int prev[20];
int order_arr[20];
int src;
main()
{
int num_nodes,i, j, d;
djikstra( num_nodes);
}
void djikstra(int _num_nodes )
{
int i, min_val, l;
int k =0;
int m =0;
int min =999;
int last;
int neighbour[20];
arr[0] = src;
last =0;
last++;
arr[last] = min_val;
{
if(search(i) == 0)
{
if(cost[min_val][i] < 999)
{
neighbour[m] = i;
m++;
}
}
}
m =0;
while(neighbour[m] != -1)
{
if(dist[min_val] + cost[min_val][neighbour[m]] < dist[neighbour[m]])
{
dist[neighbour[m]] = dist[min_val] + cost[min_val][neighbour[m]];
prev[neighbour[m]] = min_val;
}
m++;
}
m=0;
for(i = 0; i <_num_nodes; i++)
neighbour[i] = -1;
min =999;
min_val = -1;
i =1;
l=1;
while( i < _num_nodes)
{
print_route(i, l);
printf("[ distance = %d]", dist[i]);
printf("\n");
i++;
l++;
for(k = 0; k <20; k++)
order_arr[k] = -1;
}
}
if( _i == src)
{
ptr = order_arr;
while(*ptr != -1)
ptr++;
len = ptr-order_arr;
+)
{
temp = order_arr[h];
order_arr[h] = order_arr[len - h -1];
order_arr[len-h-1] = temp;
}
ptr = order_arr;
printf("%d", src);
while(*ptr != -1)
{
printf("->%d ", *ptr);
ptr++;
}
return;
}
else
{
order_arr[inc[_l]] = _i;
inc[_l]++;
print_route(prev[_i], _l);
}
}
int search(_i)
{
int i =0;
if(_i == arr[i])
break;
else
i++;
}
if(arr[i] == -1)
return 0;
else
return 1;
}
FIGURE
When finding out the cost matrix use 999 in the place of ∞.
Experiment 13
Aim: To implement a subset of simple mail transfer protocol (SMTP) using UDP
Description:
SMTP provides for mail exchanges between users on the same or different computers. The SMTP
client and server can be divided into two components: user agent (UA) and mail transfer agent (MTA).
The user agent is a program used to send and receive mail. The actual mail transfer is done through
mail transfer agents. To send mail, a system must have client MTA, and to receive mail, a system must
have a server MTA. SMTP uses commands and responses to transfer messages between an MTA client
and MTA server. Commands are sent from the client to the server. It consists of a keyword followed
by zero or more arguments. Examples: HELO, MAIL FROM, RCPT TO etc. Responses are sent from
the server to the client. It is a three-digit code that may be followed by additional textual information.
The process of transferring a mail message occurs in three phases: connection establishmnet, mail
transfer, and connection termination.
Although the transport protocol specified for SMTP is TCP, in this experiment, UDP protocol will be
used.
Algorithm:
SMTP Client
2. Send the message “SMTP REQUEST FROM CLIENT” to the server. This is done so that the
server understands the address of the client.
3. Read the first message from the server using client socket and print it.
4. The first command HELO<”Client's mail server address”> is sent by the client
5. Read the second message from the server and print it.
6. The second command MAIL FROM:<”email address of the sender”> is sent by the client.
7. Read the third message from the server and print it.
8. The third command RCPT TO:<”email address of the receiver”> is sent by the client
9. Read the fourth message from the server and print it.
11. Read the fifth message from the server and print it.
12. Write the messages to the server and end with “.”
13. Read the sixth message from the server and print it.
15. Read the seventh message from the server and print it.
Server
2. Read the message from the client and gets the client's address
4. Read the first message from the client and print it.
12. Read the email text from the client till a “.” is reached
14. Read the fifth message from the client and print it.
Program
Client
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
int n;
int sock_fd;
int i=0;
char buf[MAXLINE+1];
char address_buf[MAXLINE],message_buf[MAXLINE];
if(argc!=3)
exit(1);
exit(1);
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(atoi(argv[2]));
inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
n=sendto(sock_fd,buf,strlen(buf),0,(struct sockaddr*)&servaddr,sizeof(servaddr));
if(n<0)
perror("ERROR");
exit(1);
if((n=recvfrom(sock_fd,buf,MAXLINE,0,NULL,NULL))==-1)
exit(1);
buf[n]='\0';
printf("S:%s",buf);
sprintf(buf,"HELLO name_of_client_mail_server\n");
n=sendto(sock_fd,buf,strlen(buf),0,(struct sockaddr*)&servaddr,sizeof(servaddr));
if((n=recvfrom(sock_fd,buf,MAXLINE,0,NULL,NULL))==-1)
exit(1);
buf[n]='\0';
printf("S:%s",buf);
sender:");
fgets(address_buf,sizeof(address_buf),stdin);
address_buf[strlen(address_buf)-1]='\0';
sendto(sock_fd,buf,sizeof(buf),0,(struct sockaddr*)&servaddr,sizeof(servaddr));
if((n=recvfrom(sock_fd,buf,MAXLINE,0,NULL,NULL))==-1)
exit(1);
buf[n]='\0';
printf("S:%s",buf);
fgets(address_buf,sizeof(address_buf),stdin);
address_buf[strlen(address_buf)-1]='\0';
sprintf(buf,"RCPT TO : <%s>\n",address_buf);
&servaddr,sizeof(servaddr));
if((n=recvfrom(sock_fd,buf,MAXLINE,0,NULL,NULL))==-1)
exit(1);
buf[n]='\0';
printf("S:%s",buf);
sprintf(buf,"DATA\n");
sendto(sock_fd,buf,strlen(buf),0,(struct sockaddr*)&servaddr,sizeof(servaddr));
if((n=recvfrom(sock_fd,buf,MAXLINE,0,NULL,NULL))==-1)
exit(1);
buf[n]='\0';
printf("S:%s",buf);
do
fgets(message_buf,sizeof(message_buf),stdin);
sprintf(buf,"%s",message_buf);
sendto(sock_fd,buf,strlen(buf),0,(struct
sockaddr*)&servaddr,sizeof(servaddr)); message_buf[strlen(message_buf)-
1]='\0';
str=message_buf;
while(isspace(*str+
+)); if(strcmp(--
str,".")==0) break;
} while(1);
if((n=recvfrom(sock_fd,buf,MAXLINE,0,NULL,NULL))==-1)
exit(1);
buf[n]='\0';
sprintf(buf,"QUIT\n");
printf("S:%s",buf);
sendto(sock_fd,buf,strlen(buf),0,(struct
sockaddr*)&servaddr,sizeof(servaddr));
if((n=recvfrom(sock_fd,buf,MAXLINE,0,NULL,NULL))==-1)
exit(1);
buf[n]='\0';
printf("S:%s",buf);
Server
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
{
int n,sock_fd;
char mesg[MAXLINE+1];
socklen_t len;
len=sizeof(cliaddr);
if((sock_fd=socket(AF_INET,SOCK_DGRAM,0))<0)
exit(1);
bzero((char*)&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(atoi(argv[1]));
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sock_fd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
perror("bind failed:");
exit(1);
if((n=recvfrom(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,&len))==-1)
exit(1);
mesg[n]='\0';
printf("mesg:%s\n",mesg);
sprintf(mesg,"220 name_of_server_mail_server\n");
sendto(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
n=recvfrom(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,&len);
mesg[n]='\0';
printf("C:%s\n",mesg);
str_ptr=strdup(mesg);
buf_ptr=strsep(&str_ptr," ");
free(buf_ptr);
n=recvfrom(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,&len);
mesg[n]='\0';
printf("C:%s",mesg);
str_ptr=strdup(mesg);
buf_ptr=strsep(&str_ptr,":");
str_ptr[strlen(str_ptr)-1]='\
0';
free(buf_ptr);
sendto(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
n=recvfrom(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,&len);
mesg[n]='\0';
printf("C:%s",mesg);
str_ptr=strdup(mesg);
buf_ptr=strsep(&str_ptr,":");
str_ptr[strlen(str_ptr)-1]='\
0';
free(buf_ptr);
sendto(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
n=recvfrom(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,&len);
mesg[n]='\0';
printf("C:%s\n",mesg);
sendto(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
while(1)
n=recvfrom(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,&len);
mesg[n]='\0';
printf("C:%s\n",mesg);
mesg[strlen(mesg)-1]='\0';
str=mesg;
while(isspace(*str+
+)); if(strcmp(--
str,".")==0) break;
sendto(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
n=recvfrom(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,&len);
mesg[n]='\0';
printf("C:%s\n",mesg);
sendto(sock_fd,mesg,MAXLINE,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
Server program
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
int n, sock_fd;
struct sockaddr_in servaddr, cliaddr;
bzero((char*)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[1]));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
mesg[n] = '\0';
printf(“mesg:%s\n”, mesg);
str_ptr = strdup(mesg);
buf_ptr = strsep(&str_ptr, “ “);
sprintf(mesg, “250 Hello %s”, str_ptr);
free(buf_ptr);
sendto(sock_fd, mesg, MAXLINE,0, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
str_ptr = strdup(mesg);
buf_ptr = strsep(&str_ptr,
“:“); str_ptr[strlen(str_ptr)-1]
= '\0';
sprintf(mesg, “250 Hello %s..........Sender ok\n”, str_ptr);
free(buf_ptr);
sendto(sock_fd, mesg, MAXLINE,0, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
while(1)
{
n = recvfrom(sock_fd, mesg, MAXLINE, 0, (struct sockaddr *)&cliaddr, &len);
mesg[n] = '\0';
printf(“C:%s\n”,mesg);
mesg[strlen(mesg) – 1] = '\0';
str = mesg;
while(isspace(*str++));
if(strcmp(--str, “.”) == 0)
break;
Output
Client
Server
Experiment 14
Aim: To develop a concurrent file server which will provide the file requested by client if it exists. If
not, server sends appropriate message to the client. Server sends its process ID (PID) to clients for
display along with file or the message.
Description:
The file server creates listening sockets on two ports that have consecutive port numbers. One is the
listening socket for control connection and the other is the listening socket for data connection. These
sockets have descriptors listen_control and listen_data respectively. The client creates a socket and
connects to the server using TCP connection. The client socket descriptor is stored in sock_ctrl. The
server creates a connection socket when the client makes a TCP connection with the server. This
connection socket is stored in sock_ctrl. This connection is for control information to pass between
client and server. Next, the server forks a child process. Since the child is a perfect image of its parent,
the child process will also have descriptors listen_control, listen_data and sock_ctrl. The control
connection will also be duplicated between the client and the child process. The child process closes its
listening socket for control connection, i.e; listen_control. The parent server process closes its
connection socket for the control connection i.e; sock_ctrl. The client now makes a TCP connection
with the server for transferring data is stored in sock_data. The connection socket for the data
connection is stored in sock_data in the server child process.
Algorithm
Client
1. Create the client TCP control connection to a port (port_num) of the server with the client
socket descriptor sock_ctrl.
2. `while(1)
2.1 Create client socket descriptor sock_data for the data connection with server on another
port (portnum + 1). For each file transfer a new data connection is required.
2.2 Read the command from the terminal given by the user
2.3 Send the command to the server using control socket sock_ctrl.
2.6 Write the filename using control socket sock_ctrl to the server.
2.8 read data using sock_data (file contents) from the server and write to the file
Server
2. Create listening socket for the control connection on port (port_num) and store it in
listen_control.
3. Create a listening socket for the data connection on port (port_num +1) and store it in listen_data
4. while (1)
4.1 accepts the client control connection and returns the connect socket descriptor
sock_ctrl
4.2.1 if(childprocess)
while(1)
if command == “close”
break
else
if (no file)
file_present = 0;
accept the data connection and return the socket descriptor sock_data
if(file_present)
else
file_present = 1;
close sock_data
close(sock_ctrl)
close(listen_data)
close( sock_ctrl)
5. close(listen_control);
6. close(listen_data);
Program
Client
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
int n, fd, i;
char name[100];
char * p;
if(argc != 3)
exit(1);
exit(1);
bzero((char*)&servaddr, sizeof(servaddr));
bzero(line, sizeof(line));
bzero(buffer, sizeof(buffer));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
exit(1);
while (1)
{
i=0;
if(( sock_data = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Enter command:");
scanf("%s", cmd);
if(strcmp(cmd, "close") == 0)
close(sock_data);
close(sock_ctrl);
break;
printf("Enter filename:");
scanf("%s", name);
exit(1);
while(n == -1)
perror("cannot connect");
do
i += n;
} while(n>0);
if(buffer[0] =='@')
p = buffer;
printf("%s\n", p++);
remove(name);
Server
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdlib.h>
if(argc != 2)
exit(1);
exit(1);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(argv[1]));
exit(1);
listen(listen_control, 5);
exit(1);
exit(1);
listen(listen_control, 5);
listen(listen_data, 5);
for(; ;)
perror("accept failed");
exit(1);
if(fork() == 0)
close(listen_control);
while(1)
i=0;
if(strcmp(cmd, "close") == 0)
break;
else
file_present = 0;
perror("accept failed");
exit(1);
if(file_present == 1)
do
i = i+n;
} while(n>0);
close(fd);
else
file_present =1;
bzero(buffer, sizeof(buffer));
close(sock_data);
close(sock_ctrl);
close(listen_data);
exit(0);
close(sock_ctrl);
close(listen_control);
close(listen_data);
Output
The files stored in the server are a1, b1, and c1. Client 1 connects to the server and gets files a1 and b1.
Client 2 connects to server and receives c1. The server process id is stored in the files received.
Client 1
Client 2
Server
Experiment 15
Aim: To observe data transferred using UDP in client server communication and to study UDP
datagram.
Description:
Wireshark is a free network protocol analyzer that runs on Windows, Mac, and Linux/Unix computer.
It operates in computers using Ethernet, serial (PPP and SLIP), 802.11 wireless LANs, and many other
link-layer technologies. It is also a packet sniffer since it can be used to observe messages exchanged
between protocol entities. It will also typically store and/or display the contents of the various protocol
fields in these captured messages. A packet sniffer receives a copy of packets that are sent/received
from/by application and protocols executing on your machine. Packet sniffer software consists of two
components. One is packet capture library that receives a copy of every link-layer frame that is sent
from or received by your computer. The second component of a packet sniffer is the packet analyzer,
which displays the contents of all fields within a protocol message. Wireshark has a rich functionality
that includes the capability to analyze hundreds of protocols, and a well-designed user interface.
Wireshark is installed in the computer. The wireshark interface has 5 major components.
1. Command menus
The two noteworthy menus are File menu that allows you to save captured packet data and exit the
Wireshark application. The Capture menu allows you to begin packet capture and stop capturing when
needed.
4. Packet-contents window
Displays the entire contents of the captured frame in both ASCII and hexadecimal format.
Output
UDP datagrams
Packet capturing is started. Skype application is also started. This generates UDP datagrams.
From the trace, the details of frame 47 can be seen. It is an UDP datagram as specified by column 5.
UDP header has the following fields
UDP header has a length of 8bytes. The payload of the UDP datagram is therefore 705 bytes whose
hexadecimal values are given in the trace.
Output
Experiment 16
Aim: To observe 3 way handshake during TCP connection establishment using Wireshark
Description:
Output:
IP address of the client computer is 192.168.43.15 and the source port is 53001. The destination has
IP address 128.119.245.12 with port number 80.
Connection Establishment
The TCP SYN segment is used to initiate the TCP connection between the client computer and server.
Frame 24 in the trace shows the transfer of SYN segment from the source to destination computer. It
has sequence number 0. The SYN flag is set to 1 and it indicates that this segment is a SYN segment.
The sequence number of the SYN/ACK segment from server to the client computer in reply to the
SYN has the value of 0 in the trace and is given by frame 27. The value of the acknowledgement field
in the SYN/ACK segment is 1. The value of the acknowledgement field in the SYN/ACK segment is
determined by the server by adding 1 to the initial sequence number of SYN segment
from the client computer. The SYN flag and Acknowledgement flag in the segment are set to 1 and
they indicate that this segment is a SYNACK segment. Finally an acknowledgement is sent by the
client computer to the server with ack number 1 and sequence number 1 as shown in frame 28. This
completes TCP connection establishment.
Data Transfer
Let us look at packet numbers 42 and 43. They are TCP segments carrying data from the source to
destination. The sequence number of former segment = 7510, while that of the latter = 8880. The
difference between the two sequence numbers = 8880 – 7510 = 1370 bytes is the length of the TCP
segment.
Connection Termination
Packet 204 is the TCP segment with FIN and ACK fields set from the destination to source. The
source then sends an ACK given by packet 2015
Output
Experiment 17
Aim: To develop a packet capturing and filtering application using raw sockets
Description:
Normally, an application accesses the network layer using the transport layer. However, if a raw socket
is used an application can bypass the transport layer and access the network layer directly.
The raw socket is created using the socket function
int sockfd;
sockfd = socket(AF_INET, SOCK_RAW, protocol);
where protocol is one of the the constants IPPROTO_xxx defined in <netinet/in.h> header. The socket
created above is an IPv4 raw socket. Only the superuser can create a raw socket. There is no concept
of a port number in a raw socket. It is possible to read and write any type of datalink frame also, if, in
the above socket creation function, the first parameter is AF_PACKET and the third parameter has
value htons (ETH_P_ALL).
The program described here receives frames from an application that sends UDP datagrams. Using the
raw socket, we read the frame using the raw socket and filter out the UDP datagrams based on the
protocol field in the IP header. The data link frames are read in by the raw socket using recvfrom.
Program
filter_new.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<linux/if_packet.h>
#include<netinet/in.h>
#include<netinet/if_ether.h>
#include<netinet/ip.h>
#include<netinet/udp.h>
#include<netinet/tcp.h>
#include<arpa/inet.h>
#include<arpa/inet.h>
int main()
{
len = sizeof(servaddr);
if(sock_r_fd < 0)
{
perror("Error in socket creation");
exit(1);
}
while(1)
{
print_headers(buffer, n);
}
}
ethhdr)); if(ip->protocol == 6)
{
++tcp;
}
else if(ip->protocol == 17)
{
++udp;
udp_header(_buffer, _n);
}
else
{
other_headers++;
}
int i=0;
int remaining_data, iphdrlen;
struct sockaddr_in src, dest;
unsigned char * data;
struct iphdr *ip;
struct udphdr *udp;
}
Output
Experiment 18
Aim: To design and configure a network with multiple subnets with wired and wireless LANs using
required network devices. Configure the following services in the network- TELNET, SSH, FTP
server, Webserver, File server, DHCP server and DNS server.*
Description:
Design
The above topology shows 3 subnets .The network is designed with server, hosts, switch and Routers.
Configuration
Hosts are configured with IP addresses 192.168.2.2, 192.168.2.3, 192.168.2.4 and the server with
192.168.2.100 . These hosts are connected to the fast Ethernet port of the router through the switch
Server is configured with DHCP, DNS etc. Subnet 2 contains one host with IP address 192.168.3.2
Subnet 3 contains one host with IP address 192.168.4.2. Routers R1, R2, R3 are connected
through serial cable (R1,R2,R3)
We need to configure static routing in the routers to enable communication of hosts in different
subnets
Router 1
Router 2
Router 3
Output
Files and services can be accessed across subnets.
Experiment 19
Aim: To Install network simulator NS-2 in any of the Linux operating system and simulate wired and
wireless scenarios.
Description
A simulation can be thought of as a flow process of network entities (e.g., nodes, packets). As these
entities move through the system, they interact with other entities, join certain activities, trigger events,
cause some changes to the state of the system, and leave the process. From time to time, they contend
or wait for some type of resources. This implies that there must be a logical execution sequence to
cause all these actions to happen in a comprehensible and manageable way.
Network Simulator (Version 2), widely known as NS2, is simply an event driven simulation tool that
has proved useful in studying the dynamic nature of communication networks. Simulation of wired as
well as wireless network functions and protocols (e.g., routing algorithms, TCP, UDP) can be done
using NS2. In general, NS2 provides users with a way of specifying such network protocols and
simulating their corresponding behaviors.
Basic Architecture
NS2 provides users with an executable command ns which takes on input argument, the name of a Tcl
simulation scripting file. In most cases, a simulation trace file is created, and is used to plot graph
and/or to create animation. NS2 consists of two key languages: C++ and Object-oriented Tool
Command Language (OTcl). While the C++ defines the internal mechanism (i.e., a backend) of the
simulation objects, the OTcl sets up simulation by assembling and configuring the objects as well as
scheduling discrete events (i.e., a frontend).
4) Now change your directory(here i have already extracted the downloaded files to desktop,so my
location is desktop) type the following codes in the command window to install NS2.
cd Desktop
cd ns-allinone-2.35
./install
5) After compleating the installation type the following command in the command window
gedit ~/.bashrc
6) Now an editor window appears,please copy and paste the follwing codes in the end of the text file
(note that '/home/abhiram/Desktop/ns-allinone-2.35/octl-1.14' in each line in the below code should be
replaced with your location where the 'ns-allinone-2.35.tar.gz'file is extracted)
# LD_LIBRARY_PATH
OTCL_LIB=/home/abhiram/Desktop/ns-allinone-2.35/otcl-1.14
NS2_LIB=/home/abhiram/Desktop/ns-allinone-2.35/lib
X11_LIB=/usr/X11R6/lib
USR_LOCAL_LIB=/usr/local/lib
export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OTCL_LIB:$NS2_LIB:$X11_LIB:$USR_LOCAL
_LIB
# TCL_LIBRARY
TCL_LIB=/home/abhiram/Desktop/ns-allinone-2.35/tcl8.5.10/library
USR_LIB=/usr/lib
export TCL_LIBRARY=$TCL_LIB:$USR_LIB
# PATH
XGRAPH=/home/abhiram/Desktop/ns-allinone-2.35/bin:/home/abhiram/Desktop/ns-allinone-
2.35/tcl8.5.10/unix:/home/abhiram/Desktop/ns-allinone-2.35/tk8.5.10/unix
NS=/home/abhiram/Desktop/ns-allinone-2.35/ns-2.35/
NAM=/home/abhiram/Desktop/ns-allinone-2.35/nam-1.15/
PATH=$PATH:$XGRAPH:$NS:$NAM
7) Save and close the text editor and then type the following command on the terminal
source ~/.bashrc
8) Close the terminal window and start a new terminal window and now change the directory to ns-
2.35 and validate ns-2.35 by exicuting the following command ( it takes 30 to 45 minutes)
cd ns-2.35
./validate
9) If the installation is successful, then you will be able to see % at the command prompt while
typing the following command
ns
exit
Ns2 Commands
[simulator-instance] node
Shape of node can be changed using shape procedure of node class. Shapes in ns2 available are
box, hexagon and circle. Default shape is circle. Once a shape is defined then it can't be
changed after simulation starts.
Syntax:
Syntax:
[node-instance] reset
Fetch id of Node
[node-instance] id
Sytanx:
Every node maintains list of neighbors which are connected to that node.
Syntax:
[node-instance] neighbor
Link Commands
In ns2, nodes can be connected in two ways, simplex and duplex. Simplex connection allows one-
way communication and duplex connection allows two-way communication. Each type requires
bandwidth, delay and type of queue for configuration.
Bandwidth is specified in Mbps(Mb) and delay is specified in milli seconds (ms).
Type of Queue available in ns2: DropTail, RED, CBQ, FQ, SFQ, DRR.
Syntax:
$ns simplex-link/duplex-link [node-instance1] [node-instance2] bandwidth delay Q-Type
Agent Class
For every node transport mechanism need to be defined to send data. These transport
mechanism in ns2 defined using agent. For example FTP application requires TCP transport
protocol, that's why TCP agent need to be associated with sending node. All agents are
subclass of Agent class
In ns2 simulation result stored in trace files. These file formats need to be understood for
analysing result. Here we will discuss general trace file and nam trace file.
Carrier Sense Multiple Access (CSMA) is a network protocol that listens to or senses network
signals on the carrier/medium before transmitting any data.
CSMA is implemented in Ethernet networks with more than one computer or network
device attached to it.
Simulation of CSMA
AODV
An Ad Hoc On-Demand Distance Vector (AODV) is a routing protocol designed for wireless and
mobile ad hoc networks. This protocol establishes routes to destinations on demand and supports both
unicast and multicast routing.The AODV protocol builds routes between nodes only if they are
requested by source nodes. AODV is therefore considered an on-demand algorithm and does not create
any extra traffic for communication along links. The routes are maintained as long as they are required
by the sources.
In AODV, networks are silent until connections are established. Network nodes that need connections
broadcast a request for connection. The remaining AODV nodes forward the message and record the
node that requested a connection. Thus, they create a series of temporary routes back to the requesting
node.
A node that receives such messages and holds a route to a desired node sends a backward message
through temporary routes to the requesting node. The node that initiated the request uses the route
containing the least number of hops through other nodes. The entries that are not used in routing tables
are recycled after some time. If a link fails, the routing error is passed back to the transmitting node
and the process is repeated.
Simulation of AODV
# Define options
set val(chan) Channel/WirelessChannel ;# channel type
set val(prop) Propagation/TwoRayGround ;# radio-propagation model
set val(netif) Phy/WirelessPhy ;# network interface type
set val(mac) Mac/802_11 ;# MAC type
set val(ifq) Queue/DropTail ;# interface queue type
set val(ll) LL ;# link layer type
set val(ant) Antenna/OmniAntenna ;# antenna model
set val(ifqlen) 50 ;# max packet in ifq
set val(nn) 3 ;# number of mobilenodes
set val(rp) AODV ;# routing protocol
set val(x) 500 ;# X dimension of topography
set val(y) 400 ;# Y dimension of topography
set val(stop) 150 ;# time of simulation end
create-god $val(nn)
#
# Create nn mobilenodes [$val(nn)] and attach them to the channel.
#
# Generation of movements
$ns at 10.0 "$node_(0) setdest 250.0 250.0 3.0"
$ns at 15.0 "$node_(1) setdest 45.0 285.0 5.0"
$ns at 110.0 "$node_(0) setdest 480.0 300.0 5.0"
$ns run
Output