0% found this document useful (0 votes)
22 views39 pages

NAS Practical File Student

Practical file of Network and system

Uploaded by

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

NAS Practical File Student

Practical file of Network and system

Uploaded by

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

PRACTICAL FILE

OF
“NETWORKS AND SYSTEMS LAB”
(13450145)

FACULTY OF ENGINEERING AND TECHNOLOGY

Submitted to: Submitted by:


Ms. Charvi Name:
Assistant Professor Reg. no.:
BCA 1st Sem (CC)
INDEX
S.No Name of the Experiment Date Signature
EXPERIMENT NO. 1

AIM: Learn to use commands like tcpdump, netstat, ipconfig, nslookup and
traceroute. Capture ping and traceroute PDUs using a network protocol
analyzer and examine.

Solution:

1. tcpdump:

 Description: tcpdump is a command-line packet analyzer that captures network traffic in


real-time and displays it for analysis.

 Usage: It's commonly used to monitor network activity, diagnose network issues, and
analyze packet contents.

 Example: sudo tcpdump icmp captures ICMP (ping) packets and displays them as they
traverse the network.

 Output:
2. netstat:

 Description: netstat (network statistics) is a command-line tool that displays network-


related information, such as active network connections, routing tables, and interface
statistics.

 Usage: It's used to monitor network connections, troubleshoot connectivity issues, and
view network statistics.

 Example: netstat -tuln displays a list of listening TCP and UDP connections.

 Output:

3. ipconfig (Windows) / ifconfig (Linux):

 Description: ipconfig (Windows) and ifconfig (Linux) are commands that provide
information about IP configuration and network interfaces.

 Usage: They're used to view IP addresses, subnet masks, gateways, and other network
configuration details.

 Examples:
 Windows: ipconfig /all displays detailed IP configuration information for all
interfaces.

 Linux: ifconfig shows information about network interfaces.

 Output:

4. nslookup:

 Description: nslookup is a command-line tool used to query DNS (Domain Name


System) servers to retrieve domain-related information.

 Usage: It's used to look up DNS records, resolve domain names to IP addresses, and
troubleshoot DNS-related issues.

 Example: nslookup google.com queries DNS to find the IP address associated with the
domain "google.com".

 Output:
5. traceroute:

 Description: traceroute is a command-line tool that shows the route and the time taken
for network packets to travel from the source to a destination server.

 Usage: It's used to diagnose network routing issues and identify delays or packet loss in
the network path.

 Example: traceroute google.com traces the route taken by packets from your computer
to the Google website.

 Output:

These commands are essential tools for network administrators, engineers, and anyone dealing
with network troubleshooting and analysis. They provide insights into network activities,
configurations, and issues, helping you better understand and manage your network
environment.

Capturing Ping and Traceroute Packets using Wireshark (Network Protocol Analyzer):

1. Install Wireshark: Download and install Wireshark from its official website.
2. Open Wireshark:

 Launch Wireshark and select the network interface you want to capture packets
on.

3. Capture ICMP (Ping) Packets:

 Start the capture by clicking the "Start" button.

 In the "Capture Filter" field, enter icmp to capture only ICMP packets (ping).

 Initiate a ping from another device or the command line.

 Once the ping is complete, stop the capture in Wireshark.

4. Capture Traceroute Packets:

 Start a new capture session.

 In the "Capture Filter" field, enter icmp to capture only ICMP packets
(traceroute).

 Initiate a traceroute from another device or the command line.

 Stop the capture when the traceroute is finished.

5. Examine Captured Packets:

 In Wireshark, you'll see a list of captured packets. You can click on any packet to
see detailed information.

 You can view source and destination IPs, protocols, packet timings, and more.

Remember:

 Capturing packets often requires administrative privileges (superuser/root access).


Ensure you have the necessary permissions.

 Always consider ethical and legal implications. Obtain proper authorization before
capturing packets on any network.

 Interpreting packet captures requires some knowledge of networking protocols and


packet structures.

By using the above commands and Wireshark, you can capture and examine ping and
traceroute packets to better understand how network communication works.
Output:

1) Ping in Wireshark

2) Traceroute in Wireshark
EXPERIMENT NO. 2

