0% found this document useful (0 votes)
26 views52 pages

443 CN File

Uploaded by

shivam.nexus07
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views52 pages

443 CN File

Uploaded by

shivam.nexus07
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

DELHI TECHNOLOGICAL UNIVERSITY

(Formerly Delhi College of Engineering)


Shahbad Daulatpur, Bawana Road, Delhi 110042

DEPARTMENT OF COMPUTER SCIENCE AND


ENGINEERING

CO-306
COMPUTER NETRWORKS
LABORATORY FILE

SUBMITTED TO: SUBMITTED BY:


Dr. Sanjay Kumar Shivam Awasthi
Shubham Shandilya
2K21/CO/443
2K21/CO/457
INDEX

S. No. Experiment Page Signature

1. Introduction to computer network 3-5

2. Write a program to implement different framing 6-13


techniques:
1) Bit Stuffing
2) Byte Stuffing
3) Character Stuffing

3. Write a program to Implement Cyclic Redundancy 14-18


Check
4. Write a program to Implement stop and wait protocol. 19-23
5. Write a program to implement sliding window 24-28
protocol.
6. Write a program to implement show the Network ID, 29-39
Host ID and Class of the address. Also implement
Subnetting and Supernetting taking user inputs.
7. Write a program for shortest path using Dijkstra 40-43
algorithm.

8. Write a program for Link State Routing 44-47

9. Write a program for Distance vector routing 48-53


EXPERIMENT-1
Aim: Introduction to Computer Networks.
Theory:
A computer network is a system that connects numerous independent computers in order to
share information (data) and resources.
A computer network consists of various kinds of nodes. Servers, networking hardware,
personal computers, and other specialized or general-purpose hosts can all be nodes in a
computer network. Host names and network addresses are used to identify them.
Types of Computer Networks
Division Based on the Communication Medium
 Wired Network: Communication done in a wired medium. Copper wire, twisted pair,
or fiber optic cables are all options. A wired network employs wires to link devices to
the Internet or another network, such as laptops or desktop PCs.
Types of Ethernet Cables:
1. Coaxial Cables: A coaxial cable is used to carry high-frequency
electrical signals with low losses. It is usually used in telephone
systems, cable TV, etc.
2. Twisted Pair Cable: Twisted pair is a copper wire cable in which two
insulated copper wires are twisted around each other to reduce
interference or crosstalk.
3. Fiber Optic Cable: Fiber optic cables use optical fibers which are
made of glass cores surrounded by several layers of cladding material
usually made of PVC or Teflon, it transmits data in the form of light
signals due to which there are no interference issues in fiber optics.
 Wireless Network: “Wireless” means without wire, media that is made up of
electromagnetic waves (EM Waves) or infrared waves. Antennas or sensors will be
present on all wireless devices. For data or voice communication, a wireless network
uses radio frequency waves rather than wires
Division Based on Area Covered
 Local Area Network (LAN): A LAN is a network that covers an area of around 10
kilometers. For example, a college network or an office network. Depending upon the
needs of the organization, a LAN can be a single office, building, or Campus.
 Metropolitan Area Network (MAN): MAN refers to a network that covers an entire
city. For example: consider the cable television network.
 Wide Area Network (WAN): WAN refers to a network that connects countries or
continents. For example, the Internet allows users to access a distributed system called
www from anywhere around the globe.
Network Topology
The structure of the network and how each component is connected to the others are defined
by the network topology.
Bus Topology
Every computer and network device is connected to a single cable in a bus topology network.
Linear Bus topology is defined as having exactly two terminals.

Ring Topology
The topology is named ring topology because one computer is connected to another, with the
final one being connected to the first. Exactly two neighbors for each device. A signal is
passed along the ring in one direction. Each ring incorporates a repeater.

Star Topology
Each device in a star topology has a dedicated point-to-point link to a central controller,
which is commonly referred to as the HUB. There is no direct connection between the
devices. Traffic between the devices is not allowed in this topology. As an exchange, the
controller is used.
Example: Used in high-speed LANs

Mesh Topology
Every device in a mesh topology has dedicated point-to-point connectivity to every other
device. The term “dedicated” refers to the fact that the link exclusively transports data
between the two devices it links.
Example: connection of telephone regional office in which each regional office needs to be
connected to every other regional office.
OSI MODEL OF COMPUTER NETWORKS
The OSI (Open Systems Interconnection) model is a conceptual framework that standardizes
the functions of a telecommunication or computing system into seven abstraction layers.
These layers are:
1. Physical Layer: Deals with the physical connection of devices and the transmission
of raw data over a physical medium.
2. Data Link Layer: Provides error-free transmission of data frames over the physical
layer, addressing issues like framing, error detection, and flow control.
3. Network Layer: Focuses on routing packets from the source to the destination across
multiple networks, handling addressing, routing, and traffic control.
4. Transport Layer: Ensures end-to-end communication, segmenting and reassembling
data, providing error recovery, flow control, and congestion avoidance.
5. Session Layer: Establishes, maintains, and synchronizes the interactions (sessions)
between communicating systems.
6. Presentation Layer: Handles data translation, encryption, compression, and
formatting to ensure that data can be understood by the application layer.
7. Application Layer: Provides network services directly to user applications,
facilitating communication between end-user applications.
Each layer in the OSI model performs specific functions, and the model serves as a guideline
for developing and understanding network protocols and systems, fostering interoperability
between different vendors' hardware and software.

Learning Outcome:
This gives us a basic overview about computer network, networking devices, types of network and
network topology and the OSI Model of Computer Network
EXPERIMENT-2

Aim : To implement different framing techniques:


1) Bit Stuffing
2) Byte Stuffing
3) Character Stuffing

