You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.0 KiB
114 lines
3.0 KiB
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
#include "subnetting.h"
|
|
|
|
// This section of code consitutes a more Java-like version of finding a preix
|
|
// A C programmer is more likely to simply do the binary math.
|
|
const unsigned int prefix_map[9] = {0, 128, 192, 224, 240, 248, 252, 254, 255};
|
|
const int usable_hosts_map[9] = {254, 126, 62, 30, 14, 6, 2, 0, 0};
|
|
const int subnet_multiplyer[4] = {0, 8, 16, 24};
|
|
|
|
unsigned int* subnet_to_octet_array(unsigned int octets[4], char subnet_mask[16]){
|
|
sscanf(subnet_mask, "%u.%u.%u.%u", &octets[0], &octets[1], &octets[2], &octets[3]);
|
|
return octets;
|
|
}
|
|
|
|
char* prefix_to_mask(char subnet_mask[16], unsigned int prefix){
|
|
unsigned int octets[5];
|
|
for (int i = 0; i < 5; ++i){
|
|
for (int j = 8; j >= 0; --j){
|
|
if (prefix >= j){
|
|
prefix -= j;
|
|
octets[i] = prefix_map[j];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
sprintf(subnet_mask, "%u.%u.%u.%u", octets[0], octets[1], octets[2], octets[3]);
|
|
return subnet_mask;
|
|
}
|
|
|
|
int hosts_for_prefix(int prefix){
|
|
return (int)pow(2.0, (double)(32-prefix));
|
|
}
|
|
|
|
int subnets_for_prefix(int prefix){
|
|
return (int)pow(2.0, (double)(prefix%8));
|
|
}
|
|
|
|
void ui_to_octets(char addr[16], unsigned int subnet_mask){
|
|
int octets[4];
|
|
octets[0] = (subnet_mask >> 24) & 0xFF;
|
|
octets[1] = (subnet_mask >> 16) & 0xFF;
|
|
octets[2] = (subnet_mask >> 8) & 0xFF;
|
|
octets[3] = subnet_mask & 0xFF;
|
|
sprintf(addr, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
|
|
}
|
|
|
|
int prefix_for_hosts(int hosts_required){
|
|
for (int i = 32; i >= 0; --i){
|
|
if (hosts_for_prefix(i)-2 >= hosts_required){
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
char network_class(int subnet_arr[4]){
|
|
if (subnet_arr[0] != 255){
|
|
return '?';
|
|
} else if (subnet_arr[1] != 255){
|
|
return 'A';
|
|
} else if (subnet_arr[2] != 255){
|
|
return 'B';
|
|
} else if (subnet_arr[3] != 255){
|
|
return 'C';
|
|
} else {
|
|
return '?';
|
|
}
|
|
}
|
|
|
|
unsigned int octets_to_ui(char octets[16]){
|
|
int so_s[4];
|
|
unsigned int rv;
|
|
sscanf(octets, "%d.%d.%d.%d", &so_s[0], &so_s[1], &so_s[2], &so_s[3]);
|
|
rv = (so_s[0] << 24) | (so_s[1] << 16) | (so_s[2] << 8) | (so_s[3]);
|
|
return rv;
|
|
}
|
|
|
|
unsigned int bdr_addr(unsigned int ip, unsigned int subnet){
|
|
return ip | ~subnet;
|
|
}
|
|
unsigned int net_addr(unsigned int ip, unsigned int subnet){
|
|
return ip & subnet;
|
|
}
|
|
|
|
char* network_address(char result[16], char ip[16], char subnet[16]){
|
|
unsigned int num = octets_to_ui(ip) & octets_to_ui(subnet);
|
|
ui_to_octets(result, num);
|
|
return result;
|
|
}
|
|
char* broadcast_address(char result[16], char ip[16], char subnet[16]){
|
|
unsigned int bdr_add = octets_to_ui(ip) | ~octets_to_ui(subnet);
|
|
ui_to_octets(result, bdr_add);
|
|
return result;
|
|
}
|
|
|
|
|
|
char* usable_host_addresses(char result[33], char ip[16], char subnet[16]){
|
|
char slow_addrs[16];
|
|
char shigh_addrs[16];
|
|
unsigned int low_addr = net_addr(octets_to_ui(ip), octets_to_ui(subnet));
|
|
unsigned int high_addr = bdr_addr(octets_to_ui(ip), octets_to_ui(subnet));
|
|
|
|
++low_addr;
|
|
--high_addr;
|
|
|
|
ui_to_octets(slow_addrs, low_addr);
|
|
ui_to_octets(shigh_addrs, high_addr);
|
|
sprintf(result, "%s-%s", slow_addrs, shigh_addrs);
|
|
return result;
|
|
}
|