AIM: Write a program for a HDLC frame to perform the following. i) Bit stuffing
ii) Character stuffing.

Solution:

#include <stdio.h>

#include <string.h

// Function for bit stuffing

void bitStuffing(char *input_bits, int max_consecutive_ones, char *stuffed_bits) {

int consecutive_ones = 0;

int index = 0;

for (int i = 0; i < strlen(input_bits); i++) {

if (input_bits[i] == '1') {

consecutive_ones++;

if (consecutive_ones == max_consecutive_ones) {

stuffed_bits[index++] = '1';

stuffed_bits[index++] = '0'; // Stuff a '0' bit after 'max_consecutive_ones' consecutive


'1' bits

consecutive_ones = 0;

} else {

stuffed_bits[index++] = '1';

} else {

consecutive_ones = 0;
stuffed_bits[index++] = '0';

stuffed_bits[index] = '\0'; // Null-terminate the stuffed_bits array

// Function for character stuffing

void characterStuffing(char *input_chars, char start_flag, char end_flag, char escape_char, char
*stuffed_chars) {

int index = 0;

stuffed_chars[index++] = start_flag;

for (int i = 0; i < strlen(input_chars); i++) {

if (input_chars[i] == start_flag || input_chars[i] == end_flag || input_chars[i] ==


escape_char) {

stuffed_chars[index++] = escape_char; // Escape the special character

stuffed_chars[index++] = input_chars[i]; // Append the character

stuffed_chars[index++] = end_flag;

stuffed_chars[index] = '\0'; // Null-terminate the stuffed_chars array

int main() {

char input_bits[] = "011111100111110011111010";

int max_consecutive_ones = 5;

char stuffed_bits[100];
char input_chars[] = "ABC$DE#F";

char start_flag = '$';

char end_flag = '#';

char escape_char = '!';

char stuffed_chars[100];

bitStuffing(input_bits, max_consecutive_ones, stuffed_bits);

printf("Original Bits: %s\n", input_bits);

printf("Stuffed Bits: %s\n", stuffed_bits);

characterStuffing(input_chars, start_flag, end_flag, escape_char, stuffed_chars);

printf("Original Characters: %s\n", input_chars);

printf("Stuffed Characters: %s\n", stuffed_chars);

return 0;

Output:
EXPERIMENT NO. 3

AIM: Implement Dijkstra’s algorithm to compute the shortest routing path.


Solution:

#include <stdio.h>

#include <stdbool.h>

#include <limits.h>

#define V 6 // Number of vertices in the graph

// Function to find the vertex with the minimum distance value

int minDistance(int dist[], bool visited[]) {

int min = INT_MAX, min_index;

for (int v = 0; v < V; v++)

if (! visited[v] && dist[v] <= min)

min = dist[v], min_index = v;

return min_index;

// Function to print the constructed distance array

void printSolution(int dist[]) {

printf("Vertex \t Distance from Source\n");

for (int i = 0; i < V; i++)

printf("%d \t %d\n", i, dist[i]);

}
// Function that implements Dijkstra's single-source shortest path algorithm

void dijkstra(int graph[V][V], int source) {

int dist[V];

bool visited[V];

for (int i = 0; i < V; i++) {

dist[i] = INT_MAX;

visited[i] = false;

dist[source] = 0;

for (int count = 0; count < V - 1; count++) {

int u = minDistance(dist, visited);

visited[u] = true;

for (int v = 0; v < V; v++) {

if (!visited[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])

dist[v] = dist[u] + graph[u][v];

printSolution(dist);

int main() {
int graph[V][V] = {

{0, 4, 0, 0, 0, 0},

{4, 0, 8, 0, 0, 0},

{0, 8, 0, 7, 0, 9},

{0, 0, 7, 0, 1, 0},

{0, 0, 0, 1, 0, 3},

{0, 0, 9, 0, 3, 0}

};

dijkstra(graph, 0);

return 0;

In this implementation:

 V is the number of vertices in the graph.

 The graph array represents the weighted adjacency matrix of the graph.

 The dijkstra function calculates the shortest path from a given source vertex.

 The printSolution function displays the computed shortest distances.

Output:

EXPERIMENT NO. 4
AIM: Write a program for error detecting code using CRC-CCITT.

Solution:

#include <stdio.h>
#include <string.h>

#define POLYNOMIAL 0x1021 // CRC-CCITT polynomial


#define WIDTH 16 // Number of bits in CRC-CCITT

// Function to perform CRC-CCITT error detection


unsigned short crc_ccitt(const unsigned char *data, int len) {
unsigned short crc = 0xFFFF; // Initial CRC value

for (int i = 0; i < len; i++) {


crc ^= (unsigned short)(data[i] << 8); // XOR data byte into MSB of CRC

for (int j = 0; j < 8; j++) {


if (crc & 0x8000) // If MSB is 1
crc = (crc << 1) ^ POLYNOMIAL;
else
crc = crc << 1;
}
}

return crc;
}

int main() {
unsigned char data[] = "Hello, CRC-CCITT!"; // Data to be transmitted
int data_len = strlen(data);

unsigned short checksum = crc_ccitt(data, data_len);

printf("Data: %s\n", data);

printf("CRC-CCITT Checksum: 0x%04X\n", checksum);


// Simulate transmission and introduce error by changing a bit
data[10] ^= 0x01; // Toggle the 10th bit

unsigned short received_checksum = crc_ccitt(data, data_len);


if (received_checksum == 0) {
printf("Received data is error-free.\n");
} else {
printf("Received data has errors.\n");
}

return 0;
}

In this program:
 The crc_ccitt function calculates the CRC-CCITT checksum for the given data.
 The main function simulates the transmission of data, introduces an error by toggling a
bit, and then calculates the received checksum to detect the error.

Output:

EXPERIMENT NO. 5
AIM: Implementation of Stop and Wait Protocol and Sliding Window Protocol.

Solution: i) Stop and Wait Protocol

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>

// Simulates a simple channel with a chance of frame loss or corruption


bool isFrameLostOrCorrupted(float errorProbability) {
return (rand() / (float)RAND_MAX) < errorProbability;
}

void stopAndWaitSender(float errorProbability) {


for (int i = 1; i <= 5; i++) {
printf("Sender: Sending frame %d\n", i);

if (isFrameLostOrCorrupted(errorProbability)) {
printf("Receiver: Acknowledgment for frame %d lost or corrupted.\n", i);
} else {
printf("Receiver: Acknowledgment for frame %d received.\n", i);
}

printf("\n");
}
}

void stopAndWaitReceiver(float errorProbability) {


for (int i = 1; i <= 5; i++) {
if (isFrameLostOrCorrupted(errorProbability)) {
printf("Sender: Frame %d lost or corrupted.\n", i);
} else {
printf("Sender: Frame %d received.\n", i);
printf("Receiver: Sending acknowledgment for frame %d\n", i);

}
printf("\n");
}
}

int main() {
srand(time(NULL));
float errorProbability = 0.3; // Probability of frame loss or corruption

printf("Stop and Wait Protocol:\n\n");


stopAndWaitSender(errorProbability);
printf("\n");
stopAndWaitReceiver(errorProbability);

return 0;
}

Output:

Solution: ii) Sliding Window Protocol


#include <stdio.h>

#include <stdbool.h>

#include <stdlib.h>

#include <time.h>

#define WINDOW_SIZE 3

// Simulates a simple channel with a chance of frame loss or corruption

bool isFrameLostOrCorrupted(float errorProbability) {

return (rand() / (float)RAND_MAX) < errorProbability;

void slidingWindowSender(float errorProbability) {

int base = 1;

int nextSeqNum = 1;

while (base <= 5) {

for (int i = base; i < base + WINDOW_SIZE && i <= 5; i++) {

printf("Sender: Sending frame %d\n", i);

if (isFrameLostOrCorrupted(errorProbability)) {

printf("Receiver: Acknowledgment for frame %d lost or corrupted.\n", i);

} else {

printf("Receiver: Acknowledgment for frame %d received.\n", i);

nextSeqNum = i + 1;

}
printf("Sender: Waiting for acknowledgments...\n");

base = nextSeqNum;

printf("\n");

void slidingWindowReceiver(float errorProbability) {

int expectedSeqNum = 1;

while (expectedSeqNum <= 5) {

if (isFrameLostOrCorrupted(errorProbability)) {

printf("Sender: Frame %d lost or corrupted.\n", expectedSeqNum);

} else {

printf("Sender: Frame %d received.\n", expectedSeqNum);

printf("Receiver: Sending acknowledgment for frame %d\n", expectedSeqNum);

expectedSeqNum++;

printf("\n");

int main() {

srand(time(NULL));

float errorProbability = 0.3; // Probability of frame loss or corruption

printf("Sliding Window Protocol:\n\n");

slidingWindowSender(errorProbability);
printf("\n");

slidingWindowReceiver(errorProbability)

return 0;

Output:
EXPERIMENT NO. 6

AIM: Write a program to find the shortest path between vertices using bellman-
ford algorithm.

Solution:

#include <stdio.h>

#include <stdlib.h>

#include <limits.h>

#define NUM_VERTICES 5 // Number of vertices

#define NUM_EDGES 8 // Number of edges

struct Edge {

int src, dest, weight;

};

struct Graph {

int V, E;

struct Edge* edges;

};

struct Graph* createGraph(int V, int E) {

struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));

graph->V = V;

graph->E = E;

graph->edges = (struct Edge*)malloc(E * sizeof(struct Edge));

return graph;
}

void printDistances(int dist[], int n) {

printf("Vertex \t Distance from Source\n");

for (int i = 0; i < n; i++)

printf("%d \t %d\n", i, dist[i]);

void BellmanFord(struct Graph* graph, int src) {

int V = graph->V;

int E = graph->E;

int dist[V]

// Initialize distances

for (int i = 0; i < V; i++)

dist[i] = INT_MAX;

dist[src] = 0;

// Relax all edges V-1 times

for (int i = 1; i <= V - 1; i++) {

for (int j = 0; j < E; j++) {

int u = graph->edges[j].src;

int v = graph->edges[j].dest;

int weight = graph->edges[j].weight;

if (dist[u] != INT_MAX && dist[u] + weight < dist[v])

dist[v] = dist[u] + weight;

}
}

// Check for negative-weight cycles

for (int i = 0; i < E; i++) {

int u = graph->edges[i].src;

int v = graph->edges[i].dest;

int weight = graph->edges[i].weight;

if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) {

printf("Graph contains negative-weight cycle\n");

return;

printDistances(dist, V);

int main() {

struct Graph* graph = createGraph(NUM_VERTICES, NUM_EDGES);

graph->edges[0].src = 0;

graph->edges[0].dest = 1;

graph->edges[0].weight = -1;

graph->edges[1].src = 0;

graph->edges[1].dest = 2;

graph->edges[1].weight = 4;

graph->edges[2].src = 1;

graph->edges[2].dest = 2;
graph->edges[2].weight = 3;

graph->edges[3].src = 1;

graph->edges[3].dest = 3;

graph->edges[3].weight = 2;

graph->edges[4].src = 1;

graph->edges[4].dest = 4;

graph->edges[4].weight = 2;

graph->edges[5].src = 3;

graph->edges[5].dest = 2;

graph->edges[5].weight = 5;

graph->edges[6].src = 3;

graph->edges[6].dest = 1;

graph->edges[6].weight = 1;

graph->edges[7].src = 4;

graph->edges[7].dest = 3;

graph->edges[7].weight = -3;

int source = 0

printf("Shortest distances from source vertex %d:\n", source);

BellmanFord(graph, source);

return 0;

}
In this program:

 NUM_VERTICES is the number of vertices, and NUM_EDGES is the number of edges.

 The Edge structure represents an edge with its source, destination, and weight.

 The Graph structure represents the graph.

 The createGraph function allocates memory for the graph and its edges.

 The BellmanFord function computes the shortest paths using the Bellman-Ford

algorithm.

 The printDistances function prints the computed distances.

 The main function initializes the graph, specifies the source vertex, and invokes the

Bellman-Ford algorithm.

Output:
EXPERIMENT NO. 7

AIM: Implement a program for simple RSA algorithm to encrypt and decrypt the
data.

Solution:

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

// Function to calculate the Greatest Common Divisor (GCD) of two numbers

int gcd(int a, int b) {

if (b == 0)

return a;

return gcd(b, a % b);

// Function to calculate the modular inverse using extended Euclidean algorithm

int modInverse(int a, int m) {

for (int x = 1; x < m; x++)

if ((a * x) % m == 1)

return x;

return -1; // Inverse doesn't exist

// Function to calculate the power of a number modulo m

int powerMod(int base, int exponent, int m) {


int result = 1;

while (exponent > 0) {

if (exponent % 2 == 1)

result = (result * base) % m;

base = (base * base) % m;

exponent /= 2;

return result;

int main() {

int p = 61; // A prime number

int q = 53; // Another prime number

int n = p * q; // Calculate n

int phi = (p - 1) * (q - 1); // Calculate Euler's totient function phi(n)

// Choose an encryption key e

int e;

for (e = 2; e < phi; e++) {

if (gcd(e, phi) == 1)

break;

// Calculate the decryption key d

int d = modInverse(e, phi);


int plaintext = 88; // Data to be encrypted

printf("Original Data: %d\n", plaintext);

// Encryption: c = (plaintext^e) % n

int ciphertext = powerMod(plaintext, e, n);

printf("Encrypted Data: %d\n", ciphertext);

// Decryption: decrypted = (ciphertext^d) % n

int decrypted = powerMod(ciphertext, d, n);

printf("Decrypted Data: %d\n", decrypted);

return 0;

In this program:

 Two prime numbers p and q are chosen to create a modulus n.

 The Euler's totient function phi(n) is calculated as (p - 1) * (q - 1).

 An encryption key e is chosen such that it is coprime with phi(n) (GCD is 1).

 The decryption key d is calculated using the modular inverse of e modulo phi(n).

 The plaintext data is encrypted using ciphertext = (plaintext^e) % n.

 The ciphertext is decrypted using decrypted = (ciphertext^d) % n.

Output:
EXPERIMENT NO. 8

AIM: Design a program for congestion control using leaky bucket algorithm.

Solution:

#include <stdio.h>

#include <stdlib.h>

#include <stdbool.h>

#include <unistd.h>

#define BUCKET_CAPACITY 10 // Maximum bucket size

#define OUTPUT_RATE 3 // Rate at which data is output from the bucket

struct LeakyBucket {

int currentSize;

};

// Initialize the leaky bucket

void initBucket(struct LeakyBucket *bucket) {

bucket->currentSize = 0;

// Add data to the bucket

void addToBucket(struct LeakyBucket *bucket, int dataSize) {

if (bucket->currentSize + dataSize <= BUCKET_CAPACITY) {

bucket->currentSize += dataSize;

} else {

printf("Bucket overflow! Dropping data.\n");


}

// Output data from the bucket

void outputFromBucket(struct LeakyBucket *bucket) {

if (bucket->currentSize > 0) {

printf("Outputting %d units of data.\n", OUTPUT_RATE);

bucket->currentSize -= OUTPUT_RATE;

} else {

printf("Bucket is empty.\n");

int main() {

struct LeakyBucket bucket;

initBucket(&bucket);

int dataSizes[] = {4, 2, 6, 1, 3}; // Data sizes arriving at different times

for (int i = 0; i < sizeof(dataSizes) / sizeof(dataSizes[0]); i++) {

printf("Time t=%d: Received %d units of data.\n", i, dataSizes[i]);

addToBucket(&bucket, dataSizes[i]);

outputFromBucket(&bucket);

sleep(1); // Simulate time passing

return 0;

}
In this program:

 The LeakyBucket structure represents the leaky bucket.

 The initBucket function initializes the bucket.

 The addToBucket function adds data to the bucket if there's space.

 The outputFromBucket function outputs data from the bucket based on the output

rate.

 The main function simulates the arrival of data of different sizes at different times and

applies the leaky bucket algorithm to control the data output rate.

Output:
EXPERIMENT NO. 9

AIM: Develop a program for distance vector algorithm to find suitable path for
transmission.

Solution:

#include <stdio.h>

#include <stdbool.h>

#include <limits.h>

#define NUM_NODES 4

// Initialize the routing table

void initRoutingTable(int routingTable[][NUM_NODES], int numNodes) {

for (int i = 0; i < numNodes; i++) {

for (int j = 0; j < numNodes; j++) {

if (i == j)

routingTable[i][j] = 0;

else

routingTable[i][j] = INT_MAX;

// Print the routing table

void printRoutingTable(int routingTable[][NUM_NODES], int numNodes) {

printf("Routing Table:\n");
for (int i = 0; i < numNodes; i++) {

printf("Node %d: ", i);

for (int j = 0; j < numNodes; j++) {

if (routingTable[i][j] == INT_MAX)

printf("INF ");

else

printf("%d ", routingTable[i][j]);

printf("\n");

// Update the routing table using the Distance Vector algorithm

void distanceVector(int routingTable[][NUM_NODES], int numNodes) {

for (int k = 0; k < numNodes; k++) {

for (int i = 0; i < numNodes; i++) {

for (int j = 0; j < numNodes; j++) {

if (routingTable[i][k] != INT_MAX && routingTable[k][j] != INT_MAX) {

int newDist = routingTable[i][k] + routingTable[k][j];

if (newDist < routingTable[i][j])

routingTable[i][j] = newDist;

}
}

int main() {

int numNodes = NUM_NODES;

int routingTable[NUM_NODES][NUM_NODES];

// Initialize the routing table

initRoutingTable(routingTable, numNodes);

// Define the initial distance values

routingTable[0][1] = 3;

routingTable[0][2] = 2;

routingTable[1][2] = 1;

routingTable[2][3] = 5;

routingTable[1][3] = 2;

printf("Initial ");

printRoutingTable(routingTable, numNodes);

// Apply the Distance Vector algorithm

distanceVector(routingTable, numNodes);

printf("After Applying Distance Vector Algorithm\n");

printRoutingTable(routingTable, numNodes);

return 0;

}
In this program:

 The initRoutingTable function initializes the routing table with initial values.

 The printRoutingTable function prints the routing table.

 The distanceVector function applies the Distance Vector algorithm by iteratively

updating the routing table.

 The main function initializes the routing table with initial distances, applies the

Distance Vector algorithm, and then prints the updated routing table.

Output:
EXPERIMENT NO. 10

AIM: Develop a program to find the shortest path between vertices using
bellman-ford algorithm.

Solution:

#include <stdio.h>

#include <stdlib.h>

#include <limits.h>

#define V 5 // Number of vertices

#define E 8 // Number of edges

struct Edge {

int src, dest, weight;

};

void bellmanFord(struct Edge edgeList[], int src) {

int dist[V];

for (int i = 0; i < V; i++)

dist[i] = INT_MAX;

dist[src] = 0;

for (int i = 1; i <= V - 1; i++) {

for (int j = 0; j < E; j++) {

int u = edgeList[j].src;

int v = edgeList[j].dest;

int weight = edgeList[j].weight;


if (dist[u] != INT_MAX && dist[u] + weight < dist[v])

dist[v] = dist[u] + weight;

// Check for negative-weight cycles

for (int i = 0; i < E; i++) {

int u = edgeList[i].src;

int v = edgeList[i].dest;

int weight = edgeList[i].weight;

if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) {

printf("Graph contains negative-weight cycle\n");

return;

printf("Vertex \t Distance from Source\n");

for (int i = 0; i < V; i++)

printf("%d \t %d\n", i, dist[i]);

int main() {

struct Edge edgeList[E] = {

{0, 1, -1}, {0, 2, 4}, {1, 2, 3},

{1, 3, 2}, {1, 4, 2}, {3, 2, 5},

{3, 1, 1}, {4, 3, -3}


};

int source = 0;

bellmanFord(edgeList, source);

return 0;

In this program:

 The graph array stores the directed edges along with their weights.

 The bellmanFord function calculates the shortest path distances using the Bellman-

Ford algorithm.

 The main function initializes the graph and source vertex, and then invokes the

bellmanFord function to find the shortest paths.

Output:

You might also like