DCNL Codes
DCNL Codes
4 Date:
ALGORITHM:
LEAKY BUCKET:
1. Start
2. Set the bucket size or buffer size and equate it to counter value.
3. Set the output rate.
4. Check the size of the packet with the counter size.
5. If the packet size is less than the counter transmit else make it wait for counter to
reset.
6. Repeat the process until all the packets transmitted.
7. Reject the packets where its size is greater than bucket size.
8. Stop.
TOKEN BUCKET:
1. Start
2. A token is added at every time.
3. The bucket can hold at most b-tokens. If a token arrive when bucket is full it is
discarded.
4. When a packet of m-bytes arrived m-tokens are removed from the buckets and the
packet is sent to the network.
5. If less than n-tokens are available no tokens are removed from the buckets and the
packet is considered to be non-conformant.
6. The non-conformant packet may be enquired for subsequent transmission when
sufficient token have been accumulated in the bucket or the non-conformant packet
may be dropped.
THEORY:
LEAKY BUCKET:
The leaky bucket is an algorithm that may be used to determine whether some sequence
of discrete events conforms to defined limits on their average and peak rates or frequencies.
The leaky bucket algorithm is used in packet switched computer networks and
telecommunications networks to check that data transmissions, in the form of packets, conform
to defined limits on bandwidth and burstiness (a measure of the unevenness or variations in the
traffic flow). It can also be used as a scheduling algorithm to determine the timing of
transmissions that will comply with the limits set for the bandwidth and burstiness applied by
the network: see network scheduler.
PROGRAM:
LEAKY BUCKET:
#include<stdio.h>
#include<stdlib.h>
struct packet
{
int time;
int size;
} p[50];
int main()
{
int i,n,m,k=0;
int bsize,bfilled,outrate;
printf("enter the number of packets:");
scanf("%d",&n);
printf("enter packets in the order of their arrival time\n");
for(i=0;i<n;i++)
{
printf("enter the time and size:");
scanf("%d%d",&p[i].time,&p[i].size);
}
printf("enter the bucket size:");
scanf("%d",&bsize);
printf("enter the output rate:");
scanf("%d",&outrate);
m=p[n-1].time;
i=1;
k=0;
bfilled=0;
while(i<=m||bfilled!=0)
{
printf("\n\nAt time %d",i);
if(p[k].time==i)
{
if(bsize>=bfilled+p[k].size)
{
bfilled=bfilled+p[k].size;
printf("\n%d byte packet is inserted",p[k].size);
k=k+1;
}
else
{
printf("\n%d byte packet is discarded",p[k].size);
k=k+1;
}
}
if(bfilled==0)
{
The Leaky Bucket Algorithm is based on, and gets its name from, an analogy of a
bucket that has a hole in the bottom through which any water it contains will leak away at a
constant rate, until or unless it is empty. Water can be added intermittently, i.e. in bursts, but if
too much is added at once, or it is added at too high an average rate, the water will exceed the
capacity of the bucket, which will overflow. Hence, this leaky bucket determines whether
adding some amount of water would exceed or conform to a limit on the average rate at which
water can be added, set by the leak rate, and a limit on how much water can be added in a burst,
set by the depth of the bucket.
In network scenario we can control the output rate to be always less than a fixed rate in
a packet switched network where the size of each packet can be different by making use of a
counter and clock. At the tick of the clock, the counter is set to the amount of data that can be
output in one tick. The algorithm then checks the size of the frame at the front of the queue. If
the size is less than equal to the value of the counter, the packet is sent; if the size is greater
than or equal to the value of the counter, the packet is left in the queue and waits for the next
tick of the clock. The leaky bucket is used to implement traffic policing and traffic shaping in
Ethernet and cellular data networks. The algorithm can also be used to control metered-
bandwidth Internet connections to prevent going over the allotted bandwidth for a month,
thereby avoiding extra charges.
TOKEN BUCKET:
The token bucket is an algorithm used in packet switched computer networks and
telecommunications networks. It can be used to check that data transmissions, in the form of
packets, conform to defined limits on bandwidth and burstiness (a measure of the unevenness
or variations in the traffic flow). It can also be used as a scheduling algorithm to determine the
timing of transmissions that will comply with the limits set for the bandwidth and burstiness:
see network scheduler. +
The token bucket algorithm is based on an analogy of a fixed capacity bucket into which
tokens, normally representing a unit of bytes or a single packet of predetermined size, are added
at a fixed rate. When a packet is to be checked for conformance to the defined limits, the bucket
is inspected to see if it contains sufficient tokens at that time. If so, the appropriate number of
tokens, e.g. equivalent to the length of the packet in bytes, are removed ("cashed in"), and the
packet is passed, e.g., for transmission. The packet does not conform if there are insufficient
tokens in the bucket, and the contents of the bucket are not changed. Non-conformant packets
can be treated in various ways:
They may be enqueued for subsequent transmission when sufficient tokens have
accumulated in the bucket. They may be transmitted, but marked as being non-conformant,
possibly to be dropped subsequently if the network is overloaded.
A conforming flow can thus contain traffic with an average rate up to the rate at
which tokens are added to the bucket, and have a burstiness determined by the depth of the
bucket. This burstiness may be expressed in terms of either a jitter tolerance, i.e. how much
sooner a packet might conform (e.g. arrive or be transmitted) than would be expected from
the limit on the average rate, or a burst tolerance or maximum burst size, i.e. how much more
than the average level of traffic might conform in some finite period.
printf("\nNo packets to transmitted");
}
else if(bfilled>outrate)
{
bfilled=bfilled-outrate;
printf("\n %d bytes transferred",outrate);
}
else
{
printf("\n%d bytes transferred",bfilled);
bfilled=0;
}
printf("\n packets in the bucket %d byte",bfilled);
i++;
}
return 0;
}
OUTPUT:
PROGRAM:
TOKEN BUCKET:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int no_of_packets, storage, output_queue;
int input_pkt_size, token_bucket;
int packet_arrival = 0;
storage = 0;
//no_of_packets = 8;
//bucket_size = 10;
printf("\nEnter the intial bucket size: ");
scanf("%d", &token_bucket);
//input_pkt_size = 4;
for ( int i = 0; i < 10; i++ )
{
if (token_bucket != 30)
token_bucket += 1;
else
{
printf("Max token size reached");
token_bucket = 0;
}
printf("\nToken size = %d", token_bucket);
packet_arrival = rand () % 2;
if (packet_arrival == 1)
{
input_pkt_size = rand () % 10 + 1;
printf("\nPacket of size incoming: %d\n", input_pkt_size);
if (input_pkt_size <= token_bucket)
{
printf("\nPacket is sent");
token_bucket -= input_pkt_size;
}
else
puts("\nPacket is discarded");
}
else
continue;
}
return 0;
}
OUTPUT:
RESULT:
Thus the following Congestion Control Algorithms were implemented and outputs
were verified.
1. Leaky Bucket Algorithm.
2. Token Bucket Algorithm.
Ex. No: 5 Date:
DATA ENCRYPTION AND DECRYPTION ALGORITHMS
AIM:
To verify the following data encryption and decryption algorithms.
1. Caesar Cipher Algorithm
2. Vigenere Cipher Algorithm
3. RSA Authentication Algorithm
THEORY:
Cryptography is the science of secret writing is an ancient art; the first documented use
of cryptography in writing dates back to circa 1900 B.C. when an Egyptian scribe used non-
standard hieroglyphs in an inscription. It is no surprise, then, that new forms of cryptography
came soon after the widespread development of computer communications. In data and
telecommunications, cryptography is necessary when communicating over any untrusted
medium, which includes just about any network, particularly the Internet.
1. Privacy/confidentiality: Ensuring that no one can read the message except the
intendedreceiver.
3. Integrity: Assuring the receiver that the received message has not been altered in
any wayfrom the original.
4. Non-repudiation: A mechanism to prove that the sender really sent this message.
5. Key exchange: The method by which crypto keys are shared between sender and
receiver.
CHARACTERISTICS OF CRYPTOGRAPHY:
1. Authentication
2. Data Privacy
3. Protection against Alteration
4. Non-repudiated Transfer of Information
5. Unobstructed Channel of Communication
PROGRAM:
CAESAR CIPHER ALGORITHM:
ENCRYPTION:
#include<stdio.h>
int main() {
char message[100], ch;
int i, key;
printf("Enter a message to encrypt: ");
gets(message);
printf("Enter key: ");
scanf("%d", &key);
message[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch + key;
if(ch > 'Z'){
ch = ch - 'Z' + 'A' - 1;
}
message[i] = ch;
}
}
printf("Encrypted message: %s", message);
return 0;
}
DECRYPTION:
#include<stdio.h>
int main() {
char message[100], ch;
int i, key;
printf("Enter a message to decrypt: ");
gets(message);
printf("Enter key: ");
scanf("%d", &key);
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
CAESAR CIPHER ALGORITHM:
The Caesar cipher, also known as a shift cipher, is one of the simplest forms of
encryption. It is a cipher where each letter in the original message called the plain text is
replaced with a letter corresponding to a certain number of letters up or down in the alphabet.
For example, with a left shift of 3, D would be replaced by A, E would become B, and so on.
The method is namedafter Julius Caesar, who used it in his private correspondence.
The encryption can also be represented using modular arithmetic by first transforming
the letters into numbers, according to the scheme, A=0, B-1...Z-25. Encryption of a letter x by
a shift be described mathematically as:
E, (x (x+n) mod 26
ALGORITHM:
1. Start.
3. During encryption, each alphabet in the message is shifted to the respective number
ofshift and replaced by another alphabet, places down the line.
OUTPUT:
VIGNERE CIPHER ALGORITHM:
The method was originally described by Glovan Battista Bellaso in 1553, later was
misattributed to Blaise de Vigenere and is widely known as Vigenere Cipher.
The Vigenere Cipher is a sequence with different shift values. To encrypt, a table of
alphabets can be used, termed a tabula recta, Vigenere square, or Vigenere table. It consists of
the alphabet written out 26 times in different rows, each alphabet shifted cyclically to the left
compared to the previous alphabet, corresponding to the 26 possible Caesar ciphers. At different
points in the encryption process, the cipher uses a different alphabet from one of rows.
ALGORITHM:
1. Start.
#include<stdio.h>
#include<string.h>
int main()
{
char msg[100],key[100];
int i, j;
//encryption
for(i = 0; i < msgLen; ++i)
encryptedMsg[i] = ((msg[i] + newKey[i]) % 26) + 'A';
encryptedMsg[i] = '\0';
//decryption
for(i = 0; i < msgLen; ++i)
decryptedMsg[i] = (((encryptedMsg[i] - newKey[i]) + 26) % 26) + 'A';
decryptedMsg[i] = '\0';
return 0;
}
OUTPUT:
RIVEST SHAMIR ADLEMAN ALGORITHM (RSA):
RSA is one of the first practical cryptosystems and is widely used for secure data
transmission. In such a cryptosystem, the encryption key is public and differs from the
decryption key which is kept secret. In RSA, this asymmetry is based on the practical difficulty
of factoring problem. RSA is made of the initial letters of the surnames of Ron Rivest, Adi
Shamir and Leonard Adleman, who first publicly described the algorithm in 1977.
A user of RSA creates and then publishes a public key based on two large prime
numbers, along with an auxiliary value. The prime numbers must be kept secret. Anyone can
use the public key to encrypt a message. If the public key must be large enough only someone
with knowledge of the prim numbers can feasibly decode the message.
RSA is a relatively slow algorithm, and because of this it is less commonly used to
directly encrypt user data. More often, RSA passes encrypted shared keys for symmetric key
cryptography which in turn can perform bulk encryption-decryption operations a much higher
speed.
ARITHMETIC PROCESS:
RSA involves a public key and private key The public key can be known to everyone, it
is used to encrypt messages. Messages encrypted using the public key can only be decrypted
with theprivate key. The keys for the RSA algorithm are generated the following way:
1. Generate two large random primes, p and q, of equal size such that their product
npq isof the required bit length, e.g. 1024 bits.
2. Compute n = pq and (phi) - (p-1) (q-1). 3. Choose an integer e, 1 <e <phi, such that
gcd(e, phi) - 1.
3. Compute the secret exponent d, 1<d<phi, such that ed= 1 (mod phi).
4. The public key is (n, e) and the private key (d, p, q). Keep all the values d, p, q and
phi secret. [We prefer sometimes to write the private key as (n, d) because you need
the value of n when using d. Other times we might write the key pair as ((N, e), d).]
Compute n=p*q=3*11=33
PROGRAM:
RSA ALGORITHM:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
long int p,q,n,t,flag,e[100],d[100],temp[100],en[100],j,i;
char m[100];
char msg[100];
int prime(long int);
void ce();
long int cd(long int);
void encrypt();
void decrypt();
void main() {
printf("\nENTER FIRST PRIME NUMBER\n");
scanf("%ld",&p);
flag=prime(p);
if(flag==0) {
printf("\nWRONG INPUT\n");
exit(1);
}
}
printf("\nENTER MESSAGE\n");
fflush(stdin);
scanf("%s",msg);
for (i=0;msg[i]!='\0';i++) {
m[i]=msg[i];
n=p*q;
t=(p-1)*(q-1);
ce();
printf("\nPOSSIBLE VALUES OF e AND d ARE\n");
for (i=0;i<j-1;i++)
printf("\n%ld\t%ld",e[i],d[i]);
encrypt();
decrypt();
}
Compute o(n)=(p-1) * (q-1)=2*10=20
Choose e such that 1 <e <p(n) and e and o (n) are co-prime. Let e = 7
d=3 [(3*7) % 20 = 1]
ALGORITHM:
1. Start.
void encrypt() {
long int pt,ct,key=e[0],k,len;
i=0;
len=strlen(msg);
while(i!=len) {
pt=m[i];
pt=pt-96;
k=1;
for (j=0;j<key;j++) {
k=k*pt;
k=k%n;
}
temp[i]=k;
ct=k+96;
en[i]=ct;
i++;
}
en[i]=-1;
printf("\nTHE ENCRYPTED MESSAGE IS\n");
for (i=0;en[i]!=-1;i++)
printf("%ld",en[i]);
}
void decrypt() {
long int pt,ct,key=d[0],k;
i=0;
while(en[i]!=-1) {
ct=temp[i];
k=1;
for (j=0;j<key;j++) {
k=k*ct;
k=k%n;
OUTPUT:
RESULT:
Thus, the following data encryption and decryption has been implemented and verified.
1. Caesar Cipher Algorithm
2. Vigenere Cipher Algorithm
3. RSA Authentication Algorithm
Ex. No. 2 Date:
ALGORITHM:
1. Start.
2. Get the data and the divisor as input.
3. Perform XOR division and determine the remainder.
4. Then append the remainder at the end of data bits.
5. Get the received data from the user.
6. Again, perform the XOR division, if the remainder is ‘0’, then the received data bit
is not connected.
7. Else the received data bit is corrupted.
8. Stop.
THEORY:
HAMMING CODE:
Hamming Code is a set of error correction code that can be used to detect and correct it
error that can occur when computer data is moved or stored. Hamming code is named R.W
Hamming of Bell Labs. Hamming codes makes FEC less expensive to implement through the
use of block parity mechanism.
A minimum number of redundancy bits are needed to correct any single bit
error in the data.
A minimum number of 4 redundancy bits is needed if the number of data bits
is 4.
Redundancy bits in the hamming code are placed in the code word bit positions
that are raised to the power of 2.
Each redundancy bit is the parity bit for a different combination of data bits.
Each data bits may be included in more than one parity check.
PROGRAM:
HAMMING CODE:
#include<stdio.h>
void main()
{
int data[10];
int dataatrec[10],c,c1,c2,c3,i;
for(i=0;i<7;i++)
scanf("%d",&dataatrec[i]);
c1=dataatrec[6]^dataatrec[4]^dataatrec[2]^dataatrec[0];
c2=dataatrec[5]^dataatrec[4]^dataatrec[1]^dataatrec[0];
c3=dataatrec[3]^dataatrec[2]^dataatrec[1]^dataatrec[0];
c=c3*4+c2*2+c1;
Hamming codes detect two bit errors with more than one parity bit, each of which is
computed on different combinations of bits in the data. The number of parity bits required
depends on the number of bits in the data transmission, and is calculated by the hamming
rule. d+p+1<=2(1), where d is the no of data bits and p is the no of parity bits.
AIM:
To implement Error Detection codes such as Parity Checker code and Cyclic
Redundancy Check Code in C Language.
ALGORITHM:
PARITY CHECKER:
1. Start.
2. Get the data and the divisor as input.
3. Perform XOR division and determine the remainder.
4. Then append the remainder at the end of data bits.
5. Get the received data from the user.
6. Again, perform the XOR division, if the remainder is '0', then the received data bit is
not corrected.
7. Else the received data bit is corrupted.
8. Stop.
THEORY:
PARITY CHECKER:
Parity checking is the most basic form of error detection in communications. A parity
check is a process that ensures accurate data transmission between nodes during
communication. A parity bit is appended to the original data bits to create an even or odd
number, the number of bits to value one. The source then transmits this data via a link, and bits
are checked and verified at the destination. Data is considered accurate if the number of bits
matches the number transmitted from the source.
PROGRAM:
PARITY CHECK:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
char data[20],rdata[20]; int datlen;
int check(char data[20]);
int main()
{
int i, count=0, tflag, rflag, test;
tflag=check(data);
puts("\n Rececived data: \n");
strcpy(rdata, data);
for(i=0; i<datlen; i++)
printf("%c",rdata[i]);
srand(time(NULL));
test=rand()%2;
printf("\nrand=%d\n", test);
rdata[0]=(test>0.5)?'1':'0';
printf("Received data after replacing with rand\n");
for(i=0;i<datlen; i++)
printf("%c",rdata[i]);
rflag=check(rdata);
if(tflag==rflag)
puts("\n Success!!!\nThe received message has no error");
else
puts("\n Failure!!!\n The received message has some error in it.");
return 0;
}
Parity checking, which was created to eliminate data communication errors, is a simple
method of network data verification and has an easy and understandable working mechanism.
As an example, if original data is 1010001, there are three 1's when even parity checking
is used, a parity bit with value 1 is added to data left side to make the number of ones even;
transmitted data becomes 11010001. However, if odd parity checking is used, then the parity
bit value is 0,01010001.
If the original data contains an even number of 1's, then parity bit of value 1 is added
to the data's left side to make the number of ones is odd, if odd parity checking is used and data
transmitted becomes 11101001. In case data is transmitted incorrectly, the parity bit value
becomes incorrect, thus indicating an error has occurred during transmission.
Parity checking is used not only in communication but also to test memory storage
devices Many PCs, for example, perform a parity check on memory every time a byte of data
is read.
In data transmission, the ability of a receiving station to correct errors in the received
data is called forward error correction (FEC) and can increase throughput on a data link when
there is a lot of mouse present. To enable this, the transmitting station must add extra data
(called error corrections bits) to the transmission. However, the correction may not always
represent a cost-saving over that of simply resending the information.
CRC is based on binary division. In CRC, instead of adding bits to achieve the desired
parity, a sequence of redundant bits, called the CRC or CRC remainder, is appended to the end
of the data unit so that the resulting data unit becomes exactly divisible by a second,
predetermined binary number. At the destination, the incoming data unit is assumed to be intact
and is therefore accepted. A remainder indicates that the data unit has been damaged in transit
and therefore must be rejected.
int check(char data[20])
{
int i,evenpar, oddpar, count=0;
for(i=0; i<datlen; i++)
{
if (data[i]=='1')
count++;
}
printf("\n Count:\n%d\n",count);
if (count%2)
{
evenpar=1;
oddpar=0;
}
else
{
evenpar=0;
oddpar=1;
}
OUTPUT:
PROGRAM:
CYCLIC REDUNDANCY CHECK:
#include<stdio.h>
char data[20],div[20],temp[4],total[100];
int i,j,datalen,divlen,len,flag=1;
void check();
int main()
{
printf("Enter the total bit of data:");
scanf("%d",&datalen);
printf("\nEnter the total bit of divisor");
scanf("%d",&divlen);
len=datalen+divlen-1;
printf("\nEnter the data:");
scanf("%s",&data);
printf("\nEnter the divisor");
scanf("%s",div);
for(i=0;i<datalen;i++)
{
total[i]=data[i];
temp[i]=data[i];
}
for(i=datalen;i<len;i++)
total[i]='0';
check();
for(i=0;i<divlen;i++)
temp[i+datalen]=data[i];
printf("\ntransmitted Code Word:%s",temp);
printf("\n\nEnter the received code word:");
scanf("%s",total);
check();
for(i=0;i<divlen-1;i++)
if(data[i]=='1')
{
flag=0;
break;
}
if(flag==1)
printf("\nsuccessful!!");
else
printf("\nreceived code word contains errors...\n");
}
void check()
{
for(j=0;j<divlen;j++)
data[j]=total[j];
while(j<=len)
{
if(data[0]=='1')
for(i = 1;i <divlen ; i++)
data[i] = (( data[i] == div[i])?'0':'1');
for(i=0;i<divlen-1;i++)
data[i]=data[i+1];
data[i]=total[j++];
}
}
OUTPUT:
RESULT:
Thus, the error-detecting codes such as Parity Checker codes and Cyclic Redundancy
Check Codes has been implemented and verified successfully.
Ex. No.3 Date:
FLOW CONTROL MECHANISM USING ARQ
AIM:
To implement the flow control mechanisms such as Stop and Wait ARQ, Go Back –
N ARQ and Selective Repeat ARQ.
ALGORITHM:
STOP AND WAIT ARQ:
1. Start.
2. Enter the number of frames to be transmitted.
3. Sender transmits the first frame and waits for the acknowledgement from the receiver
for the transit time.
4. The receiver sends the acknowledgement (ACK) to the sender.
5. If the sender receives the ACK, it transmits the next frame.
6. Else the sender waits until the timer expires, and re-transmits the frame again.
7. The above step is followed until all the frames get transmitted.
8. Stop the program.
GO BACK N ARQ:
1. Start.
2. Enter the number of frames to be transmitted.
3. Enter the window size n.
4. The sender transmits the group of frames and each frame is labeled with a sequence
number.
5. If the receiver receives the frames intact then the receiver sends positive
acknowledgement.
6. Else the receiver sends the negative acknowledgement for the frame from which the
sender has to re-transmit the frame in sequence.
7. The step is followed until all the frames get transmitted.
8. Stop the program.
SELECTIVE REPEAT ARQ:
1. Start.
2. Enter the number of frames to be transmitted.
3. Enter the window size n.
4. The sender transmits the group of frames and each frame is labeled with a sequence
number.
5. If the receiver receives the frames intact then the receiver sends positive
acknowledgement.
6. Else the receiver sends the negative acknowledgement for the particular frame which
is lost or damaged.
7. Hence the sender re-transmits that particular frame and sends the next group of
frames.
8. The step is followed until all the frames get transmitted.
9. Stop the program.
PROGRAM:
STOP AND WAIT ARQ:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void main()
{
int i=1,j=1,noframes,x,x1=10,x2;
printf(“\nEnter the number of windows: “);
scanf(“%d”,&noframes);
printf("\nNumber of frames is %d",noframes);
while(noframes>0)
{
printf("\nSending Frame %d",i);
srand(x1++);
x=rand()%10;
if(x%2==0)
{
for(x2=1;x2<2;x2++)
{
printf("\nWaiting for %d seconds, No acknowledgement received so
retransmitting frame \n",x2);
sleep(x2);
}
printf("\nRetransmitting Frame %d",i);
srand(x1++);
x=rand()%10;
}
printf("\nAcknowledgement for frame %d",j);
noframes-=1;
i++;
j++;
}
printf("\nEnd of stop wait protocol");
}
THEORY:
FLOW CONTROL:
It refers to set of procedure involved in data link layer, to know the number of frames
that can be sent to the receiver without overwhelming to the receiver.
FLOW CONTROL PROTOCOL:
1. Stop and Wait ARQ
2. Sliding Window Protocol
Go Back N ARQ
Selective Repeat ARQ
ADVANTAGES:
It is the simplest algorithm.
No sequence is needed.
DISADVANTAGES:
Resource utilization is more.
Transmission time is huge.
OUTPUT:
SLIDING WINDOW PROTOCOL:
Multiple frames are transmitted at a time. The sequence of the frame should be given.
The window size must be same at the receiver and the sender.
There are three possibilities:
1. Lost data frame
2. Damaged data frame
3. Lost ACK
For the above possibilities, the sender should always preserve the copies of transmitted
frames and activates the timers and wait for the acknowledgement. If there is no response in
the form of NAK/ACK the sender re-transmits all the frames. The receiver should send the
damage frame (NAK) or the next expected frame (ACK) and should be aware of the status of
lost/received frames. It needs to check whether the frame received is duplicate or not. If the
frame received is duplicate then discard it.
GO BACK N ARQ:
The group of frames is transmitted by the sender and it wait for the acknowledgement. If one
of the frames is erroneous in the group of frames then the remaining frames are discarded.
Thus, the sender re-transmits the frames from the erroneous frame onwards.
PROGRAM:
GO BACK N ARQ:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
int nf, N;
int no_tr = 0;
srand(time(NULL));
printf("Enter the number of frames : ");
scanf("%d", &nf);
printf("Enter the window size : ");
scanf("%d", &N);
int i = 1;
while (i <= nf)
{
int x = 0;
for (int j = i; j < i + N && j <= nf; j++)
{
printf("Sent Frame %d\n", j);
no_tr++;
}
for (int j = i; j < i + N && j <= nf; j++)
{
int flag = rand() % 2;
if (!flag)
{
printf("Acknowledgment for Frame %d\n", j);
x++;
}
else
{
printf("Frame %d", j);
printf(" Not Received\n");
printf("Retransmitting Window");
break;
}
}
printf("\n");
i += x;
}
printf("Total number of transmissions : %d\n", no_tr);
return 0;
}
ADVANTAGES:
One ACK can acknowledge more than one frames.
The sender can send many frames at a time.
Efficiency is more.
DISADVANTAGE:
Resource utilization is more.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
int nf, N;
int no_tr = 0;
srand(time(NULL));
printf("Enter the number of frames : ");
scanf("%d", &nf);
printf("Enter the window size : ");
scanf("%d", &N);
int i = 1;
while (i <= nf)
{
int x = 0;
for (int j = i; j < i + N && j <= nf; j++)
{
printf("Sent Frame %d\n", j);
no_tr++;
}
for (int j = i; j < i + N && j <= nf; j++)
{
int flag = rand() % 2;
if (!flag)
{
printf("Acknowledgment for Frame %d\n", j);
x++;
}
else
{
printf("Frame %d Not Received\n", j);
printf("Retransmitting frame %d alone\n",j);
j--;
no_tr++;
}
}
i += x;
printf("\n");
}
printf("Total number of transmissions : %d\n", no_tr);
return 0;
}
OUTPUT:
RESULT:
Thus, the codes for implementing ARQ based flow control protocols such as Stop and
Wait ARQ, Go Back – N ARQ and Selective Repeat ARQ are verified successfully.
Ex. No: 8 Date:
DIJKSTRA’S SHORTEST PATH ALGORITHM
AIM:
Write a C program to implement Dijkstra’s algorithm to compute the shortest path
between nodes.
ALGORITHM:
1. Create cost matrix C[ ][ ] from adjacency matrix adj[ ][ ]. C[i][j] is the cost of going
from vertex i to vertex j. If there is no edge between vertices i and j then C[i][j] is
infinity.
4. Create the distance matrix, by storing the cost of vertices from vertex no. 0 to n-1 from
the source vertex 0.
for(i=1;i<n;i++)
distance[i]=cost[0][i];
Initially, distance of source vertex is taken as 0. i.e. distance[0]=0;
5. for(i=1;i<n;i++)
– Choose a vertex w, such that distance[w] is minimum and visited[w] is 0. Mark
visited[w] as 1.
– Recalculate the shortest distance of remaining vertices from the source.
– Only, the vertices not marked as 1 in array visited[ ] should be considered for
recalculation of distance. i.e. for each vertex v
if(visited[v]==0)
distance[v]=min(distance[v],
distance[w]+cost[w][v]).
THEORY:
GRAPHS:
Graphs are data structures used to represent "connections" between pairs of elements.
▪ These elements are called nodes. They represent real-life objects, persons, or entities.
▪ The connections between nodes are called edges.
.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#define INFINITY 9999
#define MAX 10
int main()
{
int G[MAX][MAX],i,j,n,u;
printf("Enter no. of vertices:");
scanf("%d",&n);
printf("\nEnter the adjacency matrix:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&G[i][j]);
printf("\nEnter the starting node:");
scanf("%d",&u);
dijkstra(G,n,u);
return 0;
}
int cost[MAX][MAX],distance[MAX],pred[MAX];
int visited[MAX],count,mindistance,nextnode,i,j;
//pred[] stores the predecessor of each node
//count gives the number of nodes seen so far
//create the cost matrix
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(G[i][j]==0)
cost[i][j]=INFINITY;
else
cost[i][j]=G[i][j];
//initialize pred[],distance[] and visited[]
for(i=0;i<n;i++)
{
distance[i]=cost[startnode][i];
pred[i]=startnode;
visited[i]=0;
}
distance[startnode]=0;
visited[startnode]=1;
count=1;
while(count<n-1)
{
mindistance=INFINITY;
This is a graphical representation of a graph:
Types of Graphs:
Graphs can be:
• Undirected: if for every pair of connected nodes, you can go from one node to the other
in both directions.
• Directed: if for every pair of connected nodes, you can only go from one node to
another in a specific direction. We use arrows instead of simple lines to represent
directed edges.
DIJKSTRA'S ALGORITHM:
• The algorithm keeps track of the currently known shortest distance from each node to
the source node and it updates these values if it finds a shorter path.
• Once the algorithm has found the shortest path between the source node and another
node, that node is marked as "visited" and added to the path.
//nextnode gives the node at minimum distance
for(i=0;i<n;i++)
if(distance[i]<mindistance&&!visited[i])
{
mindistance=distance[i];
nextnode=i;
}
//check if a better path exists through nextnode
visited[nextnode]=1;
for(i=0;i<n;i++)
if(!visited[i])
if(mindistance+cost[nextnode][i]<distance[i])
{
distance[i]=mindistance+cost[nextnode][i];
pred[i]=nextnode;
}
count++;
}
Requirements:
Dijkstra's Algorithm can only work with graphs that have positive weights. This is
because, during the process, the weights of the edges have to be added to find the shortest path.
If there is a negative weight in the graph, then the algorithm will not work properly. Once a
node has been marked as "visited", the current path to that node is marked as the shortest path
to reach that node. And negative weights can alter this if the total weight can be decremented
after this step has occurred.
Time Complexity:
The program contains two nested loops each of which has a complexity of O(n). n is
number of vertices. So the complexity of algorithm is O(n2).
Advantages:
▪ It is used in Google Maps
▪ It is used in finding Shortest Path.
▪ It is used in geographical Maps
▪ To find locations of Map which refers to vertices of graph.
▪ Distance between the location refers to edges.
▪ It is used in IP routing to find Open shortest Path First.
▪ It is used in the telephone network.
Disadvantages:
▪ It does blind search so wastes lot of time while processing.
▪ It cannot handle negative edges.
▪ This leads to acyclic graphs and most often cannot obtain the right shortest path.
OUTPUT:
RESULT:
AIM:
Write a C program to implement IP route lookup based on the optimized TRIE structure
and evaluate the performance.
THEORY:
IP ROUTING:
IP Routing is a process that sends packets from a host on one network to another host on
a different remote network. It helps you examine the destination IP address of a packet, determine
the next-hop address, and forward it. IP routers use routing tables to determine the next-hop
address to which the packet should be delivered.
In IP routing, data is routed from its source to its destination through routers and across
multiple networks. The IP Routing protocols allow routers to build up a forwarding table that
correlates final destinations with next-hop addresses.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int error_code; // In this variable we save the error codes that produces some methods
//RIB.h
// Route related hedaers
#define MTABLE_ENTRIES_LENGTH 16777216 // 2^24 entries
RIB_t rib;
uint32_t *IP_addr;
int *aux_prefixLength;
int *aux_outInterface;
/***********************************************************************
* Static variables for the input/output files
***********************************************************************/
static FILE *routingTable;
static FILE *inputFile;
static FILE *outputFile;
ROUTING METRICS
Routing metric are the value that allows the routers to decide the best route for the data packet
• Hops
• Bandwidth
• Load
• Cost
• Reliability
• Host X has an IP address of the router T1 configured as the default gateway address.
• Here, host X is trying to communicate with host Y, which is a host on another remote
network.
• This host looks up in its routing table to check if there is an entry for the destination
network address.
• If the entry is found, the host will send all data to the router T1.
• Router T1 then receives the packets and forwards them to host Y.
.
void RIB_init(RIB_t* self);
void RIB_addRoute(RIB_t* rib, uint32_t *ipv4_addr, int *mask, int *out_iface);
void RIB_lookup(RIB_t* rib, uint32_t *IP_lookup, short int *ntables, unsigned short *iface);
void RIB_destroy(RIB_t* rib);
/********************************************************************
* Constant definitions
********************************************************************/
#define OUTPUT_NAME ".out"
#define OK 0
#define ROUTING_TABLE_NOT_FOUND -3000
#define INPUT_FILE_NOT_FOUND -3001
#define BAD_ROUTING_TABLE -3002
#define REACHED_EOF -3003
#define BAD_INPUT_FILE -3004
#define PARSE_ERROR -3005
#define CANNOT_CREATE_OUTPUT -3006
processedPackets = calloc(1,sizeof(int));
totalTableAccesses = calloc(1,sizeof(double));
totalPacketProcessingTime = calloc(1,sizeof(double));
error_code = 0;
if( argc == 3 )
{
error_code = initializeIO(argv[1], argv[2]); //Initialize Input
if(error_code != 0){
printf("\nERROR: \n\t");
printIOExplanationError(error_code);
return -1; }
TYPES OF ROUTING PROTOCOLS:
The following protocols help data packets find their way across the Internet:
IP:
The Internet Protocol (IP) specifies the origin and destination for each data packet. Routers
inspect each packet’s IP header to identify where to send them.
OSPF:
Open Shortest Path First (OSPF) protocol is a link-state IGP tailor-made for IP networks using
the Shortest Path First (SPF) method.
RIP:
RIP is used in both LAN and WAN Networks. It also runs on the application layer of the OSI
model. The full form of RIP is the Routing Information Protocol. Two versions of RIP are
1. RIPv1
2. RIPv2
EIGRP:
It is a hybrid routing protocol that provides routing protocols, distance vector, and link-state
routing protocols. It will route the same protocols that IGRP routes using the same composite
metrics as IGRP, which helps the network select the best path destination.
ISIS:
ISIS routing protocol is used on the Internet to send IP routing information. It consists of a
range of components, including end systems, intermediate systems, areas, and domains.
BGP:
BGP is a routing protocol of the Internet, which is classified as a DPVP (distance path vector
protocol). The full form of BGP is the Border Gateway Protocol.
ADVANTAGES OF IP ROUTING:
The routing process ensures that appropriate packets are routed from the source to the
destination
• It offers stability
• It provides a robust network
• Offers dynamic routing update of the network paths
• Information is safe while transmitting.
initializeRouteTable();
compute_routes();
printSummary(*processedPackets, (*totalTableAccesses / *processedPackets),
(*totalPacketProcessingTime / *processedPackets));
freeIO(); /* Freeing Resources */
RIB_destroy(&rib);
free(processedPackets);
free(totalTableAccesses);
free(totalPacketProcessingTime);
}
else
{
printf("\nUSE:\n\t./my_route_lookup <routingTable>
<inputFile>\n\nWHERE:\n\t<routingTable>\t\tThe path for the file containing the routing
table\n\t<inputFile>\t\tThe path for the input file\n\n");
return -1;
}
return 1;
}
/********************************************************************
* Initalize file descriptors
*
* routingTableName contains FIB info (argv[1] of main function)
* inputFileName contains IP addresses (argv[2] of main function)
*
***********************************************************************/
int initializeIO(char *routingTableName, char *inputFileName){
char outputFileName[100];
}
ROUTE LOOKUP IN A TRIE
Looking up a route in a routing table is to find the most specific prefix matching the requested
destination.
For each node, the prefix is known by its path from the root node and the prefix length is the
current depth.
A lookup in such a trie is quite simple: at each step, fetch the nth bit of the IP address, where n
is the current depth. If it is 0, continue with the first child. Otherwise, continue with the second.
If a child is missing, backtrack until a routing entry is found. For example, when looking for
[Link], we will find the result in the corresponding leaf (at depth 32). However for
[Link], we will reach [Link]/31 but there is no second child. Therefore, we backtrack
until the [Link]/25 routing entry.
Adding and removing routes is quite easy. From a performance point of view, the lookup is
done in constant time relative to the number of routes (due to maximum depth being capped to
32).
void initializeRouteTable()
{
IP_addr = calloc(1,sizeof(int));
aux_prefixLength = calloc(1,sizeof(int));
aux_outInterface = calloc(1,sizeof(int));
error_code = readFIBLine(IP_addr, aux_prefixLength, aux_outInterface);
while(error_code == 0){ //WHILE NOT EOF OR ANOTHER TYPE OF ERROR
RIB_addRoute(&rib, IP_addr,aux_prefixLength,aux_outInterface);
error_code = readFIBLine(IP_addr,aux_prefixLength,aux_outInterface);
}
free(IP_addr);
free(aux_prefixLength);
free(aux_outInterface);
}
/***********************************************************************
* Read one entry in the FIB
*
* It should be noted that prefix, prefixLength and outInterface are
* pointers since they are used as output parameters
*
***********************************************************************/
int readFIBLine(uint32_t *prefix, int *prefixLength, int *outInterface){
int n[4], result;
/**
* [Perform routing process, going through the file and looking for the best Interface for each
IP]
*
* Output:
* processedPackets
* totalTableAccesses
* totalPacketProcessingTime
*/
void compute_routes()
{
uint32_t *IP_lookup = calloc(1,sizeof(uint32_t));
unsigned short *interface = calloc(1,sizeof(unsigned short));
double *searching_time = calloc(1,sizeof(double));
short int *number_of_tables = calloc(1,sizeof(short int));
error_code = readInputPacketFileLine(IP_lookup);
while(error_code == 0)
{
gettimeofday(&start, NULL);
RIB_lookup(&rib, IP_lookup, number_of_tables, interface);
gettimeofday(&end, NULL);
printOutputLine(*IP_lookup, *interface, &start, &end,searching_time,
*number_of_tables);
*processedPackets = *processedPackets + 1;
*totalTableAccesses = *totalTableAccesses + *number_of_tables;
*totalPacketProcessingTime = *totalPacketProcessingTime + *searching_time;
error_code = readInputPacketFileLine(IP_lookup);
}
free(IP_lookup);
free(interface);
free(searching_time);
free(number_of_tables);
}
/***********************************************************************
* Read one entry in the input packet file
*
* Again, it should be noted that IPAddress is a pointer since it is used
* as output parameter
*
***********************************************************************/
int readInputPacketFileLine(uint32_t *IPAddress){
/***********************************************************************
* Print a line to the output file
*
* gettimeofday(&initialTime, NULL) must be called right before the lookup function
*
* gettimeofday(&finalTime, NULL) must be called right after the lookup function
* The lookup function must return (either as output parameter or as return value)
* the number of hash tables that have been accessed for every IP address
*
***********************************************************************/
void printOutputLine(uint32_t IPAddress, int outInterface, struct timeval *initialTime, struct
timeval *finalTime,
double *searchingTime, int numberOfHashtables) {
/***********************************************************************
* Print execution summary to the output file
*
* It should be noted that:
*
* averageTableAccesses = totalTableAccesses/processedPackets
*
* averagePacketProcessingTime = totalPacketProcessingTime/processedPackets
*
***********************************************************************/
void printSummary(int processedPackets, double averageTableAccesses, double
averagePacketProcessingTime){
fprintf(outputFile, "\nPackets processed= %i\n", processedPackets);
fprintf(outputFile, "Average table accesses= %.2lf\n", averageTableAccesses);
fprintf(outputFile,"Average packet processing time (usecs)= %.2lf\n",
averagePacketProcessingTime);
printMemoryTimeUsage(); }
/***********************************************************************
* Print memory and CPU time
*
* For more info: man getrusage
*
***********************************************************************/
void printMemoryTimeUsage(){
/***********************************************************************
* Close the input/output files
***********************************************************************/
void freeIO() {
fclose(inputFile);
fclose(outputFile);
fclose(routingTable);
/***********************************************************************
* Write explanation for error identifier (verbose mode)
***********************************************************************/
void printIOExplanationError(int result){
switch(result) {
case ROUTING_TABLE_NOT_FOUND:
printf("Routing table not found\n");
exit(0);
case INPUT_FILE_NOT_FOUND:
printf("Input file not found\n");
exit(0);
case BAD_ROUTING_TABLE:
printf("Bad routing table structure\n");
exit(0);
case BAD_INPUT_FILE:
printf("Bad input file structure\n");
exit(0);
case PARSE_ERROR:
printf("Parse error\n");
exit(0);
case CANNOT_CREATE_OUTPUT:
printf("Cannot create output file\n");
exit(0);
case REACHED_EOF:
printf("Reached End Of File\n");
exit(0);
default:
printf("Unknown error\n");
exit(0);
}
exit(0);
/**
* [Look for an IP address inside the main table and secundary table stored in RAM]
* Input:
* IP_lookup
* Output.
* interface
* ntables
*/
void RIB_lookup(RIB_t* rib, uint32_t *IP_lookup, short int *ntables, unsigned short *iface)
{
*iface = rib->main_table[*IP_lookup>>8];
if(*iface>>15 == 0)
{
*ntables = 1;
return;
}
else
{
*ntables = 2;
*iface = rib->aux_table[(*iface & 0x7FFF)*256 + (*IP_lookup &
0x000000FF)];
// 0x7fff = 0b0111111111111111 to adquire just the address to the 2nd table
return;
}
return;
}
void RIB_destroy(RIB_t* rib) {
if (rib) {
free(rib->main_table);
free(rib->aux_table);
}
}
OUTPUT:
RESULT:
Thus the C program to implement IP route lookup based on the optimized TRIE structure
and to evaluate its performance has been executed successfully.
Ex. No: 7 Date:
FILE TRANSFER USING CLIENT – SERVER PROGRAM
AIM:
Write a C program to make the Server send the content of the requested file to the Client
if the file is present.
ALGORITHM:
SERVER:
CLIENT:
THEORY:
UDP PROTOCOL:
In computer networking, the UDP stands for User Datagram Protocol. The David P.
Reed developed the UDP protocol in 1980. It is defined in RFC 768, and it is a part of
the TCP/IP protocol, so it is a standard protocol over the internet. The UDP protocol allows the
computer applications to send the messages in the form of datagrams from one machine to
another machine over the Internet Protocol (IP) network. The UDP is an alternative
communication protocol to the TCP protocol (transmission control protocol). Like TCP, UDP
provides a set of rules that governs how the data should be exchanged over the internet.
The UDP works by encapsulating the data into the packet and providing its own header
information to the packet. Then, this UDP packet is encapsulated to the IP packet and sent off to
its destination. Both the TCP and UDP protocols send the data over the internet protocol
network, so it is also known as TCP/IP and UDP/IP. There are many differences between these
two protocols. UDP enables the process to process communication, whereas the TCP provides
host to host communication.
Since UDP sends the messages in the form of datagrams, it is considered the best-effort
mode of communication. TCP sends the individual packets, so it is a reliable transport medium.
PROGRAM:
UDP SERVER:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
}
Features of UDP protocol:
UDP is the simplest transport layer communication protocol. It contains a minimum amount of
communication mechanisms. It is considered an unreliable protocol, and it is based on best-
effort delivery services. UDP provides no acknowledgment mechanism, which means that the
receiver does not send the acknowledgment for the received packet, and the sender also does
not wait for the acknowledgment for the packet that it has sent.
o Connectionless
The UDP is a connectionless protocol as it does not create a virtual path to transfer the data. It
does not use the virtual path, so packets are sent in different paths between the sender and the
receiver, which leads to the loss of packets or received out of order.
In the case of UDP, the datagrams are sent in some order will be received in the same order is
not guaranteed as the datagrams are not numbered.
o Ports
The UDP protocol uses different port numbers so that the data can be sent to the correct
destination. The port numbers are defined between 0 and 1023.
o Faster transmission
o Acknowledgment mechanism
The UDP does have any acknowledgment mechanism, i.e., there is no handshaking between the
UDP sender and UDP receiver. If the message is sent in TCP, then the receiver acknowledges
that I am ready, then the sender sends the data. In the case of TCP, the handshaking occurs
between the sender and the receiver, whereas in UDP, there is no handshaking between the
sender and the receiver.
UDP CLIENT:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
int n, len;
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &servaddr, sizeof(servaddr));
printf("Hello message sent.\n");
Each UDP segment is handled individually of others as each segment takes different path to
reach the destination. The UDP segments can be lost or delivered out of order to reach the
destination as there is no connection setup between the sender and the receiver.
Limitations:
o It provides an unreliable connection delivery service. It does not provide any services of
IP except that it provides process-to-process communication.
o The UDP message can be lost, delayed, duplicated, or can be out of order.
o It does not provide a reliable transport delivery service. It does not provide any
acknowledgment or flow control mechanism. However, it does provide error control to
some extent.
Advantages:
o It produces a minimal number of overheads.
OUTPUT:
RESULT:
Thus the connection between two computers using UDP File Transfer Client-Server was
implemented and verified successfully.
Ex. No: 10 Date:
MULTICAST COMMUNICATION
AIM:
To create a network scenario and study the multicast communications using the NS-2
simulator tool.
THEORY:
MULTICAST COMMUNICATION:
When it comes to radio and television broadcasts, it does not matter how many users are
tuned in and using the service. This is not at all the case when sending information over IP
networks. For example, if several different users were able to connect to a live stream, the
standard IP unicast communication would require the sending station to send the corresponding
packets to each recipient separately. Since this would use up the available bandwidth within a
very short period, Multicast routing (also known as IP multicast) was quickly developed and
implemented. It enables the sender to transmit IP data streams to many recipients simultaneously
in a single step.
.
PROGRAM:
# Create nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
set n5 [$ns node]
set n6 [$ns node]
set n7 [$ns node]
There are three fundamental types of IPv4 addresses: unicast, broadcast, and multicast. A unicast
address is designed to transmit a packet to a single destination. A broadcast address is used to
send a datagram to an entire subnetwork. A multicast address is
designed to enable the delivery of datagrams to a set of hosts that have been configured as
members of a multicast group in various scattered subnetworks.
PROCEDURE:
• Set up the network topology by creating node objects, and connecting the nodes with
link objects. If the output queue of a router is implemented as a part of a link, we need to
specify the queue type. In this project, the DropTail queue is used. In some cases, we
may define the layout of the network topology for a better NAM display.
• Define traffic patterns by creating agents, applications, and flows. In NS2, packets are
always sent from one agent to another agent or a group of agents. In addition, we need
to associate these agents with nodes.
• Define the trace files, and place monitors at places in the topology to collect information
about packet flows. NS2 supports two primary monitoring capabilities: traces and
monitors. The traces enable the recording of packets whenever an event such as packet
drop or arrival occurs in a queue or a link. The monitors provide a means for collecting
quantities, such as several packets dropping their several arrived packets in the queue.
The monitor can be used to collect these quantities for all packets or just for a specified
flow (a flow monitor).
• Schedule the simulation by defining the start and stop of the simulation, traffic flows,
tracing, and other events.
• Finally we need to extract useful data from the traces, as you just did use Awk
commands, and feed it to plotting software to get human-readable results. In the
individual tasks below, each task is prefaced with the name of the files you should hand
in concerning that subtask.
$udp0 set dst_port_ 0
set cbr1 [new Application/Traffic/CBR]
$cbr1 attach-agent $udp0
• Streaming multimedia over the internet like live TV and internet radio.
• Video conferencing and webcasts.
• Stock quotes.
• Digital copies of the software
• News.
#post-processing
Thus the C program to create a network scenario and study the multicast
communications using the NS-2 simulator tool has been executed successfully.
Ex. No: 12 Date:
FILE TRANSFER USING TCP/IP PROTOCOL
AIM:
Write a C program to establish a connection between two computers using
TCP/IP socket and to make the Server send the content of the requested file to the Client if the
file is present.
THEORY:
TCP SERVER:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define SIZE 1024
fp = fopen(filename, "w");
while (1) {
n = recv(sockfd, buffer, SIZE, 0);
if (n <= 0){
break;
return;
}
fprintf(fp, "%s", buffer);
bzero(buffer, SIZE);
}
return;
}
int main(){
char *ip = "[Link]";
int port = 8080;
int e;
server_addr.sin_family = AF_INET;
server_addr.sin_port = port;
server_addr.sin_addr.s_addr = inet_addr(ip);
TCP (TRANSMISSION CONTROL PROTOCOL):
A socket is an abstraction through which an application may send and receive data, in pretty
much the same way as opening a file to read and write data.
TCP creates a connection between the source and destination node before transmitting the data
and keeps the connection alive until the communication is active.
In TCP before sending the data it breaks the large data into smaller packets and cares the
integrity of the data at the time of reassembling at the destination node. Major Internet
applications such as the World Wide Web, email, remote administration, and file transfer rely
on TCP.
TCP also offers the facility of retransmission, when a TCP client sends data to the server, it
requires an acknowledgment in return. If an acknowledgment is not received, after a certain
amount of time transmitted data will be lost and TCP automatically retransmits the data.
The communication over the network in TCP/IP model takes place in form of a client-server
architecture. ie, the client begins the communication and establishes a connection with a server.
e = bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(e < 0) {
perror("[-]Error in bind");
exit(1);
}
printf("[+]Binding successfull.\n");
addr_size = sizeof(new_addr);
new_sock = accept(sockfd, (struct sockaddr*)&new_addr, &addr_size);
write_file(new_sock);
printf("[+]Data written in the file successfully.\n");
return 0;
}
OUTPUT:
TCP CLIENT:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#define SIZE 1024
int main(){
char *ip = "[Link]";
int port = 8080;
int e;
int sockfd;
struct sockaddr_in server_addr;
FILE *fp;
char *filename = "[Link]";
server_addr.sin_family = AF_INET;
server_addr.sin_port = port;
server_addr.sin_addr.s_addr = inet_addr(ip);
Bootstrap Protocols
It provides the dynamic methods for identifying the servers and dispense the dynamic methods.
Such as address and initial program load, internet protocol.
To connect the IBM operating system are networking service provider or else configuring the
operating systems consist both the application server or else web server. For the most part, it is
the uses of internet setup data and information to affix.
In reality it is distributed data type for running the hostnames and they are associating the IP
addresses.
The TCP/IP standard are consists the DHCP that will use the central server to manage the
internet protocol addresses in Embedded Programming. In particular dynamic and other
configuration details about the whole network.
REXEC
The remote execution server is having the transmission control protocols or else IP applications
that will allow the client users to submit their remote system. Especially it will enable the
processing of both the programs and also a command to hosting on the internet.
As a matter of fact it enables the stable ad to enlarge their private process over the existing
framework of a public processor. Such as the VPN companies are controlling the networking
traffics while providing the essential security types, i.e. data privacy.
The standard model which it is consists the effectively established in practical problems. In the
final analysis, It allows the cross platforms which it is communicating among the heterogeneous
networking. Open protocols are a unique process using any individual or else organizations.
With attention to both the client-server and also scalable architecture allows the Latest
Networking which is adding a disrupting the latest services. It is assigning the internet protocols
are having an entire computer on the network.
if(e == -1) {
perror("[-]Error in socket");
exit(1);
}
printf("[+]Connected to Server.\n");
fp = fopen(filename, "r");
if (fp == NULL) {
perror("[-]Error in reading file.");
exit(1);
}
send_file(fp, sockfd);
printf("[+]File data sent successfully.\n");
return 0;
}
OUTPUT:
OUTPUT:
RESULT:
Thus the connection between two computers using TCP File Transfer Client-Server was
implemented and verified successfully.
Ex. No: 6 Date:
COMMUNICATION BETWEEN PC’S
AIM:
Write a C program to establish a connection between two computers using TCP/IP
socket and share data between them.
ALGORITHM:
SERVER:
1. Create a TCP socket.
2. Bind the socket to Server address.
3. Listen to the Client.
4. Accept and make the connection.
5. Listen to the Client, read the received/buffered characters and print them.
6. Receive the characters from the console, write the message into the buffer for sending
to Client.
7. Go to Step 5.
CLIENT:
1. Create a TCP socket.
2. Connect the socket to the Server.
3. Receive the characters from the console, write the message into the buffer for sending
to Server.
4. Listen to the Server, read the buffered characters and print them.
5. Go to Step 3.
THEORY:
TCP/IP MODEL:
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
// Driver function
int main()
{
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
Internet Layer:
o An internet layer is the second layer of the TCP/IP model.
o An internet layer is also known as the network layer.
o The main responsibility of the internet layer is to send the packets from any network,
and they arrive at the destination irrespective of the route they take.
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
void func(int sockfd)
{
char buff[MAX];
int n;
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n')
;
write(sockfd, buff, sizeof(buff));
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}
}
int main()
{
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
Thus a connection between two computers using TCP/IP socket was implemented and
verified successfully.
Ex. No: 9 Date:
PACKET SNIFFER
AIM:
Write a C program to implement a basic packet sniffer and identify packet type by
parsing the IP packet header.
THEORY:
PACKET SNIFFING:
In networking, the data is transferred in the form of packets, or small chunks of data.
These packets vary in their format, depending on the network protocol (TCP/IP, UDP, etc.). In
addition to the actual information or data, all packets contain control information designed to
help in the delivery of packets from source to destination. The control information is required as
packets intended to be transferred to a specific node often pass through several nodes in a
network and can end up at the wrong node. The control information includes IP addresses of the
sender and the receiver, packet sequencing information (e.g., packet number), and more to
ensure packets reach the right destination. However, the transfer of packets in a network can get
disrupted due to several issues and network errors.
.
PROGRAM:
#include<netinet/in.h>
#include<errno.h>
#include<netdb.h>
#include<stdio.h> //For standard things
#include<stdlib.h> //malloc
#include<string.h> //strlen
FILE *logfile;
struct sockaddr_in source,dest;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,arp=0,ospf=0,total=0,i,j;
int main()
{
int saddr_size , data_size;
struct sockaddr saddr;
logfile=fopen("[Link]","w");
if(logfile==NULL)
{
printf("Unable to create [Link] file.");
}
printf("Starting...\n");
if(sock_raw < 0)
{
//Print the error with proper message
perror("Socket Error");
return 1;
}
In protocols like TCP/IP, there’s no inherent mechanism to recover the packets lost in
transmission. However, network architects use the protocol in only fault-tolerant networks,
where losses below certain thresholds are acceptable and don’t affect the communication.
However, in protocols like UDP, the sender continues to resend the packet until it receives the
acknowledgment of receipt from the receiver. While it adds reliability to the transmission, it
also increases resource consumption. If left unchecked, it can lead to significant delays in
overall transmission rates. This is where packet sniffers offer a solution.
With a packet sniffer, sometimes also called packet analyser, network administrators can
monitor their network traffic and gain valuable insights about their infrastructure and its
performance. It allows them to measure the traffic flow in a network and also identify which
applications are using the maximum bandwidth.
As the name suggests, it’s a hardware component plugged into a network for packet
sniffing or network analysis purposes. Hardware packet sniffers are commonly used when
network administrators have to analyse or monitor a particular segment of a large network.
With a physical connection, these packet sniffers allow administrators to ensure all packets are
captured without any loss due to routing, filtering, or any other network issue. A hardware
packet sniffer can have the facility to store the packets, or they can be programmed to forward
all captured packers to a centralized location for further analysis.
Software Packet Sniffers are the more common type of packet sniffers used by many
organizations. Every computer or node connects to the network using a Network Interface Card
(NIC), which is generally configured to ignore the packets not addressed to it. However, a
Software Packet Sniffer changes this behavior, so one can receive every bit of network traffic
for analysis. The NIC configuration is known as promiscuous mode. The amount of information
collected depends on whether the packet sniffer is set on filtered or unfiltered mode.
/* This function will parse the packet read and identifies the packet type (ICMP, ARP etc
* based on the IP header protocol type */
switch (iph->protocol)
/* Check the Protocol type */
{
/* ICMP Protocol */
case 1:
++icmp;
break;
case 2:
++igmp;
break;
case 6:
++tcp;
break;
case 17:
/* UDP packet */
++udp;
break;
case 89:
/* OSPF packet */
++ospf;
break;
default:
++others;
break;
}
printf("TCP : %d UDP : %d ICMP : %d IGMP : %d Others : %d Total : %d\r",
tcp, udp, icmp, igmp, others, total);
}
OUTPUT:
RESULT:
Thus the C program to implement a basic packet sniffer and identifying packet type is
implemented and verified successfully.
Ex. No: 9 b.) Date:
PACKET SNIFFER
AIM:
Write a C program to implement a basic packet sniffer and identify packet type by parsing
the IP packet header.
THEORY:
PACKET SNIFFING:
In networking, the data is transferred in the form of packets, or small chunks of data.
These packets vary in their format, depending on the network protocol (TCP/IP, UDP, etc.). In
addition to the actual information or data, all packets contain control information designed to help
in the delivery of packets from source to destination. The control information is required as
packets intended to be transferred to a specific node often pass through several nodes in a network
and can end up at the wrong node. The control information includes IP addresses of the sender
and the receiver, packet sequencing information (e.g., packet number), and more to ensure
packets reach the right destination. However, the transfer of packets in a network can get
disrupted due to several issues and network errors.
.
PROGRAM:
#include<netinet/in.h>
#include<errno.h>
#include<netdb.h>
#include<stdio.h> //For standard things
#include<stdlib.h> //malloc
#include<string.h> //strlen
FILE *logfile;
struct sockaddr_in source,dest;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,arp=0,ospf=0,total=0,i,j;
int main()
{
int saddr_size , data_size;
struct sockaddr saddr;
logfile=fopen("[Link]","w");
if(logfile==NULL)
{
printf("Unable to create [Link] file.");
}
printf("Starting...\n");
if(sock_raw < 0)
{
//Print the error with proper message
perror("Socket Error");
return 1;
}
In protocols like TCP/IP, there’s no inherent mechanism to recover the packets lost in
transmission. However, network architects use the protocol in only fault-tolerant networks, where
losses below certain thresholds are acceptable and don’t affect communication. However, in
protocols like UDP, the sender continues to resend the packet until it receives the
acknowledgment of receipt from the receiver. While it adds reliability to the transmission, it also
increases resource consumption. If left unchecked, it can lead to significant delays in overall
transmission rates. This is where packet sniffers offer a solution.
With a packet sniffer, sometimes also called a packet analyzer, network administrators
can monitor their network traffic and gain valuable insights into their infrastructure and its
performance. It allows them to measure the traffic flow in a network and also identify which
applications are using the maximum bandwidth.
Packet sniffers are programs that intercept the network traffic flowing in and out of a system
through network interfaces. So if you are browsing the internet then traffic is flowing and a
packet sniffer would be able to catch it in the form of packets and display them for whatever
reasons required. Packet sniffers are used for various needs like analyzing protocols, monitoring
networks, and assessing the security of a network. Wireshark for example is the most popular
packet sniffer out there and is available for all platforms. It GUI based and very easy to use.
In this post, we are going to talk about how to code and make our packet sniffer in C and on the
Linux platform. By Linux, it means that the code sample shown here would work only on Linux
and not windows. Packet sniffers can be coded by either using sockets API provided by the
kernel, or by using some packet capture library like libpcap. In this tutorial we shall be covering
the first method, that is by using sockets.
As the name suggests, it’s a hardware component plugged into a network for packet
sniffing or network analysis purposes. Hardware packet sniffers are commonly used when
network administrators have to analyze or monitor a particular segment of a large network. With
a physical connection, these packet sniffers allow administrators to ensure all packets are captured
without any loss due to routing, filtering, or any other network issue. A hardware packet sniffer
can have the facility to store the packets, or they can be programmed to forward all captured
packers to a centralized location for further analysis.
Software Packet Sniffers are the more common type of packet sniffers used by many
organizations. Every computer or node connects to the network using a Network Interface Card
(NIC), which is generally configured to ignore the packets not addressed to it. However, a
Software Packet Sniffer changes this behavior, so one can receive every bit of network traffic for
analysis. The NIC configuration is known as promiscuous mode. The amount of information
collected depends on whether the packet sniffer is set in filtered or unfiltered mode.
while(1)
{
saddr_size = sizeof saddr;
//Receive a packet
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , (socklen_t*)&saddr_size);
if(data_size <0 )
{
printf("Recvfrom error , failed to get packets\n");
return 1;
}
ProcessPacket(buffer , data_size);
}
close(sock_raw);
printf("Finished");
return 0;
}
/* This function will parse the packet read and identifies the packet type (ICMP, ARP, etc
* based on the IP header protocol type */
switch (iph->protocol)
/* Check the Protocol type */
{
/* ICMP Protocol */
case 1:
++icmp;
break;
case 2:
++igmp;
break;
case 6:
++tcp;
break;
case 17:
/* UDP packet */
++udp;
break;
case 89:
/* OSPF packet */
++ospf;
break;
default:
++others;
break;
}
BENEFITS OF PACKET SNIFFING:
memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iph->saddr;
memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;
fprintf(logfile,"\n");
fprintf(logfile,"IP Header\n");
fprintf(logfile," |-IP Version : %d\n",(unsigned int)iph->version);
fprintf(logfile," |-IP Header Length : %d DWORDS or %d Bytes\n",(unsigned int)iph-
>ihl,((unsigned int)(iph->ihl))*4);
fprintf(logfile," |-Type Of Service : %d\n",(unsigned int)iph->tos);
fprintf(logfile," |-IP Total Length : %d Bytes(Size of Packet)\n",ntohs(iph->tot_len));
fprintf(logfile," |-Identification : %d\n",ntohs(iph->id));
//fprintf(logfile," |-Reserved ZERO Field : %d\n",(unsigned int)iphdr-
>ip_reserved_zero);
//fprintf(logfile," |-Dont Fragment Field : %d\n",(unsigned int)iphdr-
>ip_dont_fragment);
//fprintf(logfile," |-More Fragment Field : %d\n",(unsigned int)iphdr-
>ip_more_fragment);
fprintf(logfile," |-TTL : %d\n",(unsigned int)iph->ttl);
fprintf(logfile," |-Protocol : %d\n",(unsigned int)iph->protocol);
fprintf(logfile," |-Checksum : %d\n",ntohs(iph->check));
fprintf(logfile," |-Source IP : %s\n",inet_ntoa(source.sin_addr));
fprintf(logfile," |-Destination IP : %s\n",inet_ntoa(dest.sin_addr));
}
fprintf(logfile,"\n\n********************TCP Packet********************\n");
print_ip_header(Buffer,Size);
fprintf(logfile,"\n");
fprintf(logfile,"TCP Header\n");
fprintf(logfile," |-Source Port : %u\n",ntohs(tcph->source));
fprintf(logfile," |-Destination Port : %u\n",ntohs(tcph->dest));
fprintf(logfile," |-Sequence Number : %u\n",ntohl(tcph->seq));
fprintf(logfile," |-Acknowledge Number : %u\n",ntohl(tcph->ack_seq));
fprintf(logfile," |-Header Length : %d DWORDS or %d BYTES\n" ,(unsigned
int)tcph->doff,(unsigned int)tcph->doff*4);
//fprintf(logfile," |-CWR Flag : %d\n",(unsigned int)tcph->cwr);
//fprintf(logfile," |-ECN Flag : %d\n",(unsigned int)tcph->ece);
fprintf(logfile," |-Urgent Flag : %d\n",(unsigned int)tcph->urg);
fprintf(logfile," |-Acknowledgement Flag : %d\n",(unsigned int)tcph->ack);
fprintf(logfile," |-Push Flag : %d\n",(unsigned int)tcph->psh);
fprintf(logfile," |-Reset Flag : %d\n",(unsigned int)tcph->rst);
fprintf(logfile," |-Synchronise Flag : %d\n",(unsigned int)tcph->syn);
fprintf(logfile," |-Finish Flag : %d\n",(unsigned int)tcph->fin);
fprintf(logfile," |-Window : %d\n",ntohs(tcph->window));
fprintf(logfile," |-Checksum : %d\n",ntohs(tcph->check));
fprintf(logfile," |-Urgent Pointer : %d\n",tcph->urg_ptr);
fprintf(logfile,"\n");
fprintf(logfile," DATA Dump ");
fprintf(logfile,"\n");
fprintf(logfile,"IP Header\n");
PrintData(Buffer,iphdrlen);
fprintf(logfile,"TCP Header\n");
PrintData(Buffer+iphdrlen,tcph->doff*4);
fprintf(logfile,"Data Payload\n");
PrintData(Buffer + iphdrlen + tcph->doff*4 , (Size - tcph->doff*4-iph->ihl*4) );
fprintf(logfile,"\n#######################################################");
}
fprintf(logfile,"\n\n********************UDP Packet**********************\n");
print_ip_header(Buffer,Size);
fprintf(logfile,"\nUDP Header\n");
fprintf(logfile," |-Source Port : %d\n" , ntohs(udph->source));
fprintf(logfile," |-Destination Port : %d\n" , ntohs(udph->dest));
fprintf(logfile," |-UDP Length : %d\n" , ntohs(udph->len));
fprintf(logfile," |-UDP Checksum : %d\n" , ntohs(udph->check));
fprintf(logfile,"\n");
fprintf(logfile,"IP Header\n");
PrintData(Buffer , iphdrlen);
fprintf(logfile,"UDP Header\n");
PrintData(Buffer+iphdrlen , sizeof udph);
fprintf(logfile,"Data Payload\n");
PrintData(Buffer + iphdrlen + sizeof udph ,( Size - sizeof udph - iph->ihl * 4 ));
fprintf(logfile,"\n#######################################################");
}
fprintf(logfile,"\n\n*******************ICMP Packet**********************\n");
print_ip_header(Buffer , Size);
fprintf(logfile,"\n");
fprintf(logfile,"ICMP Header\n");
fprintf(logfile," |-Type : %d",(unsigned int)(icmph->type));
fprintf(logfile,"IP Header\n");
PrintData(Buffer,iphdrlen);
fprintf(logfile,"UDP Header\n");
PrintData(Buffer + iphdrlen , sizeof icmph);
fprintf(logfile,"Data Payload\n");
PrintData(Buffer + iphdrlen + sizeof icmph , (Size - sizeof icmph - iph->ihl * 4));
fprintf(logfile,"\n#######################################################");
}
fprintf(logfile," ");
Thus the C program to implement a basic packet sniffer and identifying packet type is
implemented and verified successfully.