ipr/
ip.rs

1/// Returns a string of the ip address converted to 32 bits.
2///
3/// # Example
4/// ```
5/// match get_bit("123.123.123.123") {
6///     Ok(bit) => println!("your ip address bit is [{}].", bit),
7///     Err(_) => println!("your input is invalid.")
8/// }
9/// ```
10pub fn get_bit(ip: impl Into<String>) -> Result<String, String> {
11    let ip = ip.into();
12    let fields: Vec<&str> = ip.split(".").collect();
13    if fields.len() > 4 {
14        return Err(String::from("fileds length of ip is larger than 4"));
15    }
16    let mut bit: u32 = 0;
17    for field in fields {
18        let field = match field.parse::<u8>() {
19            Ok(field) => field,
20            Err(_) => return Err(String::from("failed parse")),
21        };
22        bit = bit << 8 ^ field as u32;
23    }
24    Ok(format!("{:0>32b}", bit))
25}
26
27/// Returns the subnet mask of the prefix.
28///
29/// # Example
30/// ```
31/// match get_subnet_mask(16) {
32///     Ok(subnet) => println!("your subnet mask is [{}].", subnet),
33///     Err(_) => println!("your input is invalid.")
34/// }
35/// ```
36pub fn get_subnet_mask(prefix: u8) -> Result<String, String> {
37    if prefix > 32 {
38        return Err(String::from("mask_bit must be less than or equal to 32"));
39    }
40    let mask_bit = format!("{:0<32}", "1".repeat(prefix as usize));
41    make_address(mask_bit)
42}
43
44/// Returns the network address of the ip address and prefix.
45///
46/// # Example
47/// ```
48/// match get_network_address("123.123.123.123", 16) {
49///     Ok(address) => println!("your network address is [{}].", address),
50///     Err(_) => println!("your input is invalid.")
51/// }
52/// ```
53pub fn get_network_address(ip: impl Into<String>, prefix: u8) -> Result<String, String> {
54    if prefix > 32 {
55        return Err(String::from("mask_bit must be less than or equal to 32"));
56    }
57    let ip_bit = match get_bit(ip) {
58        Ok(bit) => bit,
59        Err(e) => return Err(e),
60    };
61    let network_bit = &ip_bit[..prefix as usize];
62    let mask_bit = format!("{:0<32}", network_bit);
63    make_address(mask_bit)
64}
65
66/// Returns the broadcast address of the ip address and prefix.
67///
68/// # Example
69/// ```
70/// match get_broadcast_address("123.123.123.123", 16) {
71///     Ok(address) => println!("your broadcast address is [{}].", address),
72///     Err(_) => println!("your input is invalid.")
73/// }
74/// ```
75pub fn get_broadcast_address(ip: impl Into<String>, prefix: u8) -> Result<String, String> {
76    if prefix > 32 {
77        return Err(String::from("mask_bit must be less than or equal to 32"));
78    }
79    let ip_bit = match get_bit(ip) {
80        Ok(bit) => bit,
81        Err(e) => return Err(e),
82    };
83    let network_bit = &ip_bit[..prefix as usize];
84    let mask_bit = format!("{:1<32}", network_bit);
85    make_address(mask_bit)
86}
87
88/// Returns whether the ip address is included in the address space.
89///
90/// # Example
91/// ```
92/// match check_subnet("123.123.123.123", "123.123.0.0/16") {
93///     Ok(checked) => println!("Is your ip address included in the specified address space? [{}].", checked),
94///     Err(_) => println!("your input is invalid.")
95/// }
96/// ```
97pub fn check_subnet(ip: impl Into<String>, range: impl Into<String>) -> Result<bool, String> {
98    let ip = ip.into();
99    let range = range.into();
100    let v: Vec<&str> = range.split("/").collect();
101    if v.len() != 2 {
102        return Err(String::from(""));
103    };
104    let ip_bit = match get_bit(&ip) {
105        Ok(ip_bit) => ip_bit,
106        Err(e) => return Err(e),
107    };
108    let cidr_ip = match get_bit(v[0]) {
109        Ok(ip_bit) => ip_bit,
110        Err(e) => return Err(e),
111    };
112    let cidr: u8 = match v[1].parse() {
113        Ok(cidr) => cidr,
114        Err(e) => return Err(e.to_string()),
115    };
116    if 0 >= cidr || cidr > 32 {
117        return Err(String::from(
118            "cidr must be more than 0 and less than or equal to 32",
119        ));
120    }
121    let ip_bit_num = match u64::from_str_radix(&ip_bit, 2) {
122        Ok(ip_bit_num) => ip_bit_num,
123        Err(e) => return Err(e.to_string()),
124    };
125    let cidr_bit_num = match u64::from_str_radix(&cidr_ip, 2) {
126        Ok(cidr_bit_num) => cidr_bit_num,
127        Err(e) => return Err(e.to_string()),
128    };
129    Ok((ip_bit_num >> (32 - cidr)) ^ (cidr_bit_num >> (32 - cidr)) == 0)
130}
131
132fn make_address(bit: impl Into<String>) -> Result<String, String> {
133    let bit = bit.into();
134    let mut v: Vec<String> = Vec::new();
135    for i in (0..25).step_by(8) {
136        let field = match usize::from_str_radix(&bit[i..(i + 8)], 2) {
137            Ok(field) => field,
138            Err(e) => return Err(e.to_string()),
139        };
140        v.push(field.to_string());
141    }
142    Ok(v.join("."))
143}