Theory :
Data link layer is responsible for something called Framing, which is the division of stream of
bits from network layer into manageable units (called frames). Each frame consists of sender's
address and a destination address. The destination address defines where the packet is to go
and the sender's address helps the recipient acknowledge the receipt. Frames could be of fixed
size or variable size. In fixed-size framing, there is no need for defining the boundaries of the
frames as the size itself can be used to define the end of the frame and the beginning of the next
frame. But, in variable-size framing, we need a way to define the end of the frame and the
beginning of the next frame. To separate one frame from the next, an 8-bit (or 1-byte) flag is
added at the beginning and the end of a frame. But the problem with that is, any pattern used
for the flag could also be part of the information. So, we use stuffing. Security and Error
detection are the most prominent features that are to be provided by any application which
transfers data from one end to the other end. One of such a mechanism in tracking errors which
may add up to the original data during transfer is known as Stuffing.
1. Bit Stuffing In bit stuffing, to limit the number of consecutive bits of the same
value(i.e., binary value) in the data to be transmitted. A bit of the opposite value is
inserted after the maximum allowed number of consecutive bits. High Level Data Link
Control (HDLC) is based on bit stuffing. e.g. After 5 consecutive 1-bits, a 0-bit is
stuffed.
• Start
• Initialize the array for transmitted stream with the special bit pattern 0111 1110 which
indicates the beginning of the frame.
• Get the bit stream to be transmitted in the array.
• Check for five consecutive ones and if they occur, stuff a bit 0.
• Display the data transmitted as it appears on the data line after appending 0111 1110 at
the end.
• For de-stuffing, copy the transmitted data to another array after detecting the stuffed
bits
• Display the received bit stream
• Stop

2. Byte Stuffing A byte (usually escape character (ESC)), which has a predefined bit
pattern is added to the data section of the frame when there is a character with the same
pattern as the flag. Whenever the receiver encounters the ESC character, it removes from the
data section and treats the next character as data, not a flag. Point to Point Protocol (PPP) is
based on byte stuffing.
• Start
• Append 01111110 at the beginning of the string
• Check the data if character is present; if character 01111110 is present in the string
(example 01011111101) insert another 01111110 in the string.
• Transmit 01111110 at the end of the string
• Display the string
• Stop
3. Character Stuffing In character stuffing, DLESTX and DLEETX are used to
denote the start and end of the character data with some constraints imposed on repetition
of characters as shown in the experiment.
• Start
• Append DLE STX at the beginning of the string
• Check the data if character is present; if character DLE is present in toe string (example
DOODLE) insert another DLE in the string (ex: DOODLEDLE)
• Transmit DLE ETX at the end of the string
• Display the string
• Stop

Code :
 Bit Stuffing :
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
int a[50];
int i,j,k,n,c,pos;
c=0;
cout<<"Enter no. of bits\n";
cin>>n;
cout<<"Enter the bits\n";
for(i=0;i<n;i++)
cin>>a[i];
for(i=0;i<n;i++)
{

if(a[i]==1)
{
c++;
if(c==5)
{
pos=i+1;
c=0;
for(j=n-1;j>=pos;j--)
{
k=j+1;
a[k] = a[j];
}
a[pos] = 0;
n++;
}
}
else
{
c=0;
}
}
cout<<"data after stuffing\n";
for(i=0;i<n;i++)
cout<<a[i];
return 0;
}

 Byte Stuffing :

#include<stdio.h>
using namespace std;
int main()
{
int i,j,k,data[100],n;
printf("Enter no. of bits:\n");
scanf("%d",&n);

printf("enter data to be sent:\n");

for(i=0;i<n;i++)
scanf("%d",&data[i]);

printf("the array entered is \n");


for(i=0;i<n;i++)
printf("%d",data[i]);

printf("\n");
for(i=0;i<n;i++)
{
if(data[i]==0 && data[i+1]==1 && data[i+2]==1 && data[i+3]==1 &&
data[i+4]==1 &&
data[i+5]==1 && data[i+6]==1 && data[i+7]==0)
{

i=i+8;
for(j=i+8;j>=i;j--)
{
data[j+8]=data[j];
n++;
}
for(k=0;k<8;k++)
{
if(k==0 || k==7)
data[i]=0;
else
data[i]=1;
i++;
}
}
}
printf("the byte stuffed array is:\n");
for(i=0;i<n;i++)
printf("%d",data[i]);
printf("\n");
return 0; }
 Character Stuffing :
#include <iostream>
using namespace std;
int main() {
char s[50], data[100];
int i,j,n,m;
cout<<"Enter Size"<<endl;
cin>>n;
cout<<”Enter Data”<<endl;
for(int i=0;i<n;i++) {
cin>>s[i]; }
data[0] = 'D';
data[1] = 'L';
data[2] = 'S';
data[3] = 'T';
data[4] = 'E';
data[5] = 'X';
j = 6;
m = 6;
for(int i=0;i<n;i++) {
if(s[i]=='D' && s[i+1]=='L' && s[i+2]=='E') {
data[j++] = 'D';
data[j++] = 'L';
data[j++] = 'E';
data[j++] = 'D';
data[j++] = 'L';
data[j++] = 'E';
i+=2;
m+=6; }
else{
data[j++]=s[i];
m++; } }
data[m++] = 'D';
data[m++] = 'L';
data[m++] = 'E';
data[m++] = 'E';
data[m++] = 'T';
data[m++] = 'X';
cout<<endl;
for(int i = 0;i<m;i++)cout<<data[i]<<" ";
cout<<endl;
return 0; }

Output :
1. Bit Stuffing :

2. Byte Stuffing :

3. Character Stuffing :
Learning Outcomes :
We learnt about stuffing and different stuffing techniques and their implementation and their
uses in computer networks.
The Data Link Layer is the second layer in the OSI model, above the Physical Layer, which
ensures that the error free data is transferred between the adjacent nodes in the network. It
breaks the datagrams passed down by above layers and convert them into frames ready for
transfer. This is called Framing. It provides two main functionalities
a) Reliable data transfer service between two peer network layers
b) Flow Control mechanism which regulates the flow of frames such that data congestion is
not there at slow receivers due to fast senders.
Bit stuffing is the process of inserting non-information bits into data to break up bit patterns
to affect the synchronous transmission of information. Character stuffing has the Same idea
as bit-stuffing, but operates on bytes instead of bits. It Uses reserved characters to indicate the
start and end of a frame. For instance, use the two-character sequence DLE STX (Data-Link
Escape, Start of Text) to signal the beginning of a frame, and the sequence DLE ETX (End of
Text) to flag the frame's end.
EXPERIMENT-3

