Used cargo fmt

This commit is contained in:
Luke Else 2023-08-05 13:24:09 +01:00
parent aeae3af5e6
commit 53837d7b33
2 changed files with 220 additions and 129 deletions

View File

@ -1,17 +1,17 @@
use std::str::FromStr;
use super::NetworkingErr; use super::NetworkingErr;
use std::str::FromStr;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct InvalidIPErr; pub struct InvalidIPErr;
/// Ip address enum that includes associated type /// Ip address enum that includes associated type
/// ///
/// # Example /// # Example
/// ``` /// ```
/// //Loopback Addresses: /// //Loopback Addresses:
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// use std::str::FromStr; /// use std::str::FromStr;
/// ///
/// IpAddr::V4(127, 0, 0, 1); /// IpAddr::V4(127, 0, 0, 1);
/// IpAddr::V6(String::from("::1")); /// IpAddr::V6(String::from("::1"));
/// ``` /// ```
@ -19,44 +19,42 @@ pub struct InvalidIPErr;
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum IpAddr { pub enum IpAddr {
V4(u8, u8, u8, u8), V4(u8, u8, u8, u8),
V6(String) V6(String),
} }
impl IpAddr { impl IpAddr {
/// Function that generates ar array of 4 octets / error /// Function that generates ar array of 4 octets / error
/// from an IpAddr /// from an IpAddr
/// ///
/// # Limitation /// # Limitation
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// ///
/// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1); /// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1);
/// ///
/// let ip_add: [u8; 4] = ip.to_arr().unwrap(); /// let ip_add: [u8; 4] = ip.to_arr().unwrap();
/// assert_eq!(ip_add, [127, 0, 0, 1]); /// assert_eq!(ip_add, [127, 0, 0, 1]);
/// ``` /// ```
pub fn to_arr(&self) -> Result<[u8; 4], NetworkingErr> { pub fn to_arr(&self) -> Result<[u8; 4], NetworkingErr> {
match self { match self {
IpAddr::V4(o1, o2, o3, o4) => { IpAddr::V4(o1, o2, o3, o4) => Ok([*o1, *o2, *o3, *o4]),
Ok([*o1, *o2, *o3, *o4]) _ => Err(NetworkingErr::InvalidIPErr),
}
_ => Err(NetworkingErr::InvalidIPErr)
} }
} }
/// Function that generates a IpAddr / Err from an array of /// Function that generates a IpAddr / Err from an array of
/// a octests /// a octests
/// ///
/// # Limitation /// # Limitation
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// ///
/// let ip_add: [u8; 4] = [127, 0, 0, 1]; /// let ip_add: [u8; 4] = [127, 0, 0, 1];
/// ///
/// let ip: IpAddr = IpAddr::from_arr(&ip_add).unwrap(); /// let ip: IpAddr = IpAddr::from_arr(&ip_add).unwrap();
/// assert_eq!(ip, IpAddr::V4(127, 0, 0, 1)); /// assert_eq!(ip, IpAddr::V4(127, 0, 0, 1));
/// ``` /// ```
@ -68,15 +66,15 @@ impl IpAddr {
impl From<IpAddr> for u32 { impl From<IpAddr> for u32 {
/// Function that converts an Ip address /// Function that converts an Ip address
/// into an Unsigned 32 bit integer. /// into an Unsigned 32 bit integer.
/// ///
/// # Limitation /// # Limitation
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// ///
/// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1); /// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1);
/// ///
/// let ip_u32: u32 = u32::from(ip); /// let ip_u32: u32 = u32::from(ip);
/// assert_eq!(ip_u32, 2130706433); /// assert_eq!(ip_u32, 2130706433);
/// ``` /// ```
@ -88,15 +86,15 @@ impl From<IpAddr> for u32 {
impl From<u32> for IpAddr { impl From<u32> for IpAddr {
/// Function that converts an Unsigned 32-bit Ip address /// Function that converts an Unsigned 32-bit Ip address
/// into an IpAddr /// into an IpAddr
/// ///
/// # Limitation /// # Limitation
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// ///
/// let ip: u32 = 2_130_706_433; /// let ip: u32 = 2_130_706_433;
/// ///
/// let ip_addr: IpAddr = IpAddr::from(ip); /// let ip_addr: IpAddr = IpAddr::from(ip);
/// assert_eq!(ip_addr, IpAddr::V4(127, 0, 0, 1)); /// assert_eq!(ip_addr, IpAddr::V4(127, 0, 0, 1));
/// ``` /// ```
@ -110,7 +108,7 @@ impl ToString for IpAddr {
fn to_string(&self) -> String { fn to_string(&self) -> String {
match self { match self {
IpAddr::V4(oct1, oct2, oct3, oct4) => format!("{}.{}.{}.{}", oct1, oct2, oct3, oct4), IpAddr::V4(oct1, oct2, oct3, oct4) => format!("{}.{}.{}.{}", oct1, oct2, oct3, oct4),
IpAddr::V6(addr) => format!("{}", addr) IpAddr::V6(addr) => format!("{}", addr),
} }
} }
} }
@ -118,16 +116,16 @@ impl ToString for IpAddr {
impl FromStr for IpAddr { impl FromStr for IpAddr {
type Err = NetworkingErr; type Err = NetworkingErr;
/// Function that generates a IpAddr / Err from a string /// Function that generates a IpAddr / Err from a string
/// ///
/// # Limitation /// # Limitation
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// use std::str::FromStr; /// use std::str::FromStr;
/// ///
/// let ip: &str = "127.0.0.1"; /// let ip: &str = "127.0.0.1";
/// ///
/// let parsed_ip: IpAddr = IpAddr::from_str(ip).unwrap(); /// let parsed_ip: IpAddr = IpAddr::from_str(ip).unwrap();
/// assert_eq!(parsed_ip, IpAddr::V4(127,0,0,1)); /// assert_eq!(parsed_ip, IpAddr::V4(127,0,0,1));
/// ``` /// ```
@ -135,18 +133,18 @@ impl FromStr for IpAddr {
let split_ip = s.split('.'); let split_ip = s.split('.');
if split_ip.clone().count() != 4 { if split_ip.clone().count() != 4 {
//Invalid IP address entered //Invalid IP address entered
return Err(super::NetworkingErr::InvalidIPErr) return Err(super::NetworkingErr::InvalidIPErr);
} }
let mut ip: [u8; 4] = Default::default(); let mut ip: [u8; 4] = Default::default();
//Go through each octet and ensure it can be parsed; //Go through each octet and ensure it can be parsed;
for (i, oct) in split_ip.into_iter().enumerate() { for (i, oct) in split_ip.into_iter().enumerate() {
if i > ip.len() { if i > ip.len() {
//Ip string is out of the range of the 4 octets in an IPv4 Address //Ip string is out of the range of the 4 octets in an IPv4 Address
return Err(NetworkingErr::InvalidIPErr) return Err(NetworkingErr::InvalidIPErr);
} }
match oct.parse::<u8>() { match oct.parse::<u8>() {
Ok(parsed_oct) => ip[i] = parsed_oct, Ok(parsed_oct) => ip[i] = parsed_oct,
Err(_) => return Err(NetworkingErr::InvalidIPErr) Err(_) => return Err(NetworkingErr::InvalidIPErr),
} }
} }
Ok(IpAddr::from_arr(&ip)?) Ok(IpAddr::from_arr(&ip)?)
@ -154,13 +152,13 @@ impl FromStr for IpAddr {
} }
/// Function that takes in an IP address and then prints a formatted string to the CLI /// Function that takes in an IP address and then prints a formatted string to the CLI
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::{IpAddr, print_ip}; /// use subnet_calculator::ip::{IpAddr, print_ip};
/// ///
/// let ip = IpAddr::V4(127, 0, 0, 1); /// let ip = IpAddr::V4(127, 0, 0, 1);
/// ///
/// print_ip(ip); /// print_ip(ip);
/// //Output: IP Address: 127.0.0.1 /// //Output: IP Address: 127.0.0.1
/// ``` /// ```
@ -171,7 +169,7 @@ pub fn print_ip(ip_address: IpAddr) {
mod tests { mod tests {
#[test] #[test]
/// Tests if an IP is converted to a string /// Tests if an IP is converted to a string
/// correctly using the ToString trait /// correctly using the ToString trait
fn ip_to_string() { fn ip_to_string() {
use super::*; use super::*;
@ -216,7 +214,10 @@ mod tests {
fn arr_to_ipaddr() { fn arr_to_ipaddr() {
use super::*; use super::*;
let ip_addr: [u8; 4] = [127, 0, 0, 1]; let ip_addr: [u8; 4] = [127, 0, 0, 1];
assert_eq!(IpAddr::from_arr(&ip_addr).unwrap(), IpAddr::V4(127, 0, 0, 1)); assert_eq!(
IpAddr::from_arr(&ip_addr).unwrap(),
IpAddr::V4(127, 0, 0, 1)
);
} }
#[test] #[test]
@ -226,7 +227,7 @@ mod tests {
use super::*; use super::*;
let ip = IpAddr::V4(0, 0, 0, 0); let ip = IpAddr::V4(0, 0, 0, 0);
assert_eq!(0, u32::from(ip)); assert_eq!(0, u32::from(ip));
let ip = IpAddr::V4(127, 0, 0, 1); let ip = IpAddr::V4(127, 0, 0, 1);
assert_eq!(2_130_706_433, u32::from(ip)); assert_eq!(2_130_706_433, u32::from(ip));
@ -240,12 +241,11 @@ mod tests {
#[test] #[test]
/// Tests the conversion of an u32 IPv4 Address to /// Tests the conversion of an u32 IPv4 Address to
/// an IpAddr /// an IpAddr
fn u32_to_ipaddr() fn u32_to_ipaddr() {
{
use super::*; use super::*;
let ip = u32::from(IpAddr::V4(0, 0, 0, 0)); let ip = u32::from(IpAddr::V4(0, 0, 0, 0));
assert_eq!(IpAddr::V4(0, 0, 0, 0), IpAddr::from(ip)); assert_eq!(IpAddr::V4(0, 0, 0, 0), IpAddr::from(ip));
let ip = u32::from(IpAddr::V4(127, 0, 0, 1)); let ip = u32::from(IpAddr::V4(127, 0, 0, 1));
assert_eq!(IpAddr::V4(127, 0, 0, 1), IpAddr::from(ip)); assert_eq!(IpAddr::V4(127, 0, 0, 1), IpAddr::from(ip));
@ -255,4 +255,4 @@ mod tests {
let ip = u32::from(IpAddr::V4(255, 255, 255, 255)); let ip = u32::from(IpAddr::V4(255, 255, 255, 255));
assert_eq!(IpAddr::V4(255, 255, 255, 255), IpAddr::from(ip)); assert_eq!(IpAddr::V4(255, 255, 255, 255), IpAddr::from(ip));
} }
} }

View File

@ -9,7 +9,7 @@ pub enum NetworkingErr {
InvalidCIDRErr, InvalidCIDRErr,
InvalidSubnetMask, InvalidSubnetMask,
InvalidNetwork, InvalidNetwork,
InvalidIPErr InvalidIPErr,
} }
/// enum to allow the identification of the class of the network /// enum to allow the identification of the class of the network
@ -17,7 +17,7 @@ pub enum NetworkingErr {
enum NetworkClass { enum NetworkClass {
A = 8, A = 8,
B = 16, B = 16,
C = 24 C = 24,
} }
#[allow(unused)] #[allow(unused)]
@ -36,30 +36,29 @@ pub struct Subnet {
} }
impl Network { impl Network {
#[allow(unused)] #[allow(unused)]
/// Function that constucts a network struct. /// Function that constucts a network struct.
/// ///
/// ``` /// ```
/// //Awaiting implementation before creating doctest /// //Awaiting implementation before creating doctest
/// //let network = Network::new(&IpAddr::V4(127, 0, 0, 1), 32); /// //let network = Network::new(&IpAddr::V4(127, 0, 0, 1), 32);
/// ``` /// ```
fn new(given_address: &IpAddr, broadcast_address: &IpAddr, num_hosts: u32) -> Network { fn new(given_address: &IpAddr, broadcast_address: &IpAddr, num_hosts: u32) -> Network {
Network { Network {
network_address: given_address.clone(), network_address: given_address.clone(),
broadcast_addr: broadcast_address.clone(), broadcast_addr: broadcast_address.clone(),
num_hosts, num_hosts,
} }
} }
/// Function that constucts a subnet, returning a vector of all subnets included /// Function that constucts a subnet, returning a vector of all subnets included
/// ///
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// use subnet_calculator::Network; /// use subnet_calculator::Network;
/// ///
/// let subnets = Network::create_subnet(&IpAddr::V4(127, 0, 0, 1), 16).unwrap(); /// let subnets = Network::create_subnet(&IpAddr::V4(127, 0, 0, 1), 16).unwrap();
/// ///
/// assert_eq!(subnets.networks.len(), 256); /// assert_eq!(subnets.networks.len(), 256);
/// ``` /// ```
pub fn create_subnet(network_address: &IpAddr, cidr: u8) -> Result<Subnet, NetworkingErr> { pub fn create_subnet(network_address: &IpAddr, cidr: u8) -> Result<Subnet, NetworkingErr> {
@ -69,17 +68,17 @@ impl Network {
// If the CIDR < class network enum associated value, then there is an invalid subnet. // If the CIDR < class network enum associated value, then there is an invalid subnet.
if cidr < network_class as u8 { if cidr < network_class as u8 {
return Err(NetworkingErr::InvalidCIDRErr) return Err(NetworkingErr::InvalidCIDRErr);
} }
// Determine the starting network // Determine the starting network
let mut base_network = network_address.clone(); let mut base_network = network_address.clone();
let most_sig_octet: u8 = match network_class { let most_sig_octet: u8 = match network_class {
NetworkClass::A => 1, NetworkClass::A => 1,
NetworkClass::B => 2, NetworkClass::B => 2,
NetworkClass::C => 3 NetworkClass::C => 3,
}; };
for i in most_sig_octet..4 { for i in most_sig_octet..4 {
base_network[i as usize] = 0; base_network[i as usize] = 0;
} }
@ -99,24 +98,32 @@ impl Network {
// Determine how many networks are available // Determine how many networks are available
// We know that this value is >0 at this point // We know that this value is >0 at this point
let num_networks = u32::pow(2, num_borrowed_bits as u32); let num_networks = u32::pow(2, num_borrowed_bits as u32);
// The broadcast address will always be 1 less than the next subnet network address // The broadcast address will always be 1 less than the next subnet network address
let mut broadcast_addr = (base_addr + addr_increment) - 1; let mut broadcast_addr = (base_addr + addr_increment) - 1;
//Create the subnets //Create the subnets
let mut subnet = Subnet::new(&IpAddr::from(base_addr), &IpAddr::from(broadcast_addr), num_hosts, cidr)?; let mut subnet = Subnet::new(
&IpAddr::from(base_addr),
&IpAddr::from(broadcast_addr),
num_hosts,
cidr,
)?;
// Determine the networking gaps // Determine the networking gaps
//If there is only 1 network, returning the base network will be sufficient //If there is only 1 network, returning the base network will be sufficient
if num_networks > 1 { if num_networks > 1 {
for _ in 0..num_networks - 1 {
for _ in 0..num_networks-1 {
//Increment address and append to list //Increment address and append to list
base_addr += addr_increment; base_addr += addr_increment;
// We can start adding the full subnet range now instead of 1 less // We can start adding the full subnet range now instead of 1 less
broadcast_addr += addr_increment; broadcast_addr += addr_increment;
subnet.networks.push(Network::new(&IpAddr::from(base_addr), &IpAddr::from(broadcast_addr), num_hosts)); subnet.networks.push(Network::new(
&IpAddr::from(base_addr),
&IpAddr::from(broadcast_addr),
num_hosts,
));
} }
} }
@ -124,39 +131,39 @@ impl Network {
} }
/// Function that is used to determine the class of network that an IP is in. /// Function that is used to determine the class of network that an IP is in.
/// ///
/// ```ignore /// ```ignore
/// use subnet_calculator::Network; /// use subnet_calculator::Network;
/// ///
/// let network_class = Network::get_network_class(&[127, 0, 0, 1]).unwrap(); /// let network_class = Network::get_network_class(&[127, 0, 0, 1]).unwrap();
/// assert_eq!(network_class, NetworkClass::A); /// assert_eq!(network_class, NetworkClass::A);
/// ``` /// ```
fn get_network_class(network_address: &IpAddr) -> Result<NetworkClass, NetworkingErr> { fn get_network_class(network_address: &IpAddr) -> Result<NetworkClass, NetworkingErr> {
let network_address = network_address.to_arr()?; let network_address = network_address.to_arr()?;
if network_address[0] > 224 { if network_address[0] > 224 {
return Err(NetworkingErr::InvalidIPErr) return Err(NetworkingErr::InvalidIPErr);
}else if network_address[0] >= 192 { } else if network_address[0] >= 192 {
return Ok(NetworkClass::C) return Ok(NetworkClass::C);
}else if network_address[0] >= 128 { } else if network_address[0] >= 128 {
return Ok(NetworkClass::B) return Ok(NetworkClass::B);
}else if network_address[0] >= 1 { } else if network_address[0] >= 1 {
return Ok(NetworkClass::A); return Ok(NetworkClass::A);
} }
return Err(NetworkingErr::InvalidIPErr) return Err(NetworkingErr::InvalidIPErr);
} }
#[allow(unused)] #[allow(unused)]
/// 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.
/// ///
/// ```ignore /// ```ignore
/// let cidr: u8 = 22; /// let cidr: u8 = 22;
/// let subnet_mask: [u8; 4] = gen_subnet_mask(cidr).unwrap(); /// let subnet_mask: [u8; 4] = gen_subnet_mask(cidr).unwrap();
/// ///
/// assert_eq!(subnet_mask, IpAddr::V4(255, 255, 252, 0)); /// assert_eq!(subnet_mask, IpAddr::V4(255, 255, 252, 0));
/// ``` /// ```
fn gen_subnet_mask(mut cidr: u8) -> Result<IpAddr, NetworkingErr> { fn gen_subnet_mask(mut cidr: u8) -> Result<IpAddr, NetworkingErr> {
if cidr > 32 { if cidr > 32 {
return Err(NetworkingErr::InvalidCIDRErr) return Err(NetworkingErr::InvalidCIDRErr);
} }
let mut oct: [u8; 4] = [0; 4]; let mut oct: [u8; 4] = [0; 4];
@ -165,10 +172,10 @@ impl Network {
*octet = if usize::from(cidr) >= 8 { *octet = if usize::from(cidr) >= 8 {
cidr -= 8; cidr -= 8;
u8::MAX u8::MAX
}else{ } else {
// Count the number of remaining 1s and convert to binary // Count the number of remaining 1s and convert to binary
let mut count: u8 = 0; let mut count: u8 = 0;
for i in ((8-cidr)..8).rev() { for i in ((8 - cidr)..8).rev() {
count += u8::pow(2, u32::from(i)); count += u8::pow(2, u32::from(i));
} }
cidr = 0; cidr = 0;
@ -181,22 +188,22 @@ impl Network {
//pub fn generate_subnets(self) -> Vec<Network> {} //pub fn generate_subnets(self) -> Vec<Network> {}
} }
/// Function that takes in a string reference and returns the result of splitting a string into /// Function that takes in a string reference and returns the result of splitting a string into
/// both its Address and CIDR /// both its Address and CIDR
/// ///
/// ``` /// ```
/// use subnet_calculator::ip_and_cidr_from_string; /// use subnet_calculator::ip_and_cidr_from_string;
/// use subnet_calculator::ip::IpAddr; /// use subnet_calculator::ip::IpAddr;
/// ///
/// let ip_string = String::from("192.168.0.1/24"); /// let ip_string = String::from("192.168.0.1/24");
/// let result = match ip_and_cidr_from_string(&ip_string) { /// let result = match ip_and_cidr_from_string(&ip_string) {
/// Err(_) => panic!(), /// Err(_) => panic!(),
/// Ok(ip_and_cidr) => ip_and_cidr /// Ok(ip_and_cidr) => ip_and_cidr
/// }; /// };
/// ///
/// assert_eq!(result, (IpAddr::V4(192, 168, 0, 1), 24)); /// assert_eq!(result, (IpAddr::V4(192, 168, 0, 1), 24));
/// ``` /// ```
pub fn ip_and_cidr_from_string(ip_and_cidr: &String) -> Result<(IpAddr, u8), ip::InvalidIPErr>{ pub fn ip_and_cidr_from_string(ip_and_cidr: &String) -> Result<(IpAddr, u8), ip::InvalidIPErr> {
let mut cidr: u8 = Default::default(); let mut cidr: u8 = Default::default();
let mut ip: String = Default::default(); let mut ip: String = Default::default();
@ -205,34 +212,42 @@ pub fn ip_and_cidr_from_string(ip_and_cidr: &String) -> Result<(IpAddr, u8), ip:
if split_ip_cidr.clone().count() > 2 { if split_ip_cidr.clone().count() > 2 {
return Err(ip::InvalidIPErr); return Err(ip::InvalidIPErr);
} }
ip = split_ip_cidr.clone().into_iter().next().unwrap_or("0.0.0.0").to_owned(); ip = split_ip_cidr
.clone()
.into_iter()
.next()
.unwrap_or("0.0.0.0")
.to_owned();
cidr = match split_ip_cidr.into_iter().last() { cidr = match split_ip_cidr.into_iter().last() {
None => return Err(ip::InvalidIPErr), None => return Err(ip::InvalidIPErr),
Some(cidr) => match cidr.trim().parse::<u8>() { Some(cidr) => match cidr.trim().parse::<u8>() {
Err(_) => return Err(ip::InvalidIPErr), Err(_) => return Err(ip::InvalidIPErr),
Ok(cidr) => cidr Ok(cidr) => cidr,
} },
}; };
} }
let ip_address: IpAddr = match IpAddr::from_str(&ip.trim()) { let ip_address: IpAddr = match IpAddr::from_str(&ip.trim()) {
Err(_) => return Err(ip::InvalidIPErr), Err(_) => return Err(ip::InvalidIPErr),
Ok(ip) => ip, Ok(ip) => ip,
}; };
return Ok((ip_address, cidr)) return Ok((ip_address, cidr));
} }
impl Subnet { impl Subnet {
/// Function to return a new subbet struct /// Function to return a new subbet struct
/// ///
fn new(base_address: &IpAddr, broadcast_addr: &IpAddr, num_hosts: u32, cidr: u8) -> Result<Subnet, NetworkingErr> { fn new(
Ok( base_address: &IpAddr,
Subnet { broadcast_addr: &IpAddr,
networks: vec![Network::new(base_address, broadcast_addr, num_hosts)], num_hosts: u32,
subnet_mask: Network::gen_subnet_mask(cidr)?, cidr: u8,
} ) -> Result<Subnet, NetworkingErr> {
) Ok(Subnet {
networks: vec![Network::new(base_address, broadcast_addr, num_hosts)],
subnet_mask: Network::gen_subnet_mask(cidr)?,
})
} }
} }
@ -245,7 +260,7 @@ mod tests {
let ip_string = String::from("127.0.0.1/8"); let ip_string = String::from("127.0.0.1/8");
let result = match ip_and_cidr_from_string(&ip_string) { let result = match ip_and_cidr_from_string(&ip_string) {
Err(_) => panic!(), Err(_) => panic!(),
Ok(ip_and_cidr) => ip_and_cidr Ok(ip_and_cidr) => ip_and_cidr,
}; };
assert_eq!(result.0, IpAddr::V4(127, 0, 0, 1)); assert_eq!(result.0, IpAddr::V4(127, 0, 0, 1));
assert_eq!(result.1, 8); assert_eq!(result.1, 8);
@ -255,61 +270,137 @@ mod tests {
fn cidr_to_ip_test() { fn cidr_to_ip_test() {
use super::*; use super::*;
assert_eq!(Network::gen_subnet_mask(22).unwrap(), IpAddr::V4(255, 255, 252, 0)); assert_eq!(
assert_eq!(Network::gen_subnet_mask(24).unwrap(), IpAddr::V4(255, 255, 255, 0)); Network::gen_subnet_mask(22).unwrap(),
IpAddr::V4(255, 255, 252, 0)
);
assert_eq!(
Network::gen_subnet_mask(24).unwrap(),
IpAddr::V4(255, 255, 255, 0)
);
assert_eq!(Network::gen_subnet_mask(0).unwrap(), IpAddr::V4(0, 0, 0, 0)); assert_eq!(Network::gen_subnet_mask(0).unwrap(), IpAddr::V4(0, 0, 0, 0));
assert_eq!(Network::gen_subnet_mask(4).unwrap(), IpAddr::V4(240, 0, 0, 0)); assert_eq!(
assert_eq!(Network::gen_subnet_mask(35).unwrap_err(), NetworkingErr::InvalidCIDRErr); Network::gen_subnet_mask(4).unwrap(),
IpAddr::V4(240, 0, 0, 0)
);
assert_eq!(
Network::gen_subnet_mask(35).unwrap_err(),
NetworkingErr::InvalidCIDRErr
);
} }
#[test] #[test]
fn network_class_test() { fn network_class_test() {
use super::*; use super::*;
assert_eq!(Network::get_network_class(&IpAddr::V4(127, 0, 0, 1)).unwrap(), NetworkClass::A); assert_eq!(
assert_eq!(Network::get_network_class(&IpAddr::V4(172, 6, 8, 10)).unwrap(), NetworkClass::B); Network::get_network_class(&IpAddr::V4(127, 0, 0, 1)).unwrap(),
assert_eq!(Network::get_network_class(&IpAddr::V4(192, 168, 0, 1)).unwrap(), NetworkClass::C); NetworkClass::A
assert_eq!(Network::get_network_class(&IpAddr::V4(10, 6, 8, 10)).unwrap(), NetworkClass::A); );
assert_eq!(Network::get_network_class(&IpAddr::V4(225, 255, 255, 255)).unwrap_err(), NetworkingErr::InvalidIPErr); assert_eq!(
assert_eq!(Network::get_network_class(&IpAddr::V4(225, 0, 0, 0)).unwrap_err(), NetworkingErr::InvalidIPErr); Network::get_network_class(&IpAddr::V4(172, 6, 8, 10)).unwrap(),
assert_eq!(Network::get_network_class(&IpAddr::V4(0, 0, 0, 0)).unwrap_err(), NetworkingErr::InvalidIPErr); NetworkClass::B
assert_eq!(Network::get_network_class(&IpAddr::V4(0, 0, 0, 1)).unwrap_err(), NetworkingErr::InvalidIPErr); );
assert_eq!(
Network::get_network_class(&IpAddr::V4(192, 168, 0, 1)).unwrap(),
NetworkClass::C
);
assert_eq!(
Network::get_network_class(&IpAddr::V4(10, 6, 8, 10)).unwrap(),
NetworkClass::A
);
assert_eq!(
Network::get_network_class(&IpAddr::V4(225, 255, 255, 255)).unwrap_err(),
NetworkingErr::InvalidIPErr
);
assert_eq!(
Network::get_network_class(&IpAddr::V4(225, 0, 0, 0)).unwrap_err(),
NetworkingErr::InvalidIPErr
);
assert_eq!(
Network::get_network_class(&IpAddr::V4(0, 0, 0, 0)).unwrap_err(),
NetworkingErr::InvalidIPErr
);
assert_eq!(
Network::get_network_class(&IpAddr::V4(0, 0, 0, 1)).unwrap_err(),
NetworkingErr::InvalidIPErr
);
} }
#[test] #[test]
fn subnet_creation_test() { fn subnet_creation_test() {
use super::*; use super::*;
assert_eq!(Network::create_subnet(&IpAddr::V4(192, 168, 0, 1), 23).unwrap_err(), NetworkingErr::InvalidCIDRErr); assert_eq!(
Network::create_subnet(&IpAddr::V4(192, 168, 0, 1), 23).unwrap_err(),
NetworkingErr::InvalidCIDRErr
);
let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 1), 10).unwrap(); let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 1), 10).unwrap();
assert_eq!(networks.networks.len(), 4); assert_eq!(networks.networks.len(), 4);
let networks = Network::create_subnet(&IpAddr::V4(192, 168, 200, 1), 31).unwrap().networks; let networks = Network::create_subnet(&IpAddr::V4(192, 168, 200, 1), 31)
.unwrap()
.networks;
assert_eq!(networks.len(), 128); assert_eq!(networks.len(), 128);
assert_eq!(networks.last().unwrap().network_address, IpAddr::V4(192, 168, 200, 254)); assert_eq!(
assert_eq!(networks.last().unwrap().broadcast_addr, IpAddr::V4(192, 168, 200, 255)); networks.last().unwrap().network_address,
IpAddr::V4(192, 168, 200, 254)
);
assert_eq!(
networks.last().unwrap().broadcast_addr,
IpAddr::V4(192, 168, 200, 255)
);
assert_eq!(networks.last().unwrap().num_hosts, 2); assert_eq!(networks.last().unwrap().num_hosts, 2);
let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 0), 8).unwrap().networks; let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 0), 8)
.unwrap()
.networks;
assert_eq!(networks.len(), 1); assert_eq!(networks.len(), 1);
assert_eq!(networks.last().unwrap().network_address, IpAddr::V4(127, 0, 0, 0)); assert_eq!(
assert_eq!(networks.last().unwrap().broadcast_addr, IpAddr::V4(127, 255, 255, 255)); networks.last().unwrap().network_address,
IpAddr::V4(127, 0, 0, 0)
);
assert_eq!(
networks.last().unwrap().broadcast_addr,
IpAddr::V4(127, 255, 255, 255)
);
assert_eq!(networks.last().unwrap().num_hosts, 16_777_216); assert_eq!(networks.last().unwrap().num_hosts, 16_777_216);
let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 0), 9).unwrap().networks; let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 0), 9)
.unwrap()
.networks;
assert_eq!(networks.len(), 2); assert_eq!(networks.len(), 2);
assert_eq!(networks.first().unwrap().network_address, IpAddr::V4(127, 0, 0, 0)); assert_eq!(
assert_eq!(networks.first().unwrap().broadcast_addr, IpAddr::V4(127, 127, 255, 255)); networks.first().unwrap().network_address,
IpAddr::V4(127, 0, 0, 0)
);
assert_eq!(
networks.first().unwrap().broadcast_addr,
IpAddr::V4(127, 127, 255, 255)
);
let networks = Network::create_subnet(&IpAddr::V4(168, 20, 0, 0), 17).unwrap().networks; let networks = Network::create_subnet(&IpAddr::V4(168, 20, 0, 0), 17)
.unwrap()
.networks;
assert_eq!(networks.len(), 2); assert_eq!(networks.len(), 2);
assert_eq!(networks.last().unwrap().network_address, IpAddr::V4(168, 20, 128, 0)); assert_eq!(
assert_eq!(networks.last().unwrap().broadcast_addr, IpAddr::V4(168, 20, 255, 255)); networks.last().unwrap().network_address,
IpAddr::V4(168, 20, 128, 0)
);
assert_eq!(
networks.last().unwrap().broadcast_addr,
IpAddr::V4(168, 20, 255, 255)
);
assert_eq!(networks.last().unwrap().num_hosts, 32_768); assert_eq!(networks.last().unwrap().num_hosts, 32_768);
let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 0), 17).unwrap().networks; let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 0), 17)
.unwrap()
.networks;
assert_eq!(networks.len(), 512); assert_eq!(networks.len(), 512);
assert_eq!(networks.last().unwrap().network_address, IpAddr::V4(127, 255, 128, 0)); assert_eq!(
networks.last().unwrap().network_address,
IpAddr::V4(127, 255, 128, 0)
);
} }
} }