Added to_arr and from_arr methods to IpAddr

This commit is contained in:
2023-04-20 21:42:13 +01:00
parent 7d61265f08
commit 3b4a5ce285
2 changed files with 106 additions and 30 deletions

View File

@ -1,4 +1,4 @@
use std::{str::FromStr};
use std::str::FromStr;
use ip::IpAddr;
pub mod ip;
@ -12,7 +12,6 @@ pub enum NetworkingErr {
InvalidIPErr
}
#[allow(unused)]
pub struct Network {
network_address: IpAddr,
@ -45,28 +44,58 @@ impl Network {
/// ```
pub fn create_subnet(network_address: &IpAddr, cidr: u8) -> Result<Vec<Network>, NetworkingErr> {
//Get number of host and network bits.
let subnet_mask = match Network::gen_subnet_mask(cidr) {
Ok(ip) => ip,
Err(_) => return Err(NetworkingErr::InvalidCIDRErr)
};
let subnet_mask = Network::gen_subnet_mask(cidr)?.to_arr()?;
let network_address = network_address.to_arr()?;
let network_bits = match subnet_mask {
IpAddr::V4(oct1, oct2, oct3, oct4) => {
oct1.count_zeros() + oct2.count_zeros() + oct3.count_zeros() + oct4.count_zeros()
},
IpAddr::V6(_) => return Err(NetworkingErr::InvalidIPErr)
};
let mut network_bits: u8 = Default::default();
let mut host_bits: u8 = Default::default();
//Determine the number of networks needed for the subnet.
let num_networks = get_num_networks(network_bits);
//Get first address of each network
//Need to get the most significant octet
//Get number of bits available for host in specific octet
//Determine Spacing
let mut most_sig_octet: usize = Default::default();
for (i, oct) in subnet_mask.iter().enumerate(){
if *oct < 255 {
most_sig_octet = i;
network_bits = oct.count_ones() as u8;
break;
}
//There is no significant octet
if i >= 4 {
return Err(NetworkingErr::InvalidSubnetMask);
}
}
//Determine the number of networks needed for the subnet.
host_bits = subnet_mask.map(|o| o.count_zeros() as u8).iter().sum();
host_bits -= network_bits;
//Determine Spacing
let network_spacing = 2 ^ subnet_mask[most_sig_octet].count_ones() as u8;
//Determine number of networks in the subnet
let mut num_networks: u8 = 0;
for i in 1..network_bits {
num_networks += 2^i;
}
//Generate base address
let mut base_address = network_address;
base_address[most_sig_octet] = 255 - num_networks;
for i in most_sig_octet+1..=4 {
base_address[i] = 0;
}
//Use Class constructor to generate each network.
Ok(vec![Network::new(&IpAddr::V4(0, 0, 0, 0), &IpAddr::V4(0, 0, 0, 0))])
let mut networks = vec![];
for i in 0..num_networks {
let mut new_ip = base_address;
new_ip[most_sig_octet] += i * network_spacing;
let new_network = Network::new(&IpAddr::from_arr(&new_ip)?, &IpAddr::from_arr(&subnet_mask)?);
networks.push(new_network);
}
Ok(networks)
}
/// Function that takes in a u8 CIDR and converts it to an IP address.
@ -104,16 +133,6 @@ impl Network {
//pub fn generate_subnets(self) -> Vec<Network> {}
}
fn get_num_networks(mut network_bits: u8) -> u8 {
for _ in 0..4 {
if (network_bits / 8) > 1 {
network_bits -= 8;
continue;
}
};
network_bits
}
/// Function that takes in a string reference and returns the result of splitting a string into
/// both its Address and CIDR
///