AIM: Implement Cyclic Redundancy Check

THEORY: CRC or Cyclic Redundancy Check is a method of detecting accidental


changes/errors in the communication channel.
CRC uses Generator Polynomial which is available on both sender and receiver side. An
example generator polynomial is of the form like x + x + 1. This generator polynomial
3

represents key 1011. Another example is x + 1 that represents key 101.


2

n: Number of bits in data to be sent from sender side.


k: Number of bits in the key obtained
from generator polynomial.
Sender Side (Generation of Encoded Data from Data and Generator
Polynomial (or Key)):
1. The binary data is first augmented by adding k-1 zeros in the end of the data
2. Use modulo-2 binary division to divide binary data by the key and store
remainder of division.
3. Append the remainder at the end of the data to form the encoded data and send the
same
Receiver Side (Check if there are errors introduced in transmission)
Perform modulo-2 division again and if the remainder is 0, then there are no errors.
Modulo 2 Division:
The process of modulo-2 binary division is the same as the familiar division process we use
for decimal numbers. Just that instead of subtraction, we use XOR here.
 In each step, a copy of the divisor (or data) is XORed with the k bits of the dividend
(or key).
 The result of the XOR operation (remainder) is (n-1) bits, which is used for the next
step after 1 extra bit is pulled down to make it n bits long.
 When there are no bits left to pull down, we have a result. The (n-1)-bit remainder
which is appended at the sender side.
Illustration:
Example 1 (No error in transmission):
Data word to be sent - 100100
Key - 1101 [ Or generator polynomial x3 + x2 + 1]
Sender Side:
Therefore, the remainder is 001 and hence the encoded data sent is 100100001.
Receiver Side:
Code word received at the receiver side 100100001
Therefore, the remainder is all zeros. Hence, the data received has no error.
Example 2: (Error in transmission)
Data word to be sent - 100100
Key - 1101
Sender Side: Therefore, the remainder is 001 and hence the code word sent is 100100001.
Receiver Side: Let there be an error in transmission media
Code word received at the receiver side – 100000001
Since the remainder is not all zeroes, the error
is detected at the receiver side.
Code:
#include <bits/stdc++.h>
using namespace std;
string xor1(string a, string b){
string result = "";
int n = b.length();
for (int i = 1; i < n; i++) {
if (a[i] == b[i])
result += "0";
else
result += "1";
}
return result;
}
string mod2div(string dividend, string divisor)
{
int pick = divisor.length();
string tmp = dividend.substr(0, pick);
int n = dividend.length();
while (pick < n) {
if (tmp[0] == '1'){
tmp = xor1(divisor, tmp) + dividend[pick];
}
else{
tmp = xor1(std::string(pick, '0'), tmp)
+ dividend[pick];
}
pick += 1;
}
if (tmp[0] == '1')
tmp = xor1(divisor, tmp);
else
tmp = xor1(std::string(pick, '0'), tmp);

return tmp;
}
void encodeData(string data, string key)
{
int l_key = key.length();
string appended_data
= (data + std::string(l_key - 1, '0'));
string remainder = mod2div(appended_data, key);
string codeword = data + remainder;
cout << "Remainder : " << remainder << "\n";
cout << "Encoded Data (Data + Remainder) :" << codeword
<< "\n";
}
void receiver(string data, string key)
{
string currxor
= mod2div(data.substr(0, key.size()), key);
int curr = key.size();
while (curr != data.size()) {
if (currxor.size() != key.size()) {
currxor.push_back(data[curr++]);
}
else {
currxor = mod2div(currxor, key);
}
}
if (currxor.size() == key.size()) {
currxor = mod2div(currxor, key);
}
if (currxor.find('1') != string::npos) {
cout << "there is some error in data" << endl;
}
else {
cout << "correct message received" << endl;
}
}
int main ()
{

string data = "100100";


string key = "1101";
cout << "Sender side..." << endl;
encodeData(data, key);
cout << "\nReceiver side..." << endl;
receiver(data+mod2div(data+std::string(key.size() - 1, '0'),key), key);

return 0;
}

OUTPUT:
Sender side...
Remainder: 001
Encoded Data (Data + Remainder) :100100001
Receiver side...
correct message received
LEARNING OUTCOMES:

DISCUSSION: During transmission, digital signals suffer from noise that can introduce
errors in the binary bits travelling from sender to receiver. That means a 0 bit may change to
1 or a 1 bit may change to 0. Cyclic Redundancy Check (CRC) is based on binary division. In
CRC, a sequence of redundant bits, called cyclic redundancy check bits, are appended to the
end of 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 divided by the
same number.
FINDINGS AND LEARNINGS: We learnt about CRC (Cyclic Redundancy Check) and its
implementation and significance in computer networks
EXPERIMENT-4
AIM: Implement stop and wait protocol.
THEORY:
Stop-and-wait protocol, commonly known as the alternating bit protocol, refers to a
communication technique used to transmit data between two linked devices. It makes sure
that packets are received in the right order, and that data is not lost as a result of dropped
packets.

Working of Stop and Wait Protocol

The stop and wait protocol’s operation is depicted in the above figure. The sender sends the
packet, referred to as a data packet if there is a sender and a receiver. After receiving a data
packet, the receiver sends an acknowledgement. Without receiving acknowledgement for the
first packet, the sender won’t send the second packet. The sender sends the subsequent packet
after receiving the acknowledgement.
This procedure keeps going until all of the packets have been sent. The stop and wait
protocol’s main benefit is simplicity, but there are some drawbacks as well. For instance, if
1000 data packets need to be delivered, they cannot all be sent at once since this protocol
only sends one packet at a time.
C++ implementation of stop and wait protocol:
#include <iostream>
#include <time.h>
#include <cstdlib>
using namespace std;
class timer
{
private:
unsigned long begTime;

public:
void start()
{
begTime = clock();
}
unsigned long elapsedTime()
{
return ((unsigned long)clock() - begTime) /
CLOCKS_PER_SEC;
}
bool isTimeout(unsigned long seconds)
{
return seconds >= elapsedTime();
}
};

