Removed create_subnet function because of incorrect implementation, required network class to be take into account. Added network class and relevant tests
This commit is contained in:
parent
44bafbd0e6
commit
d0da5f587f
@ -7,6 +7,11 @@ mod networking;
|
||||
|
||||
#[allow(unused_variables, unused_mut, unused_assignments)]
|
||||
fn main() {
|
||||
|
||||
let networks = Network::create_subnet(&networking::ip::IpAddr::V4(127, 0, 0, 1), 23);
|
||||
if networks.is_err() {
|
||||
println!("Hello!");
|
||||
}
|
||||
println!("Enter the IP and cidr for your given network");
|
||||
|
||||
let ip_and_cidr: (networking::ip::IpAddr, u8);
|
||||
|
@ -1,6 +1,8 @@
|
||||
use std::str::FromStr;
|
||||
use std::{str::FromStr, f32::consts::E};
|
||||
use ip::IpAddr;
|
||||
|
||||
use self::ip::InvalidIPErr;
|
||||
|
||||
pub mod ip;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -13,6 +15,7 @@ pub enum NetworkingErr {
|
||||
}
|
||||
|
||||
/// enum to allow the identification of the class of the network
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum NetworkClass {
|
||||
A = 8,
|
||||
B = 16,
|
||||
@ -54,63 +57,31 @@ impl Network {
|
||||
let subnet_mask = Network::gen_subnet_mask(cidr)?.to_arr()?;
|
||||
let network_address = network_address.to_arr()?;
|
||||
|
||||
let mut network_bits: u8 = Default::default();
|
||||
let mut host_bits: u8 = Default::default();
|
||||
// Determine the network class that the given address is in.
|
||||
|
||||
//Get first address of each network
|
||||
//Need to get the most significant octet
|
||||
//Get number of bits available for host in specific octet
|
||||
let mut most_sig_octet: usize = Default::default();
|
||||
for (i, oct) in subnet_mask.iter().enumerate(){
|
||||
if *oct == 0 {
|
||||
most_sig_octet = i-1;
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
host_bits = subnet_mask[most_sig_octet].count_zeros() as u8;
|
||||
|
||||
//Determine the number of networks needed for the subnet.
|
||||
network_bits = subnet_mask.map(|o| o.count_zeros() as u8).iter().sum();
|
||||
network_bits -= host_bits;
|
||||
|
||||
//Determine Spacing -> Incorrect
|
||||
let network_spacing = u8::pow(2, subnet_mask[most_sig_octet].count_zeros()+1);
|
||||
|
||||
//Determine number of networks in the subnet
|
||||
let mut num_networks: u8 = 0;
|
||||
for i in 1..=host_bits {
|
||||
num_networks += u8::pow(2, u32::from(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.
|
||||
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);
|
||||
}
|
||||
let networks = vec![];
|
||||
Ok(networks)
|
||||
}
|
||||
|
||||
/// Function that is used to determine the class of network that an IP is in.
|
||||
///
|
||||
/// ```
|
||||
/// let network_class = Network::get_network_class(&[127, 0, 0, 1])?;
|
||||
/// >>> NetworkClass::A
|
||||
/// ```
|
||||
fn get_network_class(network_address: &[u8; 4]) -> Result<NetworkClass, NetworkingErr> {
|
||||
if network_address[0] > 224 {
|
||||
return Err(NetworkingErr::InvalidIPErr)
|
||||
}else if network_address[0] >= 192 {
|
||||
return Ok(NetworkClass::C)
|
||||
}else if network_address[0] >= 128 {
|
||||
return Ok(NetworkClass::B)
|
||||
}else if network_address[0] >= 1 {
|
||||
return Ok(NetworkClass::A);
|
||||
}
|
||||
return Err(NetworkingErr::InvalidIPErr)
|
||||
}
|
||||
|
||||
/// Function that takes in a u8 CIDR and converts it to an IP address.
|
||||
///
|
||||
/// ```
|
||||
@ -210,4 +181,17 @@ mod tests {
|
||||
assert_eq!(Network::gen_subnet_mask(4).unwrap(), IpAddr::V4(240, 0, 0, 0));
|
||||
assert_eq!(Network::gen_subnet_mask(35).unwrap_err(), NetworkingErr::InvalidCIDRErr);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_network_class() {
|
||||
use super::*;
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(127, 0, 0, 1).to_arr().unwrap()).unwrap(), NetworkClass::A);
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(172, 6, 8, 10).to_arr().unwrap()).unwrap(), NetworkClass::B);
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(192, 168, 0, 1).to_arr().unwrap()).unwrap(), NetworkClass::C);
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(10, 6, 8, 10).to_arr().unwrap()).unwrap(), NetworkClass::A);
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(225, 255, 255, 255).to_arr().unwrap()).unwrap_err(), NetworkingErr::InvalidIPErr);
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(225, 0, 0, 0).to_arr().unwrap()).unwrap_err(), NetworkingErr::InvalidIPErr);
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(0, 0, 0, 0).to_arr().unwrap()).unwrap_err(), NetworkingErr::InvalidIPErr);
|
||||
assert_eq!(Network::get_network_class(&IpAddr::V4(0, 0, 0, 1).to_arr().unwrap()).unwrap_err(), NetworkingErr::InvalidIPErr);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user