1use std::net::{Ipv4Addr, Ipv6Addr};
2use crate::{Ipv4Network, Ipv6Network};
3use crate::helpers;
4
5#[cfg(target_pointer_width = "16")]
6const POINTER_WIDTH: u32 = 16;
7#[cfg(target_pointer_width = "32")]
8const POINTER_WIDTH: u32 = 32;
9#[cfg(target_pointer_width = "64")]
10const POINTER_WIDTH: u32 = 64;
11#[cfg(target_pointer_width = "128")]
12const POINTER_WIDTH: u32 = 128;
13
14pub struct Ipv4RangeIterator {
16 current: u32,
17 to: u32,
18 is_done: bool,
19}
20
21impl Ipv4RangeIterator {
22 pub fn new(from: Ipv4Addr, to: Ipv4Addr) -> Self {
43 let current = u32::from(from);
44 let to = u32::from(to);
45 assert!(to >= current);
46 Self {
47 current,
48 to,
49 is_done: false,
50 }
51 }
52
53 pub fn hosts(network: Ipv4Network) -> Self {
56 if network.netmask() >= 31 {
57 Self {
59 current: 0,
60 to: 0,
61 is_done: true,
62 }
63 } else {
64 let from = Ipv4Addr::from(u32::from(network.network_address()) + 1);
65 let to = Ipv4Addr::from(u32::from(network.broadcast_address()) - 1);
66 Self::new(from, to)
67 }
68 }
69}
70
71impl Iterator for Ipv4RangeIterator {
72 type Item = Ipv4Addr;
73
74 fn next(&mut self) -> Option<Self::Item> {
75 if self.current <= self.to && !self.is_done {
76 let output = self.current;
77
78 match self.current.checked_add(1) {
79 Some(x) => self.current = x,
80 None => self.is_done = true,
81 };
82
83 Some(Self::Item::from(output))
84 } else {
85 None
86 }
87 }
88
89 fn size_hint(&self) -> (usize, Option<usize>) {
90 if self.is_done {
91 return (0, Some(0));
92 }
93
94 let remaining = (self.to - self.current + 1) as usize;
95 (remaining, Some(remaining))
96 }
97}
98
99impl ExactSizeIterator for Ipv4RangeIterator {}
100
101pub struct Ipv4NetworkIterator {
103 current: u32,
104 to: u32,
105 new_netmask: u8,
106 is_done: bool,
107}
108
109impl Ipv4NetworkIterator {
110 pub fn new(network: Ipv4Network, new_netmask: u8) -> Self {
118 assert!(new_netmask <= Ipv4Network::LENGTH);
119
120 if network.netmask() == Ipv4Network::LENGTH || network.netmask() == new_netmask {
121 return Self {
122 current: 0,
123 to: 0,
124 new_netmask: 0,
125 is_done: true,
126 };
127 }
128
129 assert!(network.netmask() < new_netmask);
130
131 let current = u32::from(network.network_address());
132 let mask =
133 !helpers::bite_mask(32 - (new_netmask - network.netmask())) << (32 - new_netmask);
134 let to = current | mask;
135
136 Self {
137 current,
138 to,
139 new_netmask,
140 is_done: false,
141 }
142 }
143
144 fn step(&self) -> u32 {
145 1 << (32 - self.new_netmask)
146 }
147}
148
149impl Iterator for Ipv4NetworkIterator {
150 type Item = Ipv4Network;
151
152 fn next(&mut self) -> Option<Self::Item> {
153 if self.current <= self.to && !self.is_done {
154 let output = self.current;
155
156 match self.current.checked_add(self.step()) {
157 Some(x) => self.current = x,
158 None => self.is_done = true,
159 };
160
161 Some(Self::Item {
162 network_address: Ipv4Addr::from(output),
163 netmask: self.new_netmask,
164 })
165 } else {
166 None
167 }
168 }
169
170 fn size_hint(&self) -> (usize, Option<usize>) {
171 if self.is_done {
172 return (0, Some(0));
173 }
174
175 let remaining = ((self.to - self.current) / self.step() + 1) as usize;
176 (remaining, Some(remaining))
177 }
178}
179
180impl ExactSizeIterator for Ipv4NetworkIterator {}
181
182pub struct Ipv6NetworkIterator {
184 current: u128,
185 to: u128,
186 new_netmask: u8,
187 is_done: bool,
188}
189
190impl Ipv6NetworkIterator {
191 pub fn new(network: Ipv6Network, new_netmask: u8) -> Self {
199 assert!(new_netmask <= Ipv6Network::LENGTH);
200
201 if network.netmask() == Ipv6Network::LENGTH || network.netmask() == new_netmask {
202 return Self {
203 current: 0,
204 to: 0,
205 new_netmask: 0,
206 is_done: true,
207 };
208 }
209
210 assert!(network.netmask() < new_netmask);
211
212 let current = u128::from(network.network_address());
213 let mask = !helpers::bite_mask_u128(128 - (new_netmask - network.netmask()))
214 << (128 - new_netmask);
215 let to = current | mask;
216
217 Self {
218 current,
219 to,
220 new_netmask,
221 is_done: false,
222 }
223 }
224
225 fn step(&self) -> u128 {
226 1 << (128 - self.new_netmask)
227 }
228
229 pub fn real_len(&self) -> u128 {
230 if self.is_done {
231 return 0;
232 }
233
234 ((self.to - self.current) / self.step()).saturating_add(1)
235 }
236}
237
238impl Iterator for Ipv6NetworkIterator {
239 type Item = Ipv6Network;
240
241 fn next(&mut self) -> Option<Self::Item> {
242 if self.current <= self.to && !self.is_done {
243 let output = self.current;
244
245 match self.current.checked_add(self.step()) {
246 Some(x) => self.current = x,
247 None => self.is_done = true,
248 };
249
250 Some(Self::Item {
251 network_address: Ipv6Addr::from(output),
252 netmask: self.new_netmask,
253 })
254 } else {
255 None
256 }
257 }
258
259 fn size_hint(&self) -> (usize, Option<usize>) {
260 let remaining = self.real_len();
261
262 if 128 - remaining.leading_zeros() > POINTER_WIDTH {
263 (usize::MAX, None)
264 } else {
265 let remaining_u64 = remaining as u64;
266 (remaining_u64 as usize, Some(remaining_u64 as usize))
267 }
268 }
269}
270
271impl ExactSizeIterator for Ipv6NetworkIterator {}
272
273#[cfg(test)]
274mod tests {
275 use std::net::{Ipv4Addr, Ipv6Addr};
276 use crate::{Ipv4Network, Ipv6Network};
277 use super::{Ipv4NetworkIterator, Ipv4RangeIterator, Ipv6NetworkIterator};
278
279 #[test]
280 fn ipv4_range_iterator() {
281 let mut iterator = Ipv4RangeIterator::new(
282 Ipv4Addr::new(192, 168, 2, 0),
283 Ipv4Addr::new(192, 168, 2, 255),
284 );
285 assert_eq!(iterator.next().unwrap(), Ipv4Addr::new(192, 168, 2, 0));
286 assert_eq!(iterator.next().unwrap(), Ipv4Addr::new(192, 168, 2, 1));
287 assert_eq!(iterator.last().unwrap(), Ipv4Addr::new(192, 168, 2, 255));
288 }
289
290 #[test]
291 fn ipv4_range_iterator_length() {
292 let mut iterator = Ipv4RangeIterator::new(
293 Ipv4Addr::new(192, 168, 2, 0),
294 Ipv4Addr::new(192, 168, 2, 255),
295 );
296 assert_eq!(iterator.len(), 256);
297 iterator.next().unwrap();
298 assert_eq!(iterator.len(), 255);
299 assert_eq!(iterator.collect::<Vec<_>>().len(), 255);
300 }
301
302 #[test]
303 fn ipv4_range_iterator_same_values() {
304 let mut iterator = Ipv4RangeIterator::new(
305 Ipv4Addr::new(255, 255, 255, 255),
306 Ipv4Addr::new(255, 255, 255, 255),
307 );
308 assert_eq!(iterator.len(), 1);
309 assert_eq!(iterator.next().unwrap(), Ipv4Addr::new(255, 255, 255, 255));
310 assert!(iterator.next().is_none());
311 assert_eq!(iterator.len(), 0);
312 }
313
314 #[test]
315 fn ipv4_network_iterator() {
316 let network = Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 8).unwrap();
317 let mut iterator = Ipv4NetworkIterator::new(network, 16);
318
319 assert_eq!(iterator.len(), 256);
320 assert_eq!(
321 iterator.next().unwrap(),
322 Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 16).unwrap()
323 );
324 assert_eq!(
325 iterator.next().unwrap(),
326 Ipv4Network::new(Ipv4Addr::new(127, 1, 0, 0), 16).unwrap()
327 );
328 assert_eq!(
329 iterator.next().unwrap(),
330 Ipv4Network::new(Ipv4Addr::new(127, 2, 0, 0), 16).unwrap()
331 );
332 assert_eq!(
333 iterator.last().unwrap(),
334 Ipv4Network::new(Ipv4Addr::new(127, 255, 0, 0), 16).unwrap()
335 );
336 }
337
338 #[test]
339 fn ipv4_network_iterator_empty() {
340 let network = Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 32).unwrap();
341 let iterator = Ipv4NetworkIterator::new(network, 32);
342 assert_eq!(0, iterator.len());
343 }
344
345 #[test]
346 fn ipv6_network_iterator() {
347 let ip = Ipv6Addr::new(0x2001, 0, 0, 0, 0, 0, 0, 0);
348 let network = Ipv6Network::new(ip, 16).unwrap();
349 let mut iterator = Ipv6NetworkIterator::new(network, 17);
350
351 assert_eq!(2, iterator.len());
352 assert_eq!(iterator.next().unwrap(), Ipv6Network::new(ip, 17).unwrap());
353 assert_eq!(
354 iterator.next().unwrap(),
355 Ipv6Network::new(Ipv6Addr::new(0x2001, 0x8000, 0, 0, 0, 0, 0, 0), 17).unwrap()
356 );
357 assert!(iterator.next().is_none());
358 }
359
360 #[test]
361 #[should_panic] #[cfg(not(miri))] fn ipv6_network_iterator_whole_range_len() {
364 let ip = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
365 let network = Ipv6Network::new(ip, 0).unwrap();
366 let iterator = Ipv6NetworkIterator::new(network, 128);
367
368 iterator.len();
369 }
370
371 #[test]
372 fn ipv6_network_iterator_whole_range_real_len() {
373 let ip = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
374 let network = Ipv6Network::new(ip, 0).unwrap();
375 let iterator = Ipv6NetworkIterator::new(network, 128);
376
377 assert_eq!(iterator.real_len(), u128::MAX);
378 }
379
380 #[test]
381 fn ipv6_network_iterator_whole_range() {
382 let ip = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
383 let network = Ipv6Network::new(ip, 0).unwrap();
384 let mut iterator = Ipv6NetworkIterator::new(network, 128);
385
386 assert_eq!(
387 iterator.next().unwrap(),
388 Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128).unwrap()
389 );
390 assert_eq!(
391 iterator.next().unwrap(),
392 Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 128).unwrap()
393 );
394 }
395}