Added new functionality to Network and changed error handling to be a single enum. create_subnet() is still WIP
This commit is contained in:
parent
a067a3e349
commit
e1a978cb1f
@ -1,4 +1,5 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use super::NetworkingErr;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct InvalidIPErr;
|
pub struct InvalidIPErr;
|
||||||
@ -12,7 +13,7 @@ pub struct InvalidIPErr;
|
|||||||
/// IpAddr::V6(String::from("::1"))
|
/// IpAddr::V6(String::from("::1"))
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[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)
|
||||||
@ -30,7 +31,7 @@ impl ToString for IpAddr {
|
|||||||
|
|
||||||
|
|
||||||
impl FromStr for IpAddr {
|
impl FromStr for IpAddr {
|
||||||
type Err = InvalidIPErr;
|
type Err = NetworkingErr;
|
||||||
/// Function that generates a IpAddr / Err from a string
|
/// Function that generates a IpAddr / Err from a string
|
||||||
///
|
///
|
||||||
/// # Limitation
|
/// # Limitation
|
||||||
@ -46,18 +47,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(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(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(InvalidIPErr)
|
Err(_) => return Err(NetworkingErr::InvalidIPErr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(IpAddr::V4(ip[0],ip[1],ip[2],ip[3]))
|
Ok(IpAddr::V4(ip[0],ip[1],ip[2],ip[3]))
|
||||||
@ -106,6 +107,6 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
let ip = "127.0.0.0.1";
|
let ip = "127.0.0.0.1";
|
||||||
IpAddr::from_str(ip).unwrap();
|
IpAddr::from_str(ip).unwrap();
|
||||||
assert_eq!(IpAddr::from_str(ip), Err(InvalidIPErr))
|
assert_eq!(IpAddr::from_str(ip), Err(NetworkingErr::InvalidIPErr))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,49 +3,95 @@ use ip::IpAddr;
|
|||||||
|
|
||||||
pub mod ip;
|
pub mod ip;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[allow(dead_code)]
|
||||||
pub struct InvalidCIDRErr;
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
pub enum NetworkingErr {
|
||||||
|
InvalidCIDRErr,
|
||||||
|
InvalidSubnetMask,
|
||||||
|
InvalidNetwork,
|
||||||
|
InvalidIPErr
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub struct Network {
|
pub struct Network {
|
||||||
network_address: IpAddr,
|
network_address: IpAddr,
|
||||||
broadcast_addr: IpAddr,
|
broadcast_addr: IpAddr,
|
||||||
|
num_hosts: u32,
|
||||||
subnet_mask: Option<IpAddr>
|
subnet_mask: Option<IpAddr>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Network {
|
impl Network {
|
||||||
// pub fn new(given_address: &IpAddr, CIDR: u8) -> Network {
|
|
||||||
|
|
||||||
// }
|
#[allow(unused)]
|
||||||
|
/// Function that constucts a network struct.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let network = Network::new(&IpAddr::V4(127, 0, 0, 1), 32);
|
||||||
|
/// ```
|
||||||
|
pub fn new(given_address: &IpAddr, subnet_mask: &IpAddr) -> Network {
|
||||||
|
Network {
|
||||||
|
network_address: given_address.clone(),
|
||||||
|
broadcast_addr: given_address.clone(),
|
||||||
|
num_hosts: 0,
|
||||||
|
subnet_mask: Some(subnet_mask.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Function that constucts a subnet, returning a vector of all subnets included
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 1), 32);
|
||||||
|
/// ```
|
||||||
|
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 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)
|
||||||
|
};
|
||||||
|
|
||||||
|
//Determine the number of networks needed for the subnet.
|
||||||
|
let num_networks = get_num_networks(network_bits);
|
||||||
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
//Get first address of each network
|
||||||
|
//Use Class constructor to generate each network.
|
||||||
|
Ok(vec![Network::new(&IpAddr::V4(0, 0, 0, 0), &IpAddr::V4(0, 0, 0, 0))])
|
||||||
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let CIDR: u8 = 22
|
/// let cidr: u8 = 22
|
||||||
/// let subnet_mask: [u8; 4] = gen_subnet_mask(CIDR);
|
/// let subnet_mask: [u8; 4] = gen_subnet_mask(cidr);
|
||||||
///
|
///
|
||||||
/// >> IpAddr::V4(255, 255, 252, 0)
|
/// >> IpAddr::V4(255, 255, 252, 0)
|
||||||
/// ```
|
/// ```
|
||||||
pub fn gen_subnet_mask(mut CIDR: u8) -> Result<IpAddr, InvalidCIDRErr> {
|
fn gen_subnet_mask(mut cidr: u8) -> Result<IpAddr, NetworkingErr> {
|
||||||
if CIDR > 32 {
|
if cidr > 32 {
|
||||||
return Err(InvalidCIDRErr)
|
return Err(NetworkingErr::InvalidCIDRErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut oct: [u8; 4] = [0; 4];
|
let mut oct: [u8; 4] = [0; 4];
|
||||||
|
|
||||||
for octet in oct.iter_mut() {
|
for octet in oct.iter_mut() {
|
||||||
*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;
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,10 +101,14 @@ impl Network {
|
|||||||
//pub fn generate_subnets(self) -> Vec<Network> {}
|
//pub fn generate_subnets(self) -> Vec<Network> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NetworkClassBits {
|
fn get_num_networks(mut network_bits: u8) -> u8 {
|
||||||
A = 8,
|
for _ in 0..4 {
|
||||||
B = 16,
|
if (network_bits / 8) > 1 {
|
||||||
C = 24
|
network_bits -= 8;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
network_bits
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
@ -123,6 +173,6 @@ mod tests {
|
|||||||
assert_eq!(Network::gen_subnet_mask(24).unwrap(), IpAddr::V4(255, 255, 255, 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!(Network::gen_subnet_mask(4).unwrap(), IpAddr::V4(240, 0, 0, 0));
|
||||||
assert_eq!(Network::gen_subnet_mask(35).unwrap_err(), InvalidCIDRErr);
|
assert_eq!(Network::gen_subnet_mask(35).unwrap_err(), NetworkingErr::InvalidCIDRErr);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user