Added to_arr and from_arr methods to IpAddr
This commit is contained in:
parent
7d61265f08
commit
3b4a5ce285
@ -19,6 +19,45 @@ pub enum IpAddr {
|
|||||||
V6(String)
|
V6(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IpAddr {
|
||||||
|
/// Function that generates ar array of 4 octets / error
|
||||||
|
/// from an IpAddr
|
||||||
|
///
|
||||||
|
/// # Limitation
|
||||||
|
/// Currently only works for IPs of type IPv4
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1);
|
||||||
|
///
|
||||||
|
/// let ip_add: [u8; 4] = ip.to_arr();
|
||||||
|
/// /// ip_add = [127, 0, 0, 1]
|
||||||
|
/// ```
|
||||||
|
pub fn to_arr(&self) -> Result<[u8; 4], NetworkingErr> {
|
||||||
|
match self {
|
||||||
|
IpAddr::V4(o1, o2, o3, o4) => {
|
||||||
|
Ok([*o1, *o2, *o3, *o4])
|
||||||
|
}
|
||||||
|
_ => Err(NetworkingErr::InvalidIPErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Function that generates a IpAddr / Err from an array of
|
||||||
|
/// a octests
|
||||||
|
///
|
||||||
|
/// # Limitation
|
||||||
|
/// Currently only works for IPs of type IPv4
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// let ip_add: [u8; 4] = [127, 0, 0, 1];
|
||||||
|
///
|
||||||
|
/// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1);
|
||||||
|
/// /// ip_add = [127, 0, 0, 1]
|
||||||
|
/// ```
|
||||||
|
pub fn from_arr(arr: &[u8; 4]) -> Result<IpAddr, NetworkingErr> {
|
||||||
|
Ok(IpAddr::V4(arr[0], arr[1], arr[2], arr[3]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToString for IpAddr {
|
impl ToString for IpAddr {
|
||||||
/// Function that returns an IP address in string form
|
/// Function that returns an IP address in string form
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
@ -29,7 +68,6 @@ 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
|
||||||
@ -85,7 +123,6 @@ mod tests {
|
|||||||
/// correctly using the ToString trait
|
/// correctly using the ToString trait
|
||||||
fn ip_to_string() {
|
fn ip_to_string() {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
let ip = IpAddr::V4(192, 168, 0, 1);
|
let ip = IpAddr::V4(192, 168, 0, 1);
|
||||||
assert_eq!(ip.to_string(), "192.168.0.1")
|
assert_eq!(ip.to_string(), "192.168.0.1")
|
||||||
}
|
}
|
||||||
@ -109,4 +146,24 @@ mod tests {
|
|||||||
IpAddr::from_str(ip).unwrap();
|
IpAddr::from_str(ip).unwrap();
|
||||||
assert_eq!(IpAddr::from_str(ip), Err(NetworkingErr::InvalidIPErr))
|
assert_eq!(IpAddr::from_str(ip), Err(NetworkingErr::InvalidIPErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
/// Tests the conversion of an IPv4 Address to
|
||||||
|
/// an array
|
||||||
|
fn ipaddr_to_arr() {
|
||||||
|
use super::*;
|
||||||
|
let mut ip_addr = IpAddr::V4(127, 0, 0, 1);
|
||||||
|
assert_eq!(ip_addr.to_arr().unwrap(), [127, 0, 0, 1]);
|
||||||
|
ip_addr = IpAddr::V6("::".to_string());
|
||||||
|
assert_eq!(ip_addr.to_arr().unwrap_err(), NetworkingErr::InvalidIPErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
/// Tests the conversion of an array to
|
||||||
|
// an IPv4 Address
|
||||||
|
fn arr_to_ipaddr() {
|
||||||
|
use super::*;
|
||||||
|
let mut ip_addr: [u8; 4] = [127, 0, 0, 1];
|
||||||
|
assert_eq!(IpAddr::from_arr(&ip_addr).unwrap(), IpAddr::V4(127, 0, 0, 1));
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use std::{str::FromStr};
|
use std::str::FromStr;
|
||||||
use ip::IpAddr;
|
use ip::IpAddr;
|
||||||
|
|
||||||
pub mod ip;
|
pub mod ip;
|
||||||
@ -12,7 +12,6 @@ pub enum NetworkingErr {
|
|||||||
InvalidIPErr
|
InvalidIPErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub struct Network {
|
pub struct Network {
|
||||||
network_address: IpAddr,
|
network_address: IpAddr,
|
||||||
@ -45,28 +44,58 @@ impl Network {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn create_subnet(network_address: &IpAddr, cidr: u8) -> Result<Vec<Network>, NetworkingErr> {
|
pub fn create_subnet(network_address: &IpAddr, cidr: u8) -> Result<Vec<Network>, NetworkingErr> {
|
||||||
//Get number of host and network bits.
|
//Get number of host and network bits.
|
||||||
let subnet_mask = match Network::gen_subnet_mask(cidr) {
|
let subnet_mask = Network::gen_subnet_mask(cidr)?.to_arr()?;
|
||||||
Ok(ip) => ip,
|
let network_address = network_address.to_arr()?;
|
||||||
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);
|
|
||||||
|
|
||||||
|
let mut network_bits: u8 = Default::default();
|
||||||
|
let mut host_bits: u8 = Default::default();
|
||||||
|
|
||||||
//Get first address of each network
|
//Get first address of each network
|
||||||
//Need to get the most significant octet
|
//Need to get the most significant octet
|
||||||
//Get number of bits available for host in specific 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 < 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
|
//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.
|
//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.
|
/// 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> {}
|
//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
|
/// 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
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user