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:
		@@ -7,6 +7,11 @@ mod networking;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[allow(unused_variables, unused_mut, unused_assignments)]
 | 
					#[allow(unused_variables, unused_mut, unused_assignments)]
 | 
				
			||||||
fn main() {
 | 
					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");
 | 
					    println!("Enter the IP and cidr for your given network");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    let ip_and_cidr: (networking::ip::IpAddr, u8);
 | 
					    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 ip::IpAddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use self::ip::InvalidIPErr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod ip;
 | 
					pub mod ip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[allow(dead_code)]
 | 
					#[allow(dead_code)]
 | 
				
			||||||
@@ -13,6 +15,7 @@ pub enum NetworkingErr {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// enum to allow the identification of the class of the network
 | 
					/// enum to allow the identification of the class of the network
 | 
				
			||||||
 | 
					#[derive(Debug, Eq, PartialEq)]
 | 
				
			||||||
enum NetworkClass {
 | 
					enum NetworkClass {
 | 
				
			||||||
    A = 8,
 | 
					    A = 8,
 | 
				
			||||||
    B = 16,
 | 
					    B = 16,
 | 
				
			||||||
@@ -54,63 +57,31 @@ impl Network {
 | 
				
			|||||||
        let subnet_mask = Network::gen_subnet_mask(cidr)?.to_arr()?;
 | 
					        let subnet_mask = Network::gen_subnet_mask(cidr)?.to_arr()?;
 | 
				
			||||||
        let network_address = network_address.to_arr()?;
 | 
					        let network_address = network_address.to_arr()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut network_bits: u8 = Default::default();
 | 
					        // Determine the network class that the given address is in. 
 | 
				
			||||||
        let mut host_bits: u8 = Default::default();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Get first address of each network
 | 
					        let networks = vec![];
 | 
				
			||||||
        //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);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(networks)
 | 
					        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.
 | 
					    /// 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(4).unwrap(), IpAddr::V4(240, 0, 0, 0));
 | 
				
			||||||
        assert_eq!(Network::gen_subnet_mask(35).unwrap_err(), NetworkingErr::InvalidCIDRErr);
 | 
					        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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user