int main()
{
int n;
int frames[20];
cout << "\nEnter number of frames : ";
cin >> n;
cout << "\nEnter frames :" << endl;
for (int i = 0; i < n; i++)
cin >> frames[i];

unsigned long seconds = 5;


srand(time(NULL));
timer t;
cout << "Frames to be sent by the user : ";
for (int i = 0; i < n; i++)
cout << frames[i] << " ";

int count = 0;
bool delay = false;
cout << endl
<< "\nSender\t\t\t\t\tReceiver" << endl;

do
{
bool timeout = false;
cout << "Sending Frame : " << frames[count];
cout.flush();
cout << "\t\t";
t.start();
if (rand() % 2)
{
int to = 24600 + rand() % (64000 - 24600) + 1;
for (int i = 0; i < 64000; i++)
for (int j = 0; j < to; j++)
{
}
}
if (t.elapsedTime() <= seconds)
{
cout << "Frame received is : " << frames[count] << " ";
if (delay)
{
cout << "Duplicate";
delay = false;
}
cout << endl;
count++;
}
else
{
cout << "---" << endl;
cout << "Timeout" << endl;
timeout = true;
}
t.start();
if (rand() % 2 || !timeout)
{
int to = 24600 + rand() % (64000 - 24600) + 1;
for (int i = 0; i < 64000; i++)
for (int j = 0; j < to; j++)
{
}
if (t.elapsedTime() > seconds)
{
cout << "Delayed Acknowledgment" << endl;
count--;
delay = true;
}
else if (!timeout)
cout << "Got Acknowledgment of frame :" << frames[count] - 1 << endl;
}
} while (count != n);
return 0;
OUTPUT

Learning Outcome:
1. We learnt about stop and wait protocol and its implementation and significance in computer
networks.
2. From this experiment students will understand the operation of a packet- based stop-and-
wait Student will able to illustrate the mechanism of flow control Stop and Wait protocol .
EXPERIMENT-5
AIM: Write a program to implement Sliding window protocol.
THEORY:
Sliding Window Technique is a method used to efficiently solve problems that involve
defining a window or range in the input data (arrays or strings) and then moving that window
across the data to perform some operation within the window. This technique is commonly
used in algorithms like finding subarrays with a specific sum, finding the longest substring
with unique characters, or solving problems that require a fixed-size window to process
elements efficiently.

Types of sliding Window Protocol :

Go – back – N ARQ:
Go – Back – N ARQ provides for sending multiple frames before receiving the
acknowledgment for the first frame. It uses the concept of sliding window, and so is also
called sliding window protocol. The frames are sequentially numbered and a finite number of
frames are sent. If the acknowledgment of a frame is not received within the time period, all
frames starting from that frame are retransmitted.

Selective Request ARQ:


This protocol also provides for sending multiple frames before receiving the acknowledgment
for the first frame. However, here only the erroneous or lost frames are retransmitted, while
the good frames are received and buffered.
C++ implementation of Go – back – N ARQ:
#include<bits/stdc++.h>
#include<ctime>
#define ll long long int
using namespace std;
void transmission(ll & i, ll & N, ll & tf, ll & tt) {
while (i <= tf) {
int z = 0;
for (int k = i; k < i + N && k <= tf; k++) {
cout << "Sending Frame " << k << "..." << endl;
tt++;
}
for (int k = i; k < i + N && k <= tf; k++) {
int f = rand() % 2;
if (!f) {
cout << "Acknowledgment for Frame " << k << "..." << endl;
z++;
} else {
cout << "Timeout!! Frame Number : " << k << " Not Received" << endl;
cout << "Retransmitting Window..." << endl;
break;
}
}
cout << "\n";
i = i + z;
}
}
int main() {
ll tf, N, tt = 0;
srand(time(NULL));
cout << "Enter the Total number of frames : ";
cin >> tf;
cout << "Enter the Window Size : ";
cin >> N;
ll i = 1;
transmission(i, N, tf, tt);
cout << "Total number of frames which were sent and resent are : " << tt <<
endl;
return 0;
}

C++ implementation of Selective Request ARQ:


#include<iostream>
using namespace std;
int main()
{
int w,i,f,frames[50];
cout<<"Enter window size: ";
cin>>w;
cout<<"\nEnter number of frames to transmit: ";
cin>>f;
cout<<"\nEnter "<<f<<" frames: ";
for(i=1;i<=f;i++)
cin>>frames[i];
cout<<"\nWith sliding window protocol the frames will be sent in the following
manner (assuming no corruption of frames)\n\n";
cout<<"After sending "<<w<<" frames at each stage sender waits for acknowledgement
sent by the receiver\n\n";
for(i=1;i<=f;i++)
{
if(i%w==0)
{
cout<<frames[i]<<"\n";
cout<<"Acknowledgement of above frames sent is received by sender\n\n";
}
else
cout<<frames[i]<<" ";
}
if(f%w!=0)
cout<<"\nAcknowledgement of above frames sent is received by sender\n";
return 0;
}

Learning Outcome:
We learnt about sliding window protocol and its implementation and significance in
computer networks.
EXPERIMENT-6
AIM: To implement a program in c to show the Network ID, Host ID and Class of the
address. Also implement Subnetting and Supernetting taking user inputs.

THEORY:-
Class:
IP addresses are divided into 5 classes namely, Class A, Class B, Class C, Class D, and Class
E. This concept came in around the 1980s. Where
 Class A is generally used for big networks such as the ISP networks.
 Class B is used for medium to large networks like some big organizations.
 Class C addresses are generally used for smaller networks.
 Class D addresses are used for Multicasting.
 Class E addresses are reserved addresses and they are used for experimental purposes.

Class A: 1.0.0.0 to 127.255.255.255


Class B: 128.0.0.0 to 191.255.255.255
Class C: 192.0.0.0 to 223.255.255.255
Class D: 224.0.0.0 to 239.255.255.255
Class E: 240.0.0.0 to 255.255.255.255
Network ID:-
A network ID or NetID is the fragment of IP address that classifies the network for a
specified host i.e., it tells us which network the host belongs to, generally comprised of one to
up to four octets in dotted-decimal representation. In dotted-decimal representation, an IP
address is divided into four octets, and based on which class the IP address belongs to its
octets are further divided into network ID and HOST ID.

Host ID:-
It is the fragment of an IP address that uniquely classifies a host on a specified TCP/IP
network. A host ID can be found simply by ANDing the IP address in binary form with its
respective default subnet mask (in binary form).

For Example, the IP address is 198.162.30.4 which means it belongs to class C, so its default
subnet mask will be 255.255.255.0; Now applying AND on both, it will give the host ID
0.0.0.4 and network ID 198.162.30.0.
Subnetting:-
It is the procedure to divide the network into sub-networks or small networks, these smaller
networks are known as subnets. The subnet is also defined as an internal address made up of
a combination of a small network and host segments. In a subnet, a few bits from the host
portion are used to design small-sized subnetworks from the original network. In subnetting,
network bits are converted into host bits.
Supernetting:-
It is the procedure to combine small networks into larger spaces. In subnetting, Network
addresses’ bits are increased. on the other hand, in supernetting, Host addresses’ bits are
increased. Super netting is implemented via Classless interdomain routing.

PROCEDURE:-
Algorithm for finding Network ID, Host ID and class :-
1. Parse the IP Address: Split the IP address into its octets (each segment separated by a
period).
2. Determine the IP Address Class: Based on the value of the first octet, determine the
class of the IP address. The classes are as follows:
 Class A: 0.0.0.0 to 127.255.255.255
 Class B: 128.0.0.0 to 191.255.255.255
 Class C: 192.0.0.0 to 223.255.255.255
 Class D: 224.0.0.0 to 239.255.255.255 (reserved for multicasting)
 Class E: 240.0.0.0 to 255.255.255.255 (reserved for experimental use)
3. Determine the Network and Host Bits: Depending on the class of the IP address, the
number of bits used for the network and host parts vary. For example:
 Class A: Network (8 bits), Host (24 bits)
 Class B: Network (16 bits), Host (16 bits)
 Class C: Network (24 bits), Host (8 bits)
4. Calculate Network ID and Host ID: Use the network bits to determine the network ID
and the remaining bits for the host ID.
Code for finding Network ID, Host ID and class :-
#include<stdio.h>
#include<string.h>
char findClass(char str[])
{
char arr[4];
int i = 0;
while (str[i] != '.')
{
arr[i] = str[i];
i++;
}
i--;
int ip = 0, j = 1;
while (i >= 0)
{
ip = ip + (str[i] - '0') * j;
j = j * 10;
i--;
}
if (ip >=1 && ip <= 126)
return 'A';
else if (ip >= 128 && ip <= 191)
return 'B';
else if (ip >= 192 && ip <= 223)
return 'C';
else if (ip >= 224 && ip <= 239)
return 'D';
else
return 'E';
}
void separate(char str[], char ipClass)
{
char network[12], host[12];
for (int k = 0; k < 12; k++)
network[k] = host[k] = '\0';
if (ipClass == 'A')
{
int i = 0, j = 0;
while (str[j] != '.')
network[i++] = str[j++];
i = 0;
j++;
while (str[j] != '\0')
host[i++] = str[j++];
printf("Network ID is %s\n", network);
printf("Host ID is %s\n", host);
}
else if (ipClass == 'B')
{
int i = 0, j = 0, dotCount = 0;
while (dotCount < 2)
{
network[i++] = str[j++];
if (str[j] == '.')
dotCount++;
}
i = 0;
j++;
while (str[j] != '\0')
host[i++] = str[j++];
printf("Network ID is %s\n", network);
printf("Host ID is %s\n", host);
}
else if (ipClass == 'C')
{
int i = 0, j = 0, dotCount = 0;
while (dotCount < 3)
{
network[i++] = str[j++];
if (str[j] == '.')
dotCount++;
}
i = 0;
j++;
while (str[j] != '\0')
host[i++] = str[j++];
printf("Network ID is %s\n", network);
printf("Host ID is %s\n", host);
}
else
printf("In this Class, IP address is not"
" divided into Network and Host ID\n");
}
int main(){
char str[20];
printf("Give
an IP
address: ");
scanf("%s",str);
char ipClass = findClass(str);
printf("Given IP address is %s\n",str);
printf("Given IP address belongs to Class %c\n",
ipClass);
separate(str, ipClass);
return 0;
}
output:-

Subnetting Algorithm:-
1. Determine the Required Number of Subnets:
 Calculate the number of subnets needed based on the requirements of your
network (e.g., number of departments, segments, etc.).
2. Determine the Number of Bits for Subnetting:
 Choose the appropriate number of bits for subnetting based on the number of
required subnets.
 Calculate the number of bits required as n = ceil(log2(number_of_subnets)).
3. Subnet the IP Address Space:
 Divide the IP address space into subnet ranges using the chosen number of
bits.
 Each subnet will have its own network ID and range of host IDs.
 Calculate the subnet mask based on the number of subnet bits.
4. Assign IP Addresses to Subnets:
 Allocate IP addresses from each subnet range to the devices in the
corresponding subnet.
Supernetting Algorithm:-
1. Identify Contiguous IP Address Ranges:
 Determine the contiguous IP address ranges that you want to combine into a
single supernet.
 Ensure that the ranges have the same subnet mask.
2. Determine the Common Prefix Bits:
 Find the common prefix bits among the IP address ranges.
 Count the number of common bits to determine the supernet prefix length.
3. Combine IP Address Ranges:
 Create a single supernet range that encompasses all the IP address ranges.
 The supernet's network ID will be determined by the common prefix bits, and
the range of host IDs will cover all the combined IP address ranges.
4. Allocate IP Addresses:
 Assign IP addresses from the supernet range to the devices in your network.
Code for subnetting and supernetting:-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void ipToBinary(char *ip, int binary[32]) {
int i = 0;
char *token = strtok(ip, ".");
while (token != NULL) {
int num = atoi(token);
for (int j = 7; j >= 0; j--) {
binary[i++] = (num >> j) & 1;
}
token = strtok(NULL, ".");
}
}
void printBinaryIP(int binary[32]) {
for (int i = 0; i < 32; i++) {
printf("%d", binary[i]);
if ((i + 1) % 8 == 0) {
printf(".");
}
}
printf("\n");
}
void subnet(char *ip, int subnetMask) {
int binaryIP[32];
ipToBinary(ip, binaryIP);
printf("Original IP address in binary format: ");
printBinaryIP(binaryIP);
printf("Subnet mask: ");
for (int i = 0; i < subnetMask; i++) {
printf("1");
if ((i + 1) % 8 == 0 && i != 31) {
printf(".");
}
}
for (int i = subnetMask; i < 32; i++) {
printf("0");
if ((i + 1) % 8 == 0 && i != 31) {
printf(".");
}
}
printf("\n");
printf("Subnetted network address: ");
for (int i = 0; i < 32; i++) {
printf("%d", binaryIP[i] & ((i < subnetMask) ? 1 : 0));
if ((i + 1) % 8 == 0) {
printf("."); } }
printf("\n");
}
void supernet(char *ip1, char *ip2) {
int binaryIP1[32], binaryIP2[32];
ipToBinary(ip1, binaryIP1);
ipToBinary(ip2, binaryIP2);
printf("IP address 1 in binary format: ");
printBinaryIP(binaryIP1);
printf("IP address 2 in binary format: ");
printBinaryIP(binaryIP2);
int commonPrefixLength = 0;
for (int i = 0; i < 32; i++) {
if (binaryIP1[i] != binaryIP2[i]) {
break; }
commonPrefixLength++; }
printf("Common prefix length: %d\n", commonPrefixLength);
printf("Supernet mask: ");
for (int i = 0; i < commonPrefixLength; i++) {
printf("1");
if ((i + 1) % 8 == 0 && i != 31) {
printf(".");
}
}
for (int i = commonPrefixLength; i < 32; i++) {
printf("0");
if ((i + 1) % 8 == 0 && i != 31) {
printf(".");
}
}
printf("\n");

printf("Supernetted network address: ");


for (int i = 0; i < commonPrefixLength; i++) {
printf("%d", binaryIP1[i]);
if ((i + 1) % 8 == 0) {
printf(".");
}
}
for (int i = commonPrefixLength; i < 32; i++) {
printf("0");
if ((i + 1) % 8 == 0 && i != 31) {
printf(".");
}
}
printf("\n");
}
int main() {
char ip[20], ip1[20], ip2[20];
int subnetMask;
printf("Enter IP address (e.g., 192.168.1.1): ");
scanf("%s", ip);
printf("Enter subnet mask (e.g., 24 for /24): ");
scanf("%d", &subnetMask);
subnet(ip, subnetMask);
printf("Enter first IP address for supernetting: ");
scanf("%s", ip1);
printf("Enter second IP address for supernetting: ");
scanf("%s", ip2);
supernet(ip1, ip2);
return 0;
}
output:-
Findings and learnings:-
We learnt about Network ID, Host ID and Classes and the procedures to obtain them from an
IP address.
We also learned about Subnetting and Supernetting and how to obtain them.
EXPERIMENT-7
AIM: Write a program for shortest path using Dijkstra algorithm.
THEORY:
Dijkstra's algorithm is a popular method for finding the shortest path between nodes in a graph.
It works well for graphs with non-negative edge weights. Here's a brief overview of how
Dijkstra's algorithm works:
1. Initialization: Assign a tentative distance value to every node. Set the initial node's
distance to 0 and all other nodes' distances to infinity.
2. Selection of node: Mark all nodes as unvisited. Select the unvisited node with the
smallest tentative distance and set it as the current node.
3. Update distances: For the current node, consider all of its neighbors and calculate their
tentative distances through the current node. Compare the newly calculated tentative
distance to the current assigned value and assign the smaller one. For example, if the
current node A is marked with a distance of 6, and the edge connecting it with a
neighbor B has length 2, then the distance to B through A will be 6 + 2 = 8. If B was
previously marked with a distance greater than 8, then change it to 8.
4. Mark the current node as visited and remove it from the unvisited set.
5. Termination condition: Stop if the destination node has been visited or if the smallest
tentative distance among the unvisited nodes is infinity (indicating that there are no
more reachable nodes).
6. Output: Once the destination node has been visited, the algorithm can be terminated.
The shortest path can then be reconstructed by backtracking from the destination node
to the start node, following the chain of predecessors that led to each node.
Dijkstra's algorithm guarantees the shortest path from the start node to all other nodes in the
graph, provided it doesn't contain any negative-weight edges. If the graph contains negative-
weight edges, Dijkstra's algorithm may produce incorrect results.
Overall, Dijkstra's algorithm is efficient for finding the shortest path in graphs with non-
negative edge weights and is commonly used in various applications such as network routing,
GPS navigation, and computer networks.

Program:
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <climits>

using namespace std;

typedef pair<int, int> pii;


// Function to perform Dijkstra's algorithm
unordered_map<int, int> dijkstra(const vector<vector<pii>>& graph, int start) {
unordered_map<int, int> distances;
priority_queue<pii, vector<pii>, greater<pii>> pq;

for (size_t i = 0; i < graph.size(); ++i) {


distances[i] = INT_MAX;
}

distances[start] = 0;
pq.push({0, start});

while (!pq.empty()) {
int dist = pq.top().first;
int node = pq.top().second;
pq.pop();

if (dist > distances[node]) {


continue;
}

for (const auto& neighbor : graph[node]) {


int neighbor_node = neighbor.first;
int neighbor_dist = neighbor.second;

if (dist + neighbor_dist < distances[neighbor_node]) {


distances[neighbor_node] = dist + neighbor_dist;
pq.push({distances[neighbor_node], neighbor_node});
}
}
}

return distances;
}
int main() {

int num_nodes, num_edges;


cout << "Enter the number of nodes: ";
cin >> num_nodes;
cout << "Enter the number of edges: ";
cin >> num_edges;

// Create a graph represented as an adjacency list


vector<vector<pii>> graph(num_nodes);

cout << "Enter the edges (node1 node2 weight):" << endl;
for (int i = 0; i < num_edges; ++i) {
int node1, node2, weight;
cin >> node1 >> node2 >> weight;
graph[node1].push_back({node2, weight});
// For undirected graph, add the reverse edge
graph[node2].push_back({node1, weight});
}

int start_node;
cout << "Enter the start node: ";
cin >> start_node;

auto shortest_distances = dijkstra(graph, start_node);

// Output shortest distances from the start node


cout << "Shortest distances from node " << start_node << ": ";
for (const auto& entry : shortest_distances) {
cout << entry.first << " -> " << entry.second << ", ";
}
cout << endl;
return 0;
}

Output:

Learning Outcome:
The provided C++ code for Dijkstra's algorithm with user input demonstrates several key
concepts and skills:
1. Graph Representation: The program represents the graph using an adjacency list,
which is efficient for sparse graphs. This allows for easy storage and traversal of the
graph.
2. User Input: The program prompts the user to input the number of nodes, number of
edges, edge connections, and weights. This demonstrates handling of user input in C++.
3. Dijkstra's Algorithm: The core of the program is the implementation of Dijkstra's
algorithm, which efficiently finds the shortest paths from a given source node to all
other nodes in the graph.
4. Priority Queue: The program utilizes a priority queue to select the next node with the
smallest tentative distance during the algorithm execution. This highlights the usage of
data structures to optimize algorithm performance.
5. Output: The program provides clear output of the shortest distances from the specified
start node to all other nodes in the graph. This demonstrates effective communication
of algorithm results.
Overall, the learning outcome includes understanding graph algorithms, handling user input,
data structure utilization for algorithm optimization, and clear presentation of algorithm results.
This knowledge can be applied to various problems involving graph traversal and pathfinding
in real-world scenarios.
EXPERIMENT-8

AIM: Write a program for link state routing.

THEORY:
Link state routing is the second family of routing protocols. While distance-vector routers
use a distributed algorithm to compute their routing tables, link-state routing uses link-state
routers to exchange messages that allow each router to learn the entire network topology.
Based on this learned topology, each router is then able to compute its routing table by using
the shortest path computation.
Link state routing is a technique in which each router shares the knowledge of its neighbour
with every other router i.e. the internet work. The three keys to understand the link state
routing algorithm.
Features of Link State Routing Protocols
 Link State Packet: A small packet that contains routing information.
 Link-State Database: A collection of information gathered from the link-state
packet.
 Shortest Path First Algorithm (Dijkstra algorithm): A calculation performed
on the database results in the shortest path
 Routing Table: A list of known paths and interfaces.
Characteristics of Link State Protocol
 It requires a large amount of memory.
 Shortest path computations require many CPU circles.
 If a network uses little bandwidth; it quickly reacts to topology changes
 All items in the database must be sent to neighbours to form link-state packets.
 All neighbours must be trusted in the topology.
 Authentication mechanisms can be used to avoid undesired adjacency and
problems.
 No split horizon techniques are possible in the link-state routing.
 OSPF Protocol
Protocols of Link State Routing
1. Open Shortest Path First (OSPF)
2. Intermediate System to Intermediate System (IS-IS)

CODE:

#include <iostream>
#include <vector>
#include <limits>

using namespace std;

class LinkStateRouter {
public:
LinkStateRouter(int id, int numRouters) : id(id), numRouters(numRouters) {
routingTable.resize(numRouters + 1, numeric_limits<int>::max()); // Initialize with
maximum cost
routingTable[id] = 0; // Cost to itself is 0
}

void addLink(int neighborId, int cost) {


links.push_back(make_pair(neighborId, cost));
}

void updateRoutingTable() {
// Implement Dijkstra's algorithm to find shortest paths
bool visited[numRouters + 1] = {false};

for (int i = 1; i <= numRouters; ++i) {


int minCost = numeric_limits<int>::max();
int minIndex = -1;

// Find the router with the minimum cost


for (int j = 1; j <= numRouters; ++j) {
if (!visited[j] && routingTable[j] < minCost) {
minCost = routingTable[j];
minIndex = j;
}
}

// Mark the router as visited


visited[minIndex] = true;

// Update costs through the selected router


for (const auto& link : links) {
if (link.first == minIndex) {
int neighborId = link.first;
int cost = link.second;
routingTable[neighborId] = min(routingTable[neighborId], routingTable[minIndex] +
cost);
}
}
}
}

int getCostToNeighbor(int neighborId) {


return routingTable[neighborId];
}
private:
int id;
int numRouters;
vector<pair<int, int>> links; // Neighbor ID and cost
vector<int> routingTable; // Cost to each neighbor
};

int main() {
// Create the routers.
cout<<"SHUBHAM SHANDILYA 2K21/CO/457"<<endl;
const int numRouters = 3;
LinkStateRouter router1(1, numRouters);
LinkStateRouter router2(2, numRouters);
LinkStateRouter router3(3, numRouters);

// Add the links between the routers.


router1.addLink(2, 1);
router1.addLink(3, 2);
router2.addLink(1, 1);
router2.addLink(3, 3);
router3.addLink(1, 2);
router3.addLink(2, 3);

// Update the routing tables of all routers.


router1.updateRoutingTable();
router2.updateRoutingTable();
router3.updateRoutingTable();

// Print the routing table of router 1.


cout << "Routing table for router 1:" << endl;
for (int i = 1; i <= numRouters; i++) {
cout << "Cost to router " << i << ": " << router1.getCostToNeighbor(i) << endl;
}

return 0;
}
OUTPUT:

LEARNING OUTCOME:

 Link-state routing algorithms, like OSPF and IS-IS, are vital for efficient routing in
computer networks.
 They're used in internet routing, enterprise networks, telecom networks, data centres,
wireless mesh networks, military networks, transportation systems, and IoT networks.
 These algorithms optimize routing paths, ensure reliable communication, and improve
network performance in diverse applications and industries.
EXPERIMENT-9

AIM: Write a program for Distance vector routing.

THEORY:
Distance vector routing is another type of routing algorithm used in computer networks. Here's
a brief overview:

Definition: Distance vector routing is a distributed routing algorithm where each router
maintains a routing table that contains the distance (cost) to all reachable destinations and the
next hop router to reach them.

Operation:

 Initialization: Each router starts with its own routing table, typically initialized with
direct neighbour costs. Initially, each router only knows the cost to its directly
connected neighbours.
 Exchange of Routing Information: Routers periodically exchange routing tables with
their neighbours. Each router sends its entire routing table to its neighbours.
 Updating Routing Tables: Upon receiving a routing table from a neighbour, a router
updates its own routing table based on the received information. It calculates the total
cost to reach each destination by considering the minimum cost among all available
paths.
 Iterative Process: The process of exchanging and updating routing tables continues
iteratively. Routers continuously refine their routing tables until convergence is
reached, meaning that no further changes occur.

Key Features:

 Decentralized: Distance vector routing is decentralized, meaning that each router


independently computes its routing table based on local information and exchanges
information with neighbouring routers.
 Bellman-Ford Algorithm: Distance vector routing is based on the Bellman-Ford
algorithm, which calculates the shortest path to each destination.
 Routing Loops: Distance vector routing is susceptible to routing loops, where incorrect
routing information causes packets to loop indefinitely between routers.
 Count to Infinity Problem: Distance vector routing suffers from the "count to infinity"
problem, where routers incorrectly learn of shorter paths via longer paths, leading to
routing table instability.

Examples:
 The most well-known example of distance vector routing is the Routing Information
Protocol (RIP), specifically RIP version 1 (RIP-1). RIP uses hop count as the metric
and exchanges routing updates every 30 seconds.
 Another example is the Border Gateway Protocol (BGP), which uses a form of distance
vector routing but with path vectors and path attributes. BGP is primarily used for inter-
domain routing on the internet.
 In summary, distance vector routing is a distributed routing algorithm used in computer
networks. While simpler to implement than link-state routing, it has drawbacks such as
routing loops and the count to infinity problem. Despite its limitations, it has been
widely used in various network environments.

CODE:
#include <stdio.h>
#include <stdlib.h>

#define MAX_NODES 10

// Structure to represent a node in the network


typedef struct Node {
int id;
int routing_table[MAX_NODES][3]; // [destination, next_hop, cost]
int num_neighbors;
struct Node* neighbors[MAX_NODES];
} Node;

// Function to initialize a node


void initialize_node(Node* node, int id) {
node->id = id;
node->num_neighbors = 0;
for (int i = 0; i < MAX_NODES; i++) {
for (int j = 0; j < 3; j++) {
node->routing_table[i][j] = -1;
}
}
}

// Function to add a neighbor to a node


void add_neighbor(Node* node, Node* neighbor) {
if (node->num_neighbors < MAX_NODES) {
node->neighbors[node->num_neighbors] = neighbor;
node->num_neighbors++;
}
}
// Function to update the routing table of a node
void update_routing_table(Node* node) {
for (int i = 0; i < node->num_neighbors; i++) {
Node* neighbor = node->neighbors[i];
for (int j = 0; j < MAX_NODES; j++) {
if (neighbor->routing_table[j][0] != -1) {
int destination = neighbor->routing_table[j][0];
int cost = neighbor->routing_table[j][2];
int total_cost = cost + 1; // Assuming a cost of 1 for each hop
if (node->routing_table[destination][0] == -1 ||
total_cost < node->routing_table[destination][2]) {
// Update the routing table entry
node->routing_table[destination][0] = destination;
node->routing_table[destination][1] = neighbor->id;
node->routing_table[destination][2] = total_cost;
}
}
}
}
}

// Function to print the routing table of a node


void print_routing_table(Node* node) {
printf("Routing table of Node %d:\n", node->id);
printf("---------------------------\n");
printf("| Destination | Next Hop | Cost |\n");
printf("---------------------------\n");
for (int i = 0; i < MAX_NODES; i++) {
if (node->routing_table[i][0] != -1) {
printf("| %2d | %2d | %2d |\n", node->routing_table[i][0],
node->routing_table[i][1], node->routing_table[i][2]);
}
}
printf("---------------------------\n");
}

int main() {
printf("SHUBHAM SHANDILYA 2K21/CO/457\n");
// Create nodes
Node nodes[MAX_NODES];
for (int i = 0; i < MAX_NODES; i++) {
initialize_node(&nodes[i], i);
}
// Add neighbors
add_neighbor(&nodes[0], &nodes[1]);
add_neighbor(&nodes[0], &nodes[2]);
add_neighbor(&nodes[1], &nodes[0]);
add_neighbor(&nodes[1], &nodes[3]);
add_neighbor(&nodes[2], &nodes[0]);
add_neighbor(&nodes[2], &nodes[3]);
add_neighbor(&nodes[3], &nodes[1]);
add_neighbor(&nodes[3], &nodes[2]);

// Run distance vector routing algorithm


int convergence = 0;
int iteration = 0;
while (!convergence) {
convergence = 1;
printf("Iteration %d\n", iteration);
for (int i = 0; i < MAX_NODES; i++) {
update_routing_table(&nodes[i]);
}

// Check for convergence


for (int i = 0; i < MAX_NODES; i++) {
for (int j = 0; j < MAX_NODES; j++) {
if (nodes[i].routing_table[j][0] != -1 &&
nodes[i].routing_table[j][2] != nodes[i].routing_table[j][2]) {
convergence = 0;
break;
}
}
if (!convergence) {
break;
}
}

// Print routing tables


for (int i = 0; i < MAX_NODES; i++) {
print_routing_table(&nodes[i]);
}

iteration++;
printf("\n");
}
return 0;
}

OUTPUT:
LEARNING OUTCOMES:

Distance vector routing teaches distributed routing, updates routing tables iteratively, and
exchanges routing information among routers. It illustrates the Bellman-Ford algorithm and
challenges like routing loops and count to infinity.

You might also like