Network Lab PG Ms
Network Lab PG Ms
Experiment No 1
CRC
Problem Statement
Write a program for error detecting code using CRC-CCITT (16-bits).
Theory
It does error checking via polynomial division. In general, a bit string
bn-1bn-2bn-3b2b1b0
As
bn-1Xn-1 + bn-2 Xn-2 + bn-3 Xn-3 + b2 X2 + b1 X1 + b0
Ex: 10010101110
As
X10 + X7 + X5 + X3 + X2 + X1
All computations are done in modulo 2
Algorithm:1. Given a bit string, append 0S to the end of it (the number of 0s is the same as the degree of
the generator polynomial) let B(x) be the polynomial corresponding to B.
2. Divide B(x) by some agreed on polynomial G(x) (generator polynomial) and determine
the remainder R(x). This division is to be done using Modulo 2 Division.
3. Define T(x) = B(x) R(x)
(T(x)/G(x) => remainder 0)
4. Transmit T, the bit string corresponding to T(x).
5. Let T represent the bit stream the receiver gets and T(x) the associated polynomial. The
receiver divides T1(x) by G(x). If there is a 0 remainder, the receiver concludes T = T and
no error occurred otherwise, the receiver concludes an error occurred and requires a
retransmission.
Program
#include<stdio.h>
#include<string.h>
#include<conio.h>
#define N strlen(g)
char t[128], cs[128], g[]="10001000000100001";
int a, e, c;
void xor() {
for(c=1;c<N;c++) cs[c]=((cs[c]==g[c])?'0':'1');
}
void crc() {
for(e=0;e<N;e++) cs[e]=t[e];
do {
if(cs[0]=='1') xor();
for(c=0;c<N-1;c++) cs[c]=cs[c+1];
cs[c]=t[e++];
}while(e<=a+N-1);
}
void main() {
clrscr();
printf("\nEnter poly : "); scanf("%s",t);
printf("\nGenerating Polynomial is : %s",g);
a=strlen(t);
for(e=a;e<a+N-1;e++) t[e]='0';
printf("\nModified t[u] is : %s",t);
crc();
printf("\nChecksum is : %s",cs);
for(e=a;e<a+N-1;e++) t[e]=cs[e-a];
printf("\nFinal Codeword is : %s",t);
printf("\nTest Error detection 0(yes) 1(no) ? : ");
scanf("%d",&e);
if(e==0) {
printf("Enter position where error is to inserted : ");
scanf("%d",&e);
t[e]=(t[e]=='0')?'1':'0';
printf("Errorneous data
: %s\n",t);
}
crc();
for (e=0;(e<N-1)&&(cs[e]!='1');e++);
if(e<N-1) printf("Error detected.");
else printf("No Error Detected.");
getch();
}
Output
Enter poly : 1011101
Generating Polynomial is : 10001000000100001
Modified t[u] is : 10111010000000000000000
Checksum is : 1000101101011000
Final Codeword is : 10111011000101101011000
Test Error detection 0(yes) 1(no) ? : 0
Enter position where you want to insert error : 3
Errorneous data
: 10101011000101101011000
Error detected.
Enter poly : 1011101
Generating Polynomial is : 10001000000100001
Modified t[u] is : 10111010000000000000000
Checksum is : 1000101101011000
Final Codeword is : 10111011000101101011000
Test Error detection 0(yes) 1(no) ? : 1
No Error Detected.
Experiment No 2
Frame Sorting
Problem Statement
Write a program for frame sorting technique used in buffers.
Theory
The data link layer divides the stream of bits received from the network layer into manageable
data units called frames.
If frames are to be distributed to different systems on the network, the Data link layer adds a
header to the frame to define the sender and/or receiver of the frame.
Each Data link layer has its own frame format. One of the fields defined in the format is the
maximum size of the data field. In other words, when datagram is encapsulated in a frame, the
total size of the datagram must be less than this maximum size, which is defined by restriction
imposed by the hardware and software used in the network.
IP Datagram
Header
MTU
Trailer
Program
#include
#include
#include
#include
#include
<stdlib.h>
<time.h>
<stdio.h>
<conio.h>
<string.h>
#define FSize 3
typedef struct packet{int SeqNum; char Data[FSize+1];}packet;
struct packet *readdata, *transdata;
int divide(char *msg) {
int msglen, NoOfPacket, i, j;
msglen = strlen(msg);
NoOfPacket = msglen/FSize;
if ((msglen%FSize)!=0) NoOfPacket++;
Output
Enter The messgae to be Transmitted :
hi, it was nice meeting u on sunday
The Message has been divided as follows
Packet No.
Data
1
2
3
4
5
6
7
8
9
10
11
12
hi,
it
wa
s n
ice
me
eti
ng
u o
n s
und
ay
12
10
11
12
Message received is :
hi, it was nice meeting u on sunday
10
Experiment No 3
Distance Vector Routing
Problem Statement
Write a program for distance vector algorithm to find suitable path for transmission.
Theory
Routing algorithm is a part of network layer software which is responsible for deciding which
output line an incoming packet should be transmitted on. If the subnet uses datagram internally,
this decision must be made anew for every arriving data packet since the best route may have
changed since last time. If the subnet uses virtual circuits internally, routing decisions are made
only when a new established route is being set up. The latter case is sometimes called session
routing, because a rout remains in force for an entire user session (e.g., login session at a terminal
or a file).
Routing algorithms can be grouped into two major classes: adaptive and nonadaptive.
Nonadaptive algorithms do not base their routing decisions on measurement or estimates of
current traffic and topology. Instead, the choice of route to use to get from I to J (for all I and J) is
compute in advance, offline, and downloaded to the routers when the network ids booted. This
procedure is sometime called static routing.
Adaptive algorithms, in contrast, change their routing decisions to reflect changes in the
topology, and usually the traffic as well. Adaptive algorithms differ in where they get information
(e.g., locally, from adjacent routers, or from all routers), when they change the routes (e.g., every
T sec, when the load changes, or when the topology changes), and what metric is used for
optimization (e.g., distance, number of hops, or estimated transit time).
Two algorithms in particular, distance vector routing and link state routing are the most
popular. Distance vector routing algorithms operate by having each router maintain a table (i.e.,
vector) giving the best known distance to each destination and which line to get there. These
tables are updated by exchanging information with the neighbors.
The distance vector routing algorithm is sometimes called by other names, including the
distributed Bellman-Ford routing algorithm and the Ford-Fulkerson algorithm, after the
researchers who developed it (Bellman, 1957; and Ford and Fulkerson, 1962). It was the original
ARPANET routing algorithm and was also used in the Internet under the RIP and in early
versions of DECnet and Novells IPX. AppleTalk and Cisco routers use improved distance vector
protocols.
In distance vector routing, each router maintains a routing table indexed by, and containing
one entry for, each router in subnet. This entry contains two parts: the preferred out going line to
use for that destination, and an estimate of the time or distance to that destination. The metric
used might be number of hops, time delay in milliseconds, total number of packets queued along
the path, or something similar.
The router is assumed to know the distance to each of its neighbor. If the metric is hops, the
distance is just one hop. If the metric is queue length, the router simply examines each queue. If
the metric is delay, the router can measure it directly with special ECHO packets hat the receiver
just time stamps and sends back as fast as possible.
A
B
C
D
E
_____ _____ _____ _____
1
1
1
1
2
2
2
3
3
A
B
C
D
E
_____ _____ _____ _____
Initially
After 1 exchange
After 2 exchange
After 3 exchange
After 4 exchange
1
3
3
5
5
7
7
2
2
3
3
6
6
8
:
3
3
3
5
5
7
7
4
4
4
4
6
6
8
Initially
After 1 exchange
After 2 exchange
After 3 exchange
After 4 exchange
After 5 exchange
After 6 exchange
Many ad hoc solutions to the count to infinity problem have been proposed in the literature,
each one more complicated and less useful than the one before it. The split horizon algorithm
works the same way as distance vector routing, except that the distance to X is not reported on
line that packets for X are sent on (actually, it is reported as infinity). In the initial state of right
figure, for example, C tells D the truth about distance to A but C tells B that its distance to A is
infinite. Similarly, D tells the truth to E but lies to C.
Experiment No 4
TCP Socket
Problem Statement
Using TCP/IP sockets, write a client-server program to make client sending the file name and the
Start.
Create a socket using socket() system call.
Connect the socket to the address of the server using connect() system call.
Send the filename of required file using send() system call.
Read the contents of the file sent by server by recv() system call.
Stop.
Start.
Create a socket using socket() system call.
Bind the socket to an address using bind() system call.
Listen to the connection using listen() system call.
accept connection using accept()
Receive filename and transfer contents of file with client.
Stop.
Program4
//client
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
int main(int argc,char *argv[])
{
int create_socket,cont;
int bufsize = 1024;
char *buffer = malloc(bufsize);
char fname[256];
struct sockaddr_in address;
if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
printf("The Socket was created\n");
address.sin_family = AF_INET;
address.sin_port = htons(15000);
inet_pton(AF_INET,argv[1],&address.sin_addr);
Experiment No 5
FIFO IPC
Problem Statement
Implement the above program using as message queues or FIFO as IPC channels.
Start.
Open well known server FIFO in write mode.
Write the pathname of the file in this FIFO and send the request.
Open the client specified FIFO in read mode and wait for reply.
When the contents of the file are available in FIFO, display it on the terminal
Stop.
Start.
Create a well known FIFO using mkfifo()
Open FIFO in read only mode to accept request from clients.
When client opens the other end of FIFO in write only mode, then read the contents and
store it in buffer.
5. Create another FIFO in write mode to send replies.
6. Open the requested file by the client and write the contents into the client specified FIFO
and terminate the connection.
7. Stop.
Program 5
/*Server*/
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#define FIFO1 "fifo1"
#define FIFO2 "fifo2"
#define PERMS 0666
char fname[256];
int main() {
int readfd, writefd, fd;
ssize_t n;
char buff[512];
if (mkfifo(FIFO1, PERMS)<0)
printf("Cant Create FIFO Files\n");
if (mkfifo(FIFO2, PERMS)<0)
printf("Cant Create FIFO Files\n");
printf("Waiting for connection Request..\n");
readfd =open(FIFO1, O_RDONLY, 0);
writefd=open(FIFO2, O_WRONLY, 0);
printf("Connection Established..\n");
read(readfd, fname, 255);
printf("Client has requested file %s\n", fname);
if ((fd=open(fname,O_RDWR))<0) {
strcpy(buff,"File does not exist..\n");
write(writefd, buff, strlen(buff));
} else {
while((n=read(fd, buff,512))>0)
write(writefd, buff, n);
}
close(readfd); unlink(FIFO1);
close(writefd); unlink(FIFO2);
/*Client*/
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#define FIFO1 "fifo1"
#define FIFO2 "fifo2"
#define PERMS 0666
char fname[256];
int main()
{
ssize_t n;
char buff[512];
int readfd,writefd;
printf("Trying to Connect to Server..\n");
writefd = open(FIFO1, O_WRONLY, 0);
readfd = open(FIFO2, O_RDONLY, 0);
printf("Connected..\n");
printf("Enter the filename to request from server: ");
scanf("%s",fname);
write(writefd, fname, strlen(fname));
printf("Waiting for Server to reply..\n");
while((n=read(readfd,buff,512))>0)
write(1,buff,n);
close(readfd);
close(writefd);
return 0;
}
Output (Server)
[root@localhost CN Lab] ./s.o
Waiting for connection Request..
Connection Established..
Client has requested file farha
[root@localhost CN Lab]
Output (Client)
[root@localhost CN Lab] ./c.o
Trying to Connect to Server..
Connected..
Experiment No 6
RSA Algorithm
Problem Statement
Write a program for simple RSA algorithm to encrypt and decrypt the data.
Theory
Cryptography has a long and colorful history. The message to be encrypted, known as the
plaintext, are transformed by a function that is parameterized by a key. The output of the
encryption process, known as the ciphertext, is then transmitted, often by messenger or radio. The
enemy, or intruder, hears and accurately copies down the complete ciphertext. However, unlike
the intended recipient, he does not know the decryption key and so cannot decrypt the ciphertext
easily. The art of breaking ciphers is called cryptanalysis the art of devising ciphers
(cryptography) and breaking them (cryptanalysis) is collectively known as cryptology.
There are several ways of classifying cryptographic algorithms. They are generally
categorized based on the number of keys that are employed for encryption and decryption, and
further defined by their application and use. The three types of algorithms are as follows:
1 Secret Key Cryptography (SKC): Uses a single key for both encryption and decryption. It is
also known as symmetric cryptography.
2 Public Key Cryptography (PKC): Uses one key for encryption and another for decryption. It
is also known as asymmetric cryptography.
3 Hash Functions: Uses a mathematical transformation to irreversibly "encrypt" information
Public-key cryptography has been said to be the most significant new development in
cryptography. Modern PKC was first described publicly by Stanford University professor Martin
Hellman and graduate student Whitfield Diffie in 1976. Their paper described a two-key crypto
system in which two parties could engage in a secure communication over a non-secure
communications channel without having to share a secret key.
Generic PKC employs two keys that are mathematically related although knowledge of one
key does not allow someone to easily determine the other key. One key is used to encrypt the
plaintext and the other key is used to decrypt the ciphertext. The important point here is that it
does not matter which key is applied first, but that both keys are required for the process to work.
Because pair of keys is required, this approach is also called asymmetric cryptography.
In PKC, one of the keys is designated the public key and may be advertised as widely as the
owner wants. The other key is designated the private key and is never revealed to another party. It
is straight forward to send messages under this scheme.
The RSA algorithm is named after Ron Rivest, Adi Shamir and Len Adleman, who invented it
in 1977. The RSA algorithm can be used for both public key encryption and digital signatures. Its
security is based on the difficulty of factoring large integers.
Algorithm
1
2
3
4
5
6
Program 6
#include
#include
#include
#include
<stdio.h>
<string.h>
<conio.h>
<math.h>
Output
Enter message : farha
CT = 38 113 229 213 113
PT = farha
Experiment No 8
Leaky Bucket
Problem Statement
Write a program for congestion control using Leaky bucket algorithm.
Theory
The congesting control algorithms are basically divided into two groups: open loop and closed
loop. Open loop solutions attempt to solve the problem by good design, in essence, to make sure
it does not occur in the first place. Once the system is up and running, midcourse corrections are
not made. Open loop algorithms are further divided into ones that act at source versus ones that
act at the destination.
In contrast, closed loop solutions are based on the concept of a feedback loop if there is any
congestion. Closed loop algorithms are also divided into two sub categories: explicit feedback
and implicit feedback. In explicit feedback algorithms, packets are sent back from the point of
congestion to warn the source. In implicit algorithm, the source deduces the existence of
congestion by making local observation, such as the time needed for acknowledgment to come
back.
The presence of congestion means that the load is (temporarily) greater than the resources (in
part of the system) can handle. For subnets that use virtual circuits internally, these methods can
be used at the network layer.
Another open loop method to help manage congestion is forcing the packet to be transmitted
at a more predictable rate. This approach to congestion management is widely used in ATM
networks and is called traffic shaping.
The other method is the leaky bucket algorithm. Each host is connected to the network by an
interface containing a leaky bucket, that is, a finite internal queue. If a packet arrives at the queue
when it is full, the packet is discarded. In other words, if one or more process are already queued,
the new packet is unceremoniously discarded. This arrangement can be built into the hardware
interface or simulate d by the host operating system. In fact it is nothing other than a single server
queuing system with constant service time.
The host is allowed to put one packet per clock tick onto the network. This mechanism turns
an uneven flow of packet from the user process inside the host into an even flow of packet onto
the network, smoothing out bursts and greatly reducing the chances of congestion.
Program 8
#include<iostream.h>
#include<dos.h>
#include<stdlib.h>
#define bucketSize 512
void bktInput(int a,int b) {
if(a>bucketSize)
cout<<"\n\t\tBucket overflow";
else {
delay(500);
while(a>b){
cout<<"\n\t\t"<<b<<" bytes outputted.";
a-=b;
delay(500);
}
if (a>0) cout<<"\n\t\tLast "<<a<<" bytes sent\t";
cout<<"\n\t\tBucket output successful";
}
}
void main() {
int op, pktSize;
randomize();
cout<<"Enter output rate : "; cin>>op;
for(int i=1;i<=5;i++){
delay(random(1000));
pktSize=random(1000);
cout<<"\nPacket no "<<i<<"\tPacket size = "<<pktSize;
bktInput(pktSize,op);
}
}
Output
Enter output rate : 100
Packet no 0
Packet no 1
Packet no 2
Packet no 3
Packet no 4
Packet size = 3
Bucket output successful
Last 3 bytes sent
Packet size = 33
Bucket output successful
Last 33 bytes sent
Packet size = 117
Bucket output successful
100 bytes outputted.
Last 17 bytes sent
Packet size = 95
Bucket output successful
Last 95 bytes sent
Packet size = 949
Bucket overflow
Experiment No 7
Hamming Codes
Problem Statement
Write a program for Hamming Code generation for error detection and correction
Theory
Hamming codes are used for detecting and correcting single bit errors in transmitted data. This
requires that 3 parity bits (check bits) be transmitted with every 4 data bits. The algorithm is
called A(7, 4) code, because it requires seven bits to encode 4 bits of data.
Eg:
Bit String
000
Parity Bit
0
001
010
011
100
101
110
111
Verification
0+0+0+0=
0
0+0+1+1=
0
0+1+0+1=
0
0+1+1+0=
0
1+0+0+1=
0
1+0+1+0=
0
1+0+1+0=
0
1+1+1+1=
0
Parity types:
Even: - Even number of 1s is present, i.e. the modulo 2 sum of the bits is 0.
Odd: - Odd number of 1s is present, i.e. the modulo 2 sum of the bits is 1.
Given data bits D1, D2, D3 and D4, A (7, 4) Hamming code may define parity bits P1, P2 and
P3 as,
P1=D2+D3+D4
P2=D1+D3+D4
P3=D1+D2+D4
There are 4 equations for a parity bit that may be used in Hamming codes,
P4=D1+D2+D3
Valid Hamming codes may use any 3 of the above 4 parity bit definitions. Valid Hamming
codes may also place the parity bits in any location within the block of 7 data and parity bits.
One method for transferring 4 bits of data into a 7 bit Hamming code word is to use a 4x7
generate matrix [G] defined to be the 1x4 vector [D1 D2 D3 D4].
Its possible to create a 4x7 generator matrix [G] such that the product modulo 2 of d and [ G]
(D[G]) is the desired 1x7 Hamming code word.
For example each data bits can be represented with in a column vector as follows.
1
D1=
D2=
0
D3=
D4=
0
0
0
1
And represent each parity bit with a column vector continuing a 1 in the row corresponding to
each data bit included in the computation and a zero in all other rows.
0
P1=
P2=
P3=
And
G=
P1
P2
P3
D1
D2
D3
D4
Encoding
The process to encode the data value 1010 using the Hamming code defined by the G matrix
is as follows: 0
1
1
1
0
0
0
[1010
]
0+0+1+0
1+0+1+0
1+0+0+0
1+0+0+0
1
1
0+0+0+0
0+0+1+0
0+0+0+0
Therefore 1010 encodes into 1011010. Equivalent Hamming codes represented by different
generator matrices will produce different results.
Decoding
The first step is to check the parity bits to determine if there is an error. Arithmetically, parity
may be checked as follows: P1 = D2+D3+D4 = 0+1+1 = 0
P2 = D1+D3+D4 = 1+1+1 = 1
P3 = D1+D2+D4 = 1+0+1 = 0
Parity may also be validated by using matrix operation. A 3x7 parity check matrix [H] may be
constructed such that row 1 contains 1 s in the position of the first parity bits and all the data bits
that are included in its parity calculation. Using this, matrix [H] may be defined as follows: -
H=
(1*1)+(0*0)+(0*1)+(0*1)+(1*0)+(1*1)+(1*1)
=
(0*1)+(1*0)+(0*1)+(1*1)+(0*0)+(1*1)+(1*1)
(0*1)+(0*0)+(1*1)+(1*1)+(1*0)+(0*1)+(1*1)
1
=
1
1
1
1
Looking back at the matrix [H] the 7th column is all 1s so the 7th bit is the bit that has an error.
Program 7
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
char data[5];
int encoded[8], edata[7], syndrome[3];
int hmatrix[3][7]= { 1,0,0,0,1,1,1,
0,1,0,1,0,1,1,
0,0,1,1,1,0,1};
char gmatrix[4][8]={ "0111000", "1010100", "1100010", "1110001"};
void main() {
int i,j;
clrscr();
cout<<"Hamming Code --- Encoding\n";
cout<<"Enter 4 bit data : ";
cin>>data;
cout<<"Generator Matrix\n";
for(i=0;i<4;i++) cout<<"\t"<<gmatrix[i]<<"\n";
cout<<"Encoded Data : ";
for(i=0;i<7;i++) {
for(j=0;j<4;j++)
encoded[i]+=((data[j]- '0')*(gmatrix[j][i]- '0'));
encoded[i]=encoded[i]%2;
cout<<encoded[i]<<" ";
}
cout<<"\nHamming code --- Decoding\n";
cout<<"Enter Encoded bits as received : ";
for(i=0;i<7;i++) cin>>edata[i];
for(i=0;i<3;i++) {
for(j=0;j<7;j++)
syndrome[i]=syndrome[i]+(edata[j]*hmatrix[i][j]);
syndrome[i]=syndrome[i]%2;
}
for(j=0;j<7;j++)
if ((syndrome[0]==hmatrix[0][j])&&(syndrome[1]==hmatrix[1][j])&&
(syndrome[2]==hmatrix[2][j]))
break;
if(j==7)
cout<<"Data is error free!!\n";
else {
cout<<"Error received at bit number "<<j+1<<" of the data\n";
edata[j]=!edata[j];
cout<<"The Correct data Should be : ";
for(i=0;i<7;i++) cout<<edata[i]<<" ";
}
Output
Hamming Code --- Encoding
Enter 4 bit data : 1 0 1 0
Generator Matrix
0111000
1010100
1100010
1110001
Encoded Data : 1 0 1 1 0 1 0
Hamming code --- Decoding
Enter Encoded bits as received : 1 0 1 1 0 1 1
Error received at bit number 7 of the data
The Correct data Should be : 1 0 1 1 0 1 0
Viva Questions
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.