final changes

This commit is contained in:
2024-02-20 11:22:31 +05:30
parent 7fc56474a9
commit 862a02c7b3
7 changed files with 485 additions and 2 deletions

2
bitmaps_imp/README.md Normal file
View File

@@ -0,0 +1,2 @@
# bitops_in_c
bitops_in_c

187
bitmaps_imp/bitarr.c Normal file
View File

@@ -0,0 +1,187 @@
/*
* =====================================================================================
*
* Filename: bitarr.c
*
* Description:
*
* Version: 1.0
* Created: Sunday 04 March 2018 06:23:30 IST
* Revision: 1.0
* Compiler: gcc
*
* Author: Er. Abhishek Sagar, Networking Developer (AS), sachinites@gmail.com
* Company: Brocade Communications(Jul 2012- Mar 2016), Current : Juniper Networks(Apr 2017 - Present)
*
* This file is part of the SPFComputation distribution (https://github.com/sachinites).
* Copyright (c) 2017 Abhishek Sagar.
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* =====================================================================================
*/
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include "bitsop.h"
#include "bitarr.h"
#define CHAR_SIZE 8
void
init_bit_array(bit_array_t *bitarr, unsigned int n_bits){
unsigned int n_byte_blocks = n_bits/CHAR_SIZE;
if(n_bits % CHAR_SIZE)
n_byte_blocks++;
if(!bitarr->array)
bitarr->array = calloc(1, n_byte_blocks);
else
memset(bitarr->array, 0, n_byte_blocks);
bitarr->size = n_bits;
bitarr->trail_bits = n_bits % CHAR_SIZE;
}
void
set_bit(bit_array_t *bitarr, unsigned int index){
if(index >= bitarr->size){
printf("%u is out of array bounds [%u,%u]\n",
index, 0, bitarr->size -1);
return;
}
unsigned byte_block = 0,
residual_bit = 0;
byte_block = index / CHAR_SIZE;
residual_bit = index % CHAR_SIZE;
#if 0
assert(bitarr->size/CHAR_SIZE == byte_block &&
bitarr->trail_bits >= residual_bit);
#endif
char *ptr = bitarr->array + byte_block;
SET_BIT((*ptr), (CHAR_SIZE - residual_bit));
}
void
unset_bit(bit_array_t *bitarr, unsigned int index){
if(index >= bitarr->size){
printf("%u is out of array bounds [%u,%u]\n",
index, 0, bitarr->size -1);
return;
}
unsigned byte_block = 0,
residual_bit = 0;
byte_block = index / CHAR_SIZE;
residual_bit = index % CHAR_SIZE;
#if 0
assert(bitarr->size/CHAR_SIZE == byte_block &&
bitarr->trail_bits >= residual_bit);
#endif
char *ptr = bitarr->array + byte_block;
UNSET_BIT((*ptr), (CHAR_SIZE - residual_bit));
}
char
is_bit_set(bit_array_t *bitarr, unsigned int index){
if(index >= bitarr->size){
printf("%u is out of array bounds [%u,%u]\n",
index, 0, bitarr->size -1);
return 0;
}
unsigned byte_block = 0,
residual_bit = 0;
byte_block = index / CHAR_SIZE;
residual_bit = index % CHAR_SIZE;
#if 0
assert(bitarr->size/CHAR_SIZE == byte_block &&
bitarr->trail_bits >= residual_bit);
#endif
char *ptr = bitarr->array + byte_block;
return (char)(IS_BIT_SET((*ptr), (CHAR_SIZE - residual_bit)));
}
unsigned int
get_next_available_bit(bit_array_t *bitarr){
unsigned int i = 0;
for(; i < bitarr->size; i++){
if(is_bit_set(bitarr, i))
continue;
return i;
}
return 0xFFFFFFFF;
}
void
print_bit_array(bit_array_t *bitarr){
unsigned int i = 0, index = 0,
byte_blocks = 0,
residual_bits = 0;
int j = 0;
byte_blocks = bitarr->size / CHAR_SIZE;
residual_bits = bitarr->size % CHAR_SIZE;
//assert(bitarr->trail_bits >= residual_bit);
char *ptr = bitarr->array;
char byte = 0;
for( ; i < byte_blocks; i++){
byte = *(ptr+i);
for(j = 7; j >= 0; j--, index++){
printf("[%u] : %c\n", index, IS_BIT_SET(byte, j) ? '1' : '0');
}
}
if(!residual_bits)
return;
byte = *(ptr+i);
for(j = 7; j >= CHAR_SIZE - residual_bits; j--, index++){
printf("[%u] : %c\n", index, IS_BIT_SET(byte, j) ? '1' : '0');
}
}
#if 0
int
main(int argc, char **argv){
bit_array_t *arr = calloc(1, sizeof(bit_array_t));
init_bit_array(arr, 15);
set_bit(arr, 11);
set_bit(arr, 21);
set_bit(arr, 30);
set_bit(arr, 3);
set_bit(arr, 33);
print_bit_array(arr);
unset_bit(arr, 11);
print_bit_array(arr);
return 0;
}
#endif

57
bitmaps_imp/bitarr.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* =====================================================================================
*
* Filename: bitarr.h
*
* Description: Interface to Bit Array
*
* Version: 1.0
* Created: Sunday 04 March 2018 06:20:07 IST
* Revision: 1.0
* Compiler: gcc
*
* Author: Er. Abhishek Sagar, Networking Developer (AS), sachinites@gmail.com
* Company: Brocade Communications(Jul 2012- Mar 2016), Current : Juniper Networks(Apr 2017 - Present)
*
* This file is part of the BIT Array distribution (https://github.com/sachinites).
* Copyright (c) 2017 Abhishek Sagar.
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* =====================================================================================
*/
#ifndef __BIT_ARRAY__
#define __BIT_ARRAY__
typedef struct _bit_array{
unsigned int size;
char *array;
char trail_bits;
} bit_array_t;
void
init_bit_array(bit_array_t *bitarr, unsigned int size);
void
set_bit(bit_array_t *bitarr, unsigned int index);
void
unset_bit(bit_array_t *bitarr, unsigned int index);
char
is_bit_set(bit_array_t *bitarr, unsigned int index);
unsigned int
get_next_available_bit(bit_array_t *bitarr);
#endif /* __BIT_ARRAY__ */

13
bitmaps_imp/bitsop.h Normal file
View File

@@ -0,0 +1,13 @@
/* Assuming least significant bit starts from 0th bit*/
#ifndef __BITS__
#define __BITS__
#define IS_BIT_SET(n, pos) ((n & (1 << (pos))) != 0)
#define TOGGLE_BIT(n, pos) (n = n ^ (1 << (pos)))
#define COMPLEMENT(num) (num = num ^ 0xFFFFFFFF)
#define UNSET_BIT(n, pos) (n = n & ((1 << pos) ^ 0xFFFFFFFF))
#define SET_BIT(n, pos) (n = n | 1 << pos)
#endif

226
bitmaps_imp/solution.c Normal file
View File

@@ -0,0 +1,226 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <arpa/inet.h>
#include <math.h>
/* Visit website : https://csepracticals.wixsite.com/csepracticals
* Use following Links to verify the results :
* Link 1 : http://www.silisoftware.com/tools/ipconverter.php
* Link 2 : http://jodies.de/ipcalc
*
* Solution to Assignment
* Level : Intermediate to Advanced, not for Beginner Programmers
*
* How to compile and run :
* Compile : gcc -g -c solution.c -o solution.o
* Link : gcc -g solution.o -o solution -lm
* Run : ./solution
* */
/*Bit Wise operations
*
* You must be familiar with Bitwise operations done
* in C. Please understand the below Macros
* */
/*You must know the concept of Big endian and Little Endian Machines
* and what is the purpose of htonl and ntohl - Important*/
/*Standard Functions suchs as inet_pton and inet_ntop have been used to
* make life easier. Understand the use of this Function. Google them.*/
/*If you dont understand this assignment solution, you need to work on
* your C language*/
#define IS_BIT_SET(n, pos) ((n & (1 << (pos))) != 0)
#define TOGGLE_BIT(n, pos) (n = n ^ (1 << (pos)))
#define COMPLEMENT(num) (num = num ^ 0xFFFFFFFF)
#define UNSET_BIT(n, pos) (n = n & ((1 << pos) ^ 0xFFFFFFFF))
#define SET_BIT(n, pos) (n = n | 1 << pos)
#define PREFIX_LEN 15 /*Max length of IP address in A.B.C.D format*/
#define MAX_MASK_LEN 32 /*Maximum mask value in decimal notation*/
/*For example, if mask = 24 is passed as an argument,
* function should return an unsigned integer equivalent to
* below bit settings
* 11111111 11111111 11111111 00000000
* */
static unsigned int
get_mask_value_in_integer_format(char mask_value){
unsigned int mask = 0xFFFFFFFF;
char n_trail_bits = MAX_MASK_LEN - mask_value;
int i = 0;
for(; i < n_trail_bits; i++){
UNSET_BIT(mask, i);
}
return mask;
}
void
get_broadcast_address(char *ip_addr,
char mask,
char *output_buffer){
unsigned int ip_addr_integer = 0;
/*Convert ip address from A.B.C.D format to equivalent unsigned integer*/
inet_pton(AF_INET, ip_addr, &ip_addr_integer);
/* To understand below line, you need to google
* Little endian and big endian concept*/
ip_addr_integer = htonl(ip_addr_integer);
unsigned int mask_integer_format = get_mask_value_in_integer_format(mask);
/*if mask_integer_format = 11111111 11111111 11111111 00000000, then below
* fn would return 00000000 00000000 00000000 11111111*/
COMPLEMENT(mask_integer_format); /*Revere the bits*/
/*now, Perform OR-ing*/
unsigned int broadcast_addr = ip_addr_integer | mask_integer_format;
broadcast_addr = htonl(broadcast_addr);
/*convert the broadcast address from interger to A.B.C.D format*/
inet_ntop(AF_INET, &broadcast_addr, output_buffer, PREFIX_LEN + 1);
output_buffer[PREFIX_LEN] = '\0';
}
unsigned int
get_ip_integer_equivalent(char *ip_address){
unsigned int ip_addr_integer = 0;
/*Convert ip address from A.B.C.D format to equivalent unsigned integer*/
inet_pton(AF_INET, ip_address, &ip_addr_integer);
return htonl(ip_addr_integer);
}
void
get_abcd_ip_format(unsigned int ip_address,
char *output_buffer){
/*Convert an ip address from Integer to A.B.C.D format*/
inet_ntop(AF_INET, &ip_address, output_buffer, PREFIX_LEN + 1);
output_buffer[PREFIX_LEN] = '\0';
}
/*Follow the steps explained in the course*/
void
get_network_id(char *ip_address, char mask, char *output_buffer){
unsigned int mask_integer_format = get_mask_value_in_integer_format(mask);
unsigned int ip_address_integer = 0 ;
inet_pton(AF_INET, ip_address, &ip_address_integer);
unsigned int network_id = ip_address_integer & mask_integer_format;
network_id = htonl(network_id);
inet_ntop(AF_INET, &network_id, output_buffer, PREFIX_LEN + 1);
}
unsigned int
get_subnet_cardinality(char mask_value){
return pow(2, MAX_MASK_LEN - mask_value) -2 ;
}
/*Follow the steps explained in the course*/
int /*Return 0 if true, -1 if false*/
check_ip_subnet_membser_ship(char *network_id,
char mask,
char *check_ip){
unsigned int check_ip_integer = 0;
inet_pton(AF_INET, check_ip, &check_ip_integer);
unsigned int mask_integer = get_mask_value_in_integer_format(mask);
unsigned int calculated_nw_id = check_ip_integer & mask_integer;
unsigned int network_id_integer = 0;
inet_pton(AF_INET, network_id, &network_id_integer);
if(network_id_integer == check_ip_integer)
return 0;
return -1;
}
int
main(int argc, char **argv){
/*Testing get_broadcast_address()*/
{
printf("Testing Q1..\n");
char ip_address[PREFIX_LEN + 1],
output_buffer[PREFIX_LEN + 1];
memset(ip_address, 0, PREFIX_LEN + 1);
memcpy(ip_address, "192.168.2.10", strlen("192.168.2.10"));
ip_address[strlen(ip_address)] = '\0';
char mask = 24;
memset(output_buffer, 0 , PREFIX_LEN + 1);
get_broadcast_address(ip_address, mask, output_buffer);
printf("broadcast address = %s\n", output_buffer);
printf("Testing Q1 Done.\n");
}
/*Testing get_ip_integer_equivalent()*/
{
printf("Testing Q2..\n");
char ip_address[PREFIX_LEN + 1];
memset(ip_address, 0, PREFIX_LEN + 1);
memcpy(ip_address, "192.168.2.10", strlen("192.168.2.10"));
ip_address[strlen(ip_address)] = '\0';
unsigned int a = get_ip_integer_equivalent(ip_address);
printf("a = %u\n", a);
printf("Testing Q2 Done.\n");
}
/*Testing get_abcd_ip_format()*/
{
char output_buffer[PREFIX_LEN + 1];
memset(output_buffer, 0 , PREFIX_LEN + 1);
unsigned int a = 2058138165;
printf("Testing Q3..\n");
get_abcd_ip_format(htonl(a), output_buffer);
printf("IP address in A.B.C.D format = %s\n", output_buffer);
printf("Testing Q3 Done.\n");
}
/*Testing get_network_id()*/
{
printf("Testing Q4..\n");
char ip_address[PREFIX_LEN + 1],
output_buffer[PREFIX_LEN + 1];
memset(ip_address, 0, PREFIX_LEN + 1);
memcpy(ip_address, "192.168.2.10", strlen("192.168.2.10"));
ip_address[strlen(ip_address)] = '\0';
char mask = 20;
memset(output_buffer, 0 , PREFIX_LEN + 1);
get_network_id(ip_address, mask, output_buffer);
printf("Network Id = %s/%u\n", output_buffer, mask);
printf("Testing Q4 Done.\n");
}
/*Testing get_subnet_cardinality() */
{
printf("Testing Q5..\n");
char mask = 24;
printf("Cardinality = %u\n", get_subnet_cardinality(mask));
printf("Testing Q5 Done.\n");
}
{
/*Testing check_ip_subnet_membser_ship()*/
printf("Testing Q6..\n");
char network_id[PREFIX_LEN + 1];
strncpy(network_id, "192.168.1.0", strlen("192.168.1.0"));
network_id[PREFIX_LEN] = '\0';
char mask = 24;
char ip_address[PREFIX_LEN + 1];
strncpy(ip_address, "192.168.1.10", strlen("192.168.1.10"));
int res = check_ip_subnet_membser_ship(network_id, mask, ip_address);
printf("IP Subnet check Result = %s\n", res == 0 ? "Membership true": "Membership false");
printf("Testing Q6 Done.\n");
}
return 0;
}

Submodule bitops_in_c deleted from 324696cae0

Submodule gl_thread deleted from 12c21f8492