1.
Implement the data link layer framing methods such as character , character
stuffing and bit stuffing
#include <stdio.h>
#include <string.h>
void characterCounting(char *input) {
printf("Character Counting Framing:\n");
int length = strlen(input);
printf("%d%s\n", length, input);
void characterStuffing(char *input) {
printf("Character Stuffing Framing:\n");
printf("%c", FLAG);
for (int i = 0; i < strlen(input); i++) {
if (input[i] == FLAG || input[i] == ESC) {
printf("%c", ESC);
printf("%c", input[i]);
printf("%c\n", FLAG);
void bitStuffing(char *input) {
printf("Bit Stuffing Framing:\n");
printf("01111110 "); // Starting flag
int count = 0;
for (int i = 0; i < strlen(input); i++) {
if (input[i] == '1') {
count++;
printf("1");
if (count == 5) {
printf("0"); // Stuff a 0 after five consecutive 1s
count = 0;
} else {
printf("0");
count = 0;
printf(" 01111110\n"); // Ending flag
int main() {
char input[100];
printf("Enter the data to be framed: ");
scanf("%s", input);
characterCounting(input);
characterStuffing(input);
printf("Enter binary data for Bit Stuffing: ");
scanf("%s", input);
bitStuffing(input);
return 0;
}
2 )Write a program to compute CRC code for the polynomials CRC-12, CRC-16 and CRC
CCIP
#include <stdio.h>
#include <stdint.h>
#include <string.h>
uint16_t compute_crc(uint8_t *data, size_t length, uint16_t polynomial, uint16_t crc_width,
uint16_t init_value) {
uint16_t crc = init_value;
for (size_t i = 0; i < length; i++) {
crc ^= (data[i] << (crc_width - 8));
for (uint8_t bit = 0; bit < 8; bit++) {
if (crc & (1 << (crc_width - 1))) {
crc = (crc << 1) ^ polynomial;
} else {
crc <<= 1;
crc &= (1 << crc_width) - 1; // Mask to keep CRC within bit width
return crc;
int main() {
uint16_t CRC_12_POLY = 0x080F; // x^12 + x^11 + x^3 + x^2 + x + 1
uint16_t CRC_16_POLY = 0x8005; // x^16 + x^15 + x^2 + 1
uint16_t CRC_CCITT_POLY = 0x1021; // x^16 + x^12 + x^5 + 1
uint8_t data[] = "Hello";
size_t length = strlen((char *)data);
uint16_t crc_12 = compute_crc(data, length, CRC_12_POLY, 12, 0x000);
uint16_t crc_16 = compute_crc(data, length, CRC_16_POLY, 16, 0x0000);
uint16_t crc_ccitt = compute_crc(data, length, CRC_CCITT_POLY, 16, 0xFFFF);
printf("CRC-12: %03X\n", crc_12);
printf("CRC-16: %04X\n", crc_16);
printf("CRC-CCITT: %04X\n", crc_ccitt);
return 0;
3) Develop a simple data link layer that performs the flow control using the sliding window
protocol, and loss recovery using the Go-Back-N mechanism.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#define WINDOW_SIZE 4 // Sliding window size
#define TOTAL_FRAMES 10 // Total frames to be sent
int base = 0; // Base of the window
int next_seq_num = 0; // Next sequence number
int ack = 0; // Acknowledgment tracker
pthread_mutex_t lock;
void send_frame(int frame)
printf("Sender: Sending frame %d\n", frame);
if (rand() % 5 == 0) // Simulate random frame loss
{
printf("Sender: Frame %d lost during transmission\n", frame);
else
sleep(1); // Simulate network delay
printf("Receiver: Received frame %d\n", frame);
ack = frame + 1; // Update ACK
void *sender_thread(void *arg)
while (base < TOTAL_FRAMES)
pthread_mutex_lock(&lock);
while (next_seq_num < base + WINDOW_SIZE && next_seq_num < TOTAL_FRAMES)
send_frame(next_seq_num);
next_seq_num++;
pthread_mutex_unlock(&lock);
sleep(2);
pthread_mutex_lock(&lock);
if (ack > base)
{
printf("Sender: ACK received for frame %d, moving window\n", ack - 1);
base = ack;
else
printf("Sender: Timeout! Resending from frame %d\n", base);
next_seq_num = base;
pthread_mutex_unlock(&lock);
return NULL;
int main()
srand(time(NULL));
pthread_t sender;
pthread_mutex_init(&lock, NULL);
pthread_create(&sender, NULL, sender_thread, NULL);
pthread_join(sender, NULL);
pthread_mutex_destroy(&lock);
printf("Transmission complete!\n");
return 0;
4)Implement Dijsktra’s algorithm to compute the shortest path through a network
#include <stdio.h>
#include <limits.h>
#define V 5 // Number of vertices in the graph
// Function to find the vertex with minimum distance value
int minDistance(int dist[], int sptSet[])
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (sptSet[v] == 0 && dist[v] <= min)
min = dist[v], min_index = v;
return min_index;
// Function to print the solution
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]);
// Dijkstra's algorithm implementation
void dijkstra(int graph[V][V], int src)
int dist[V]; // Output array, dist[i] holds the shortest distance from src to i
int sptSet[V]; // sptSet[i] is true if vertex i is included in shortest path tree
// Initialize all distances as INFINITE and sptSet as false
for (int i = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = 0;
// Distance from source to itself is always 0
dist[src] = 0;
// Find shortest path for all vertices
for (int count = 0; count < V - 1; count++)
int u = minDistance(dist, sptSet);
sptSet[u] = 1;
// Update dist value of the adjacent vertices
for (int v = 0; v < V; v++)
if (!sptSet[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, 10, 0, 30, 100},
{10, 0, 50, 0, 0},
{0, 50, 0, 20, 10},
{30, 0, 20, 0, 60},
{100, 0, 10, 60, 0}};
int src = 0; // Starting node
dijkstra(graph, src);
return 0;
5) Take an example subnet of hosts and obtain a broadcast tree for the subnet.
#include <stdio.h>
#include <limits.h>
#define NODES 5 // Number of nodes (hosts) in the subnet
// Function to find the minimum key value
int minKey(int key[], int mstSet[])
int min = INT_MAX, min_index;
for (int v = 0; v < NODES; v++)
if (mstSet[v] == 0 && key[v] < min)
min = key[v], min_index = v;
return min_index;
// Function to print the MST (broadcast tree)
void printTree(int parent[], int graph[NODES][NODES])
printf("Edge \tWeight\n");
for (int i = 1; i < NODES; i++)
printf("%d - %d \t%d\n", parent[i], i, graph[i][parent[i]]);
// Prim’s Algorithm to find the Minimum Spanning Tree (Broadcast Tree)
void primMST(int graph[NODES][NODES])
int parent[NODES]; // Stores the MST
int key[NODES]; // Key values to pick the minimum weight edge
int mstSet[NODES]; // To represent nodes included in MST
for (int i = 0; i < NODES; i++)
key[i] = INT_MAX, mstSet[i] = 0;
key[0] = 0; // Start with the first node
parent[0] = -1; // First node is the root of MST
for (int count = 0; count < NODES - 1; count++)
int u = minKey(key, mstSet);
mstSet[u] = 1;
for (int v = 0; v < NODES; v++)
if (graph[u][v] && mstSet[v] == 0 && graph[u][v] < key[v])
parent[v] = u, key[v] = graph[u][v];
}
}
printTree(parent, graph);
int main()
int graph[NODES][NODES] = {
{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0}};
printf("Broadcast tree (Minimum Spanning Tree) for the subnet:\n");
primMST(graph);
return 0;
Output:
Broadcast Tree (BFS Order) starting from host 0:
Host 0 -> Host 1 -> Host 2 -> Host 3 -> Host 4 -> Host 5 -> END
6) Implement distance vector routing algorithm for obtaining routing tables at each node.
#include <stdio.h>
#define INF 9999
#define MAX_NODES 5
typedef struct {
int distance[MAX_NODES]; // Distance to each node
int nextHop[MAX_NODES]; // Next hop for each node
} RoutingTable;
void distanceVectorRouting(int costMatrix[MAX_NODES][MAX_NODES]) {
RoutingTable routingTables[MAX_NODES];
int i, j, k, updated;
// Initialize routing tables
for (i = 0; i < MAX_NODES; i++) {
for (j = 0; j < MAX_NODES; j++) {
routingTables[i].distance[j] = costMatrix[i][j];
routingTables[i].nextHop[j] = (costMatrix[i][j] != INF && i != j) ? j : -1;
// Distance Vector Routing Algorithm (Bellman-Ford)
do {
updated = 0;
for (i = 0; i < MAX_NODES; i++) { // For each node
for (j = 0; j < MAX_NODES; j++) { // Destination node
for (k = 0; k < MAX_NODES; k++) { // Intermediate node
if (routingTables[i].distance[k] + routingTables[k].distance[j] <
routingTables[i].distance[j]) {
routingTables[i].distance[j] = routingTables[i].distance[k] +
routingTables[k].distance[j];
routingTables[i].nextHop[j] = k;
updated = 1;
}
}
} while (updated);
// Display the final routing tables
for (i = 0; i < MAX_NODES; i++) {
printf("Routing Table for Node %d:\n", i);
printf("Destination\tNext Hop\tDistance\n");
for (j = 0; j < MAX_NODES; j++) {
printf("%d\t\t%d\t\t%d\n", j, routingTables[i].nextHop[j], routingTables[i].distance[j]);
printf("\n");
int main() {
int costMatrix[MAX_NODES][MAX_NODES] = {
{0, 2, 5, INF, INF},
{2, 0, 3, 1, INF},
{5, 3, 0, 1, 5},
{INF, 1, 1, 0, 2},
{INF, INF, 5, 2, 0}
};
distanceVectorRouting(costMatrix);
return 0;
Output:
Routing Table for Node 0:
des Next Hop Distance
0 -1 0
1 1 2
2 1 5
3 1 3
4 3 5