1pub 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
27pub 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
44pub 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
66pub 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
88pub 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}