Skip to main content

iprange/
lib.rs

1//! `iprange` is a library for managing IP ranges.
2//!
3//! An [`IpRange`] is a set of networks.
4//! The type of the networks it holds is specified by the generics type of [`IpRange`].
5//!
6//! You can add or remove an [`IpNet`] from an [`IpRange`].
7//! An [`IpNet`] can be either an `Ipv4Net` or an `Ipv6Net`.
8//!
9//! It also supports these useful operations:
10//!
11//! * [`merge`]
12//! * [`intersect`]
13//! * [`exclude`]
14//!
15//! Here is a simple example:
16//!
17//! ```
18//! extern crate iprange;
19//! extern crate ipnet;
20//!
21//! use std::net::Ipv4Addr;
22//! use iprange::IpRange;
23//! use ipnet::Ipv4Net;
24//!
25//! fn main() {
26//!     let ip_range: IpRange<Ipv4Net> = ["10.0.0.0/8", "172.16.0.0/16", "192.168.1.0/24"]
27//!         .iter()
28//!         .map(|s| s.parse().unwrap())
29//!         .collect();
30//!
31//!     assert!(ip_range.contains(&"172.16.32.1".parse::<Ipv4Addr>().unwrap()));
32//!     assert!(ip_range.contains(&"192.168.1.1".parse::<Ipv4Addr>().unwrap()));
33//! }
34//! ```
35//!
36//! [`IpRange`]: struct.IpRange.html
37//! [`IpNet`]: trait.IpNet.html
38//! [`Ipv4Net`]: https://docs.rs/ipnet/1.0.0/ipnet/struct.Ipv4Net.html
39//! [`merge`]: struct.IpRange.html#method.merge
40//! [`intersect`]: struct.IpRange.html#method.intersect
41//! [`exclude`]: struct.IpRange.html#method.exclude
42
43extern crate ipnet;
44#[cfg(feature = "serde")]
45#[macro_use]
46extern crate serde;
47
48use ipnet::{Ipv4Net, Ipv6Net};
49use std::collections::VecDeque;
50use std::fmt;
51use std::iter::FromIterator;
52use std::marker::PhantomData;
53use std::net::{Ipv4Addr, Ipv6Addr};
54
55/// A set of networks that supports various operations:
56///
57/// * [`add`]
58/// * [`remove`]
59/// * [`contains`]
60/// * [`merge`]
61/// * [`intersect`]
62/// * [`exclude`]
63///
64/// `IntoIter` is implemented for `&IpRange`. So, you can use `for`
65/// to iterate over the networks in an `IpRange`:
66///
67/// ```
68/// extern crate ipnet;
69/// extern crate iprange;
70///
71/// use iprange::IpRange;
72/// use ipnet::Ipv4Net;
73///
74/// fn main() {
75///     let ip_range: IpRange<Ipv4Net> = ["172.16.0.0/16", "192.168.1.0/24"]
76///         .iter()
77///         .map(|s| s.parse().unwrap())
78///         .collect();
79///
80///     for network in &ip_range {
81///         println!("{:?}", network);
82///     }
83/// }
84/// ```
85///
86/// [`add`]: struct.IpRange.html#method.add
87/// [`remove`]: struct.IpRange.html#method.remove
88/// [`contains`]: struct.IpRange.html#method.contains
89/// [`merge`]: struct.IpRange.html#method.merge
90/// [`intersect`]: struct.IpRange.html#method.intersect
91/// [`exclude`]: struct.IpRange.html#method.exclude
92#[derive(Clone, PartialEq, Eq)]
93pub struct IpRange<N: IpNet> {
94    // IpRange uses a radix trie to store networks
95    trie: IpTrie<N>,
96    phantom_net: PhantomData<N>,
97}
98
99impl<N: IpNet> IpRange<N> {
100    /// Creates an empty `IpRange`.
101    pub fn new() -> IpRange<N> {
102        IpRange {
103            trie: IpTrie::new(),
104            phantom_net: PhantomData,
105        }
106    }
107
108    /// Add a network to `self`.
109    ///
110    /// Returns `&mut self` in order to enable method chaining.
111    ///
112    /// Pay attention that this operation will not combine two
113    /// networks automatically. To do this, call [`simplify`] method
114    /// explicitly. For example:
115    ///
116    /// ```
117    /// extern crate iprange;
118    /// extern crate ipnet;
119    ///
120    /// use iprange::IpRange;
121    /// use ipnet::Ipv4Net;
122    ///
123    /// fn main() {
124    ///     let mut ip_range: IpRange<Ipv4Net> = IpRange::new();
125    ///     ip_range.add("192.168.0.0/24".parse().unwrap())
126    ///            .add("192.168.1.0/24".parse().unwrap());
127    ///     assert_eq!(ip_range.into_iter().count(), 2);
128    ///
129    ///     ip_range.simplify();
130    ///     assert_eq!(ip_range.into_iter().count(), 1);
131    /// }
132    /// ```
133    ///
134    /// [`simplify`]: struct.IpRange.html#method.simplify
135    pub fn add(&mut self, network: N) -> &mut Self {
136        self.trie.insert(network);
137        self
138    }
139
140    /// Remove a network from `self`.
141    ///
142    /// Returns `&mut self` in order to enable method chaining.
143    ///
144    /// `self` does not necessarily has exactly the network to be removed.
145    /// The network can be a networkwork of a network in `self`.
146    /// This method will do splitting and remove the corresponding network.
147    /// For example:
148    ///
149    /// ```
150    /// extern crate iprange;
151    /// extern crate ipnet;
152    ///
153    /// use iprange::IpRange;
154    /// use ipnet::Ipv4Net;
155    ///
156    /// fn main() {
157    ///     let mut ip_range: IpRange<Ipv4Net> = IpRange::new();
158    ///     ip_range.add("192.168.0.0/23".parse().unwrap())
159    ///             .remove("192.168.0.0/24".parse().unwrap());
160    ///     // Now, ip_range has only one network: "192.168.1.0/24".
161    /// }
162    /// ```
163    pub fn remove(&mut self, network: N) -> &mut Self {
164        self.trie.remove(network);
165        self
166    }
167
168    /// Returns `true` if the `self` has no network.
169    ///
170    /// # Examples
171    /// ```
172    /// # extern crate ipnet;
173    /// #
174    /// # use iprange::IpRange;
175    /// # use ipnet::Ipv4Net;
176    /// let mut ip_range = IpRange::new();
177    /// let network: Ipv4Net = "1.0.1.0/24".parse().unwrap();
178    /// ip_range.add(network.clone());
179    /// ip_range.remove(network);
180    /// assert!(ip_range.is_empty());
181    /// ```
182    pub fn is_empty(&self) -> bool {
183        self.trie.root.is_none()
184    }
185
186    /// Simplify `self` by combining networks. For example:
187    ///
188    /// ```
189    /// extern crate iprange;
190    /// extern crate ipnet;
191    ///
192    /// use iprange::IpRange;
193    /// use ipnet::Ipv4Net;
194    ///
195    /// fn main() {
196    ///     let mut ip_range: IpRange<Ipv4Net> = IpRange::new();
197    ///     ip_range
198    ///         .add("192.168.0.0/20".parse().unwrap())
199    ///         .add("192.168.16.0/22".parse().unwrap())
200    ///         .add("192.168.20.0/24".parse().unwrap())
201    ///         .add("192.168.21.0/24".parse().unwrap())
202    ///         .add("192.168.22.0/24".parse().unwrap())
203    ///         .add("192.168.23.0/24".parse().unwrap())
204    ///         .add("192.168.24.0/21".parse().unwrap())
205    ///         .simplify();
206    ///     // Now, ip_range has only one network: "192.168.0.0/19".
207    /// }
208    /// ```
209    pub fn simplify(&mut self) {
210        self.trie.simplify();
211    }
212
213    /// Returns a new `IpRange` which contains all networks
214    /// that is either in `self` or in `other`.
215    ///
216    /// The returned `IpRange` is simplified.
217    pub fn merge(&self, other: &IpRange<N>) -> Self {
218        self.into_iter().chain(other.into_iter()).collect()
219    }
220
221    /// Returns a new `IpRange` which contains all networks
222    /// that is in both `self` and `other`.
223    ///
224    /// The returned `IpRange` is simplified.
225    pub fn intersect(&self, other: &IpRange<N>) -> Self {
226        let range1 = self.into_iter().filter(|network| other.contains(network));
227        let range2 = other.into_iter().filter(|network| self.contains(network));
228        range1.chain(range2).collect()
229    }
230
231    /// Returns a new `IpRange` which contains all networks
232    /// that is in `self` while not in `other`.
233    ///
234    /// The returned `IpRange` is simplified.
235    pub fn exclude(&self, other: &IpRange<N>) -> IpRange<N> {
236        let mut new = (*self).clone();
237        for network in other {
238            new.remove(network);
239        }
240        new
241    }
242
243    /// Tests if `self` contains `network`.
244    ///
245    /// `network` is anything that can be converted into `N`.
246    /// See `ToNetwork<N>` for detail.
247    pub fn contains<T: ToNetwork<N>>(&self, network: &T) -> bool {
248        self.supernet(&network.to_network()).is_some()
249    }
250
251    /// Returns the network in `self` which is the supernetwork of `network`.
252    ///
253    /// Returns None if no network in `self` contains `network`.
254    pub fn supernet<T: ToNetwork<N>>(&self, network: &T) -> Option<N> {
255        self.trie.search(network.to_network())
256    }
257
258    /// Returns the iterator to `&self`.
259    pub fn iter(&self) -> IpRangeIter<N> {
260        self.into_iter()
261    }
262}
263
264impl<N> Default for IpRange<N>
265where
266    N: IpNet + ToNetwork<N> + Clone,
267{
268    fn default() -> Self {
269        Self::new()
270    }
271}
272
273impl<N: IpNet> fmt::Debug for IpRange<N> {
274    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
275        let mut networks: Vec<_> = self
276            .iter()
277            .take(4)
278            .map(|net| format!("{:?}", net))
279            .collect();
280        if networks.len() == 4 {
281            networks[3] = "...".to_string();
282        }
283        write!(f, "IpRange [{}]", networks.join(", "))
284    }
285}
286
287impl<'a, N> IntoIterator for &'a IpRange<N>
288where
289    N: IpNet + ToNetwork<N> + Clone,
290{
291    type Item = N;
292    type IntoIter = IpRangeIter<'a, N>;
293
294    fn into_iter(self) -> Self::IntoIter {
295        let mut queue = VecDeque::new();
296        if let Some(root) = self.trie.root.as_ref() {
297            let state: N::S = root.init_traverse_state();
298            queue.push_back(state);
299        }
300        IpRangeIter {
301            queue,
302            _phantom: PhantomData,
303        }
304    }
305}
306
307#[cfg(feature = "serde")]
308impl<N: IpNet> serde::Serialize for IpRange<N> {
309    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
310    where
311        S: serde::Serializer,
312    {
313        serde::Serialize::serialize(&self.trie.root, serializer)
314    }
315}
316
317#[cfg(feature = "serde")]
318impl<'de, N: IpNet> serde::Deserialize<'de> for IpRange<N> {
319    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
320    where
321        D: serde::Deserializer<'de>,
322    {
323        Ok(IpRange {
324            trie: IpTrie {
325                root: serde::Deserialize::deserialize(deserializer)?,
326                phantom_net: PhantomData,
327            },
328            phantom_net: PhantomData,
329        })
330    }
331}
332
333/// An abstraction for IP networks.
334pub trait IpNet: ToNetwork<Self> + fmt::Debug + Ord + Copy
335where
336    Self: Sized,
337{
338    /// Used for internal traversing.
339    type S: TraverseState<Net = Self>;
340    ///`I` is an iterator to the prefix bits of the network.
341    type I: Iterator<Item = bool>;
342
343    /// Returns the iterator to the prefix bits of the network.
344    fn prefix_bits(&self) -> Self::I;
345
346    /// Returns the prefix length.
347    fn prefix_len(&self) -> u8;
348
349    /// Returns a copy of the network with the address truncated to the given length.
350    fn with_new_prefix(&self, len: u8) -> Self;
351}
352
353/// Anything that can be converted to `IpNet`.
354///
355/// Due to limitation of Rust's type system,
356/// this trait is only implemented for some
357/// concrete types.
358pub trait ToNetwork<N: IpNet> {
359    fn to_network(&self) -> N;
360}
361
362/// An iterator over the networks in an [`IpRange`].
363///
364/// BFS (Breadth-First-Search) is used for traversing the inner Radix Trie.
365///
366/// [`IpRange`]: struct.IpRange.html
367pub struct IpRangeIter<'a, N>
368where
369    N: IpNet,
370{
371    queue: VecDeque<N::S>,
372    _phantom: PhantomData<&'a N>,
373}
374
375/// Used for internal traversing.
376///
377/// You can simply ignore this trait.
378#[doc(hidden)]
379pub trait TraverseState {
380    type Net: IpNet;
381
382    fn node(&self) -> *const IpTrieNode;
383
384    fn init(root: &IpTrieNode) -> Self;
385
386    fn transit(&self, next_node: &IpTrieNode, current_bit: bool) -> Self;
387
388    fn build(&self) -> Self::Net;
389}
390
391impl<'a, N> Iterator for IpRangeIter<'a, N>
392where
393    N: IpNet,
394{
395    type Item = N;
396
397    fn next(&mut self) -> Option<Self::Item> {
398        while let Some(elem) = self.queue.pop_front() {
399            // Get the front element of the queue.
400            // If it is a leaf, it represents a network.
401            // SAFETY: IpRangeIter has an PhantomData<'a N> so the IpNet must
402            // exist when this iterator exists.
403            let node = unsafe { &*elem.node() };
404            if node.is_leaf() {
405                return Some(elem.build());
406            }
407            for &i in &[0, 1] {
408                if let Some(child) = node.children[i as usize].as_ref() {
409                    // Push the child nodes into the queue
410                    self.queue.push_back(elem.transit(child, i != 0));
411                }
412            }
413        }
414        None
415    }
416}
417
418impl<N> FromIterator<N> for IpRange<N>
419where
420    N: IpNet + ToNetwork<N> + Clone,
421{
422    fn from_iter<T>(iter: T) -> Self
423    where
424        T: IntoIterator<Item = N>,
425    {
426        let mut ip_range = IpRange::new();
427        for network in iter {
428            ip_range.add(network);
429        }
430        ip_range.simplify();
431        ip_range
432    }
433}
434
435#[derive(Clone, Debug, PartialEq, Eq, Default)]
436struct IpTrie<N>
437where
438    N: IpNet,
439{
440    root: Option<IpTrieNode>,
441    phantom_net: PhantomData<N>,
442}
443
444impl<N> IpTrie<N>
445where
446    N: IpNet,
447{
448    fn new() -> IpTrie<N> {
449        IpTrie {
450            root: None,
451            phantom_net: PhantomData,
452        }
453    }
454
455    fn insert(&mut self, network: N) {
456        // The current node
457        let mut node = if let Some(root) = &mut self.root {
458            if root.is_leaf() {
459                // Insert into all-zero network has no effect.
460                return;
461            }
462            root as *mut IpTrieNode
463        } else {
464            self.root = Some(IpTrieNode::new());
465            self.root.as_mut().unwrap() as *mut IpTrieNode
466        };
467
468        unsafe {
469            let bits = network.prefix_bits();
470            for bit in bits {
471                let i = bit as usize;
472                let child = &mut (*node).children[i];
473                match child {
474                    Some(child) => {
475                        if child.is_leaf() {
476                            // This means the network to be inserted
477                            // is already in the trie.
478                            return;
479                        }
480                        node = &mut **child as *mut IpTrieNode;
481                    }
482                    None => {
483                        (*node).children[i] = Some(Box::new(IpTrieNode::new()));
484                        node = (*node).children[i].as_mut().unwrap().as_mut() as *mut IpTrieNode;
485                    }
486                }
487            }
488            (*node).children = [None, None];
489        }
490    }
491
492    fn search(&self, network: N) -> Option<N> {
493        let mut node = self.root.as_ref()?;
494
495        let bits = network.prefix_bits();
496        for (j, bit) in bits.enumerate() {
497            if node.is_leaf() {
498                return Some(network.with_new_prefix(j as u8));
499            }
500
501            let i = bit as usize;
502            let child = node.children[i].as_ref();
503            match child {
504                Some(child) => node = child,
505                None => return None,
506            }
507        }
508
509        if node.is_leaf() {
510            Some(network)
511        } else {
512            None
513        }
514
515        // The commented code below is more clear. However, this uses a
516        // commented method `search` in IpTrieNode, and the performance
517        // is relatively poorer that the implementation above.
518
519        // self.root.as_ref().and_then(|root| {
520        //     let mut bits = network.prefix_bits();
521        //     let first_bit = bits.next();
522        //     root.borrow()
523        //         .search(bits, first_bit, 0)
524        //         .map(|prefix_size| {
525        //             network.with_new_prefix(prefix_size)
526        //         })
527        // })
528    }
529
530    fn remove(&mut self, network: N) {
531        if let Some(root) = self.root.as_mut() {
532            let mut bits = network.prefix_bits();
533            if let Some(next_bit) = bits.next() {
534                root.remove(bits, next_bit);
535                // If root becomes a leaf after removing the network,
536                // we should simply reinitialize the trie.
537                if !root.is_leaf() {
538                    return;
539                }
540            }
541        }
542        self.root = None // Reinitialize the trie
543    }
544
545    fn simplify(&mut self) {
546        if let Some(root) = self.root.as_mut() {
547            root.simplify();
548        }
549    }
550}
551
552/// Node of the inner radix trie.
553#[derive(Clone, Debug, PartialEq, Eq)]
554#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(transparent))]
555pub struct IpTrieNode {
556    children: [Option<Box<IpTrieNode>>; 2],
557}
558
559impl IpTrieNode {
560    fn new() -> IpTrieNode {
561        IpTrieNode {
562            children: [None, None],
563        }
564    }
565
566    #[inline]
567    fn init_traverse_state<S: TraverseState>(&self) -> S {
568        S::init(self)
569    }
570
571    // If both the zero child and the one child of a node are None,
572    // it is a leaf node, and it represents a network whose
573    // prefix is the path from root to it.
574    #[inline]
575    fn is_leaf(&self) -> bool {
576        self.children[0].is_none() && self.children[1].is_none()
577    }
578
579    // If the two children of a node are all leaf node,
580    // they can be merged into a new leaf node.
581    fn simplify(&mut self) {
582        let leaf_count: u32 = self
583            .children
584            .iter_mut()
585            .map(|child| {
586                child
587                    .as_mut()
588                    .map(|child| {
589                        child.simplify();
590                        child.is_leaf() as u32
591                    })
592                    .unwrap_or_default()
593            })
594            .sum();
595        if leaf_count == 2 {
596            self.children = [None, None];
597        }
598    }
599
600    //    fn search<I>(&self, mut bits: I, current_bit: Option<bool>, acc: u8) -> Option<u8>
601    //        where I: Iterator<Item=bool>
602    //    {
603    //        if self.is_leaf() {
604    //            Some(acc)
605    //        } else {
606    //            if let Some(current_bit) = current_bit {
607    //                if let Some(child) = self.children[current_bit as usize].clone() {
608    //                    let next_bit = bits.next();
609    //                    return child
610    //                        .borrow_mut()
611    //                        .search(bits, next_bit, acc + 1);
612    //                }
613    //            }
614    //            None
615    //        }
616    //    }
617
618    fn remove<I>(&mut self, mut bits: I, current_bit: bool)
619    where
620        I: Iterator<Item = bool>,
621    {
622        let i = current_bit as usize;
623        let next_bit = bits.next();
624
625        // If the current node is a leaf node, and we have a network
626        // to remove, we must split it into two deeper nodes.
627        if self.is_leaf() {
628            self.children = [
629                Some(Box::new(IpTrieNode::new())),
630                Some(Box::new(IpTrieNode::new())),
631            ];
632        }
633
634        match next_bit {
635            Some(next_bit) => {
636                let is_leaf = if let Some(child) = self.children[i].as_mut() {
637                    // Remove the deeper node recursively
638                    child.remove(bits, next_bit);
639                    child.is_leaf()
640                } else {
641                    false
642                };
643                // In general, a leaf node represents a complete
644                // network. However, the child node cannot be a complete
645                // network after removing a network from it.
646                // This occurring indicates the only child of the
647                // child node is removed, and now this child node
648                // should be marked None.
649                if is_leaf {
650                    self.children[i] = None;
651                }
652            }
653            None => {
654                // Remove the node that represents the network.
655                self.children[i] = None;
656            }
657        }
658    }
659}
660
661const MSO_U128: u128 = 1 << 127; // Most significant one for u128
662const MSO_U32: u32 = 1 << 31; // Most significant one for u32
663
664impl IpNet for Ipv4Net {
665    type S = Ipv4TraverseState;
666    type I = Ipv4PrefixBitIterator;
667
668    #[inline]
669    fn prefix_bits(&self) -> Self::I {
670        let prefix: u32 = self.addr().into();
671        Ipv4PrefixBitIterator {
672            prefix,
673            prefix_len: self.prefix_len(),
674        }
675    }
676
677    #[inline]
678    fn prefix_len(&self) -> u8 {
679        self.prefix_len()
680    }
681
682    #[inline]
683    fn with_new_prefix(&self, len: u8) -> Self {
684        Ipv4Net::new(self.addr(), len).unwrap().trunc()
685    }
686}
687
688impl ToNetwork<Ipv4Net> for Ipv4Net {
689    #[inline]
690    fn to_network(&self) -> Ipv4Net {
691        self.trunc()
692    }
693}
694
695impl ToNetwork<Ipv4Net> for Ipv4Addr {
696    #[inline]
697    fn to_network(&self) -> Ipv4Net {
698        Ipv4Net::new(*self, 32).unwrap()
699    }
700}
701
702impl ToNetwork<Ipv4Net> for u32 {
703    #[inline]
704    fn to_network(&self) -> Ipv4Net {
705        Ipv4Net::new((*self).into(), 32).unwrap()
706    }
707}
708
709impl ToNetwork<Ipv4Net> for [u8; 4] {
710    #[inline]
711    fn to_network(&self) -> Ipv4Net {
712        Ipv4Net::new((*self).into(), 32).unwrap()
713    }
714}
715
716#[doc(hidden)]
717pub struct Ipv4TraverseState {
718    node: *const IpTrieNode,
719    prefix: u32,
720    prefix_len: u8,
721}
722
723impl TraverseState for Ipv4TraverseState {
724    type Net = Ipv4Net;
725
726    #[inline]
727    fn node(&self) -> *const IpTrieNode {
728        self.node
729    }
730
731    #[inline]
732    fn init(root: &IpTrieNode) -> Self {
733        Ipv4TraverseState {
734            node: root,
735            prefix: 0,
736            prefix_len: 0,
737        }
738    }
739
740    #[inline]
741    fn transit(&self, next_node: &IpTrieNode, current_bit: bool) -> Self {
742        let mask = if current_bit {
743            MSO_U32 >> self.prefix_len
744        } else {
745            0
746        };
747        Ipv4TraverseState {
748            node: next_node,
749            prefix: self.prefix | mask,
750            prefix_len: self.prefix_len + 1,
751        }
752    }
753
754    #[inline]
755    fn build(&self) -> Self::Net {
756        Ipv4Net::new(self.prefix.into(), self.prefix_len as u8).unwrap()
757    }
758}
759
760#[doc(hidden)]
761pub struct Ipv4PrefixBitIterator {
762    prefix: u32,
763    prefix_len: u8,
764}
765
766impl Iterator for Ipv4PrefixBitIterator {
767    type Item = bool;
768
769    #[inline]
770    fn next(&mut self) -> Option<Self::Item> {
771        if self.prefix_len > 0 {
772            let prefix = self.prefix;
773            self.prefix <<= 1;
774            self.prefix_len -= 1;
775            Some(prefix & MSO_U32 != 0)
776        } else {
777            None
778        }
779    }
780}
781
782impl IpNet for Ipv6Net {
783    type S = Ipv6TraverseState;
784    type I = Ipv6PrefixBitIterator;
785
786    #[inline]
787    fn prefix_bits(&self) -> Self::I {
788        Ipv6PrefixBitIterator {
789            prefix: self.addr().into(),
790            prefix_len: self.prefix_len(),
791        }
792    }
793
794    #[inline]
795    fn prefix_len(&self) -> u8 {
796        self.prefix_len()
797    }
798
799    #[inline]
800    fn with_new_prefix(&self, len: u8) -> Self {
801        Ipv6Net::new(self.addr(), len).unwrap().trunc()
802    }
803}
804
805impl ToNetwork<Ipv6Net> for Ipv6Net {
806    #[inline]
807    fn to_network(&self) -> Ipv6Net {
808        self.trunc()
809    }
810}
811
812impl ToNetwork<Ipv6Net> for Ipv6Addr {
813    #[inline]
814    fn to_network(&self) -> Ipv6Net {
815        Ipv6Net::new(*self, 128).unwrap()
816    }
817}
818
819impl ToNetwork<Ipv6Net> for u128 {
820    #[inline]
821    fn to_network(&self) -> Ipv6Net {
822        Ipv6Net::new((*self).into(), 128).unwrap()
823    }
824}
825
826impl ToNetwork<Ipv6Net> for [u8; 16] {
827    #[inline]
828    fn to_network(&self) -> Ipv6Net {
829        Ipv6Net::new((*self).into(), 128).unwrap()
830    }
831}
832
833impl ToNetwork<Ipv6Net> for [u16; 8] {
834    #[inline]
835    fn to_network(&self) -> Ipv6Net {
836        Ipv6Net::new((*self).into(), 128).unwrap()
837    }
838}
839
840#[doc(hidden)]
841pub struct Ipv6TraverseState {
842    node: *const IpTrieNode,
843    prefix: u128,
844    prefix_len: u8,
845}
846
847impl TraverseState for Ipv6TraverseState {
848    type Net = Ipv6Net;
849
850    #[inline]
851    fn node(&self) -> *const IpTrieNode {
852        self.node
853    }
854
855    #[inline]
856    fn init(root: &IpTrieNode) -> Self {
857        Ipv6TraverseState {
858            node: root,
859            prefix: 0,
860            prefix_len: 0,
861        }
862    }
863
864    #[inline]
865    fn transit(&self, next_node: &IpTrieNode, current_bit: bool) -> Self {
866        let mask = if current_bit {
867            MSO_U128 >> self.prefix_len
868        } else {
869            0
870        };
871        Ipv6TraverseState {
872            node: next_node,
873            prefix: self.prefix | mask,
874            prefix_len: self.prefix_len + 1,
875        }
876    }
877
878    #[inline]
879    fn build(&self) -> Self::Net {
880        Ipv6Net::new(self.prefix.into(), self.prefix_len as u8).unwrap()
881    }
882}
883
884#[doc(hidden)]
885pub struct Ipv6PrefixBitIterator {
886    prefix: u128,
887    prefix_len: u8,
888}
889
890impl Iterator for Ipv6PrefixBitIterator {
891    type Item = bool;
892
893    #[inline]
894    fn next(&mut self) -> Option<Self::Item> {
895        if self.prefix_len > 0 {
896            let prefix = self.prefix;
897            self.prefix <<= 1;
898            self.prefix_len -= 1;
899            Some(prefix & MSO_U128 != 0)
900        } else {
901            None
902        }
903    }
904}
905
906#[cfg(test)]
907mod tests {
908    use super::*;
909
910    #[test]
911    fn parse_invalid_networks() {
912        assert!("192.168.256.130/5".parse::<Ipv4Net>().is_err());
913        assert!("192.168.5.130/-1".parse::<Ipv4Net>().is_err());
914        assert!("192.168.5.130/33".parse::<Ipv4Net>().is_err());
915        assert!("192.168.5.33".parse::<Ipv4Net>().is_err());
916        assert!("192.168.5.130/0.0.0".parse::<Ipv4Net>().is_err());
917        assert!("192.168.5.130/0.0.0.256".parse::<Ipv4Net>().is_err());
918    }
919
920    impl IpRange<Ipv4Net> {
921        fn get_network(&self, prefix_size: usize, prefix: &str) -> Option<Ipv4Net> {
922            self.trie
923                .search(format!("{}/{}", prefix, prefix_size).parse().unwrap())
924        }
925    }
926
927    #[test]
928    fn add_single_network() {
929        let mut ip_range = IpRange::new();
930        let network = "192.168.5.0/24".parse().unwrap();
931        ip_range.add(network);
932        assert_eq!(ip_range.into_iter().count(), 1);
933        assert_eq!(Some(network), ip_range.get_network(24, "192.168.5.0"));
934    }
935
936    #[test]
937    fn add_multiple_networks_disjoint() {
938        let mut ip_range = IpRange::new();
939        let network1 = "10.0.0.0/8".parse().unwrap();
940        let network2 = "172.16.0.0/16".parse().unwrap();
941        let network3 = "192.168.1.0/24".parse().unwrap();
942        let network4 = "254.254.254.254/32".parse().unwrap();
943        ip_range
944            .add(network1)
945            .add(network2)
946            .add(network3)
947            .add(network4)
948            .simplify();
949
950        assert_eq!(ip_range.into_iter().count(), 4);
951        assert_eq!(Some(network1), ip_range.get_network(8, "10.0.0.0"));
952        assert_eq!(Some(network2), ip_range.get_network(16, "172.16.0.0"));
953        assert_eq!(Some(network3), ip_range.get_network(24, "192.168.1.0"));
954        assert_eq!(Some(network4), ip_range.get_network(32, "254.254.254.254"));
955    }
956
957    #[test]
958    fn simplify() {
959        let mut ip_range = IpRange::new();
960        ip_range
961            .add("192.168.0.0/20".parse().unwrap())
962            .add("192.168.16.0/22".parse().unwrap())
963            .add("192.168.20.0/24".parse().unwrap())
964            .add("192.168.21.0/24".parse().unwrap())
965            .add("192.168.22.0/24".parse().unwrap())
966            .add("192.168.23.0/24".parse().unwrap())
967            .add("192.168.24.0/21".parse().unwrap())
968            .simplify();
969
970        assert_eq!(ip_range.into_iter().count(), 1);
971        assert_eq!(
972            "192.168.0.0/19".parse().ok(),
973            ip_range.get_network(19, "192.168.0.0")
974        );
975    }
976
977    #[test]
978    fn add_multiple_networks_joint1() {
979        let mut ip_range = IpRange::new();
980        let network1 = "172.16.4.0/24".parse().unwrap();
981        let network2 = "172.16.4.0/22".parse().unwrap();
982        ip_range.add(network1).add(network2).simplify();
983
984        assert_eq!(ip_range.into_iter().count(), 1);
985        assert_eq!(Some(network2), ip_range.get_network(22, "172.16.4.0"));
986    }
987
988    #[test]
989    fn add_multiple_networks_joint2() {
990        let mut ip_range = IpRange::new();
991        let network1 = "172.16.5.0/24".parse().unwrap();
992        let network2 = "172.16.4.0/22".parse().unwrap();
993        ip_range.add(network1).add(network2).simplify();
994
995        assert_eq!(ip_range.into_iter().count(), 1);
996        assert_eq!(Some(network2), ip_range.get_network(22, "172.16.4.0"));
997    }
998
999    #[test]
1000    fn add_multiple_networks_joint3() {
1001        let mut ip_range = IpRange::new();
1002        let network1 = "172.16.4.0/24".parse().unwrap();
1003        let network2 = "172.16.4.0/22".parse().unwrap();
1004        ip_range.add(network2).add(network1).simplify();
1005
1006        assert_eq!(ip_range.into_iter().count(), 1);
1007        assert_eq!(Some(network2), ip_range.get_network(22, "172.16.4.0"));
1008    }
1009
1010    #[test]
1011    fn add_multiple_networks_joint4() {
1012        let mut ip_range = IpRange::new();
1013        let network1 = "172.16.5.0/24".parse().unwrap();
1014        let network2 = "172.16.5.0/24".parse().unwrap();
1015        ip_range.add(network1).add(network2).simplify();
1016
1017        assert_eq!(ip_range.into_iter().count(), 1);
1018        assert_eq!(Some(network2), ip_range.get_network(24, "172.16.5.0"));
1019    }
1020
1021    #[test]
1022    fn add_multiple_networks_joint5() {
1023        let mut ip_range = IpRange::new();
1024        let network1 = "172.16.5.0/24".parse().unwrap();
1025        let network2 = "172.16.0.0/16".parse().unwrap();
1026        ip_range.add(network1).add(network2).simplify();
1027
1028        assert_eq!(ip_range.into_iter().count(), 1);
1029        assert_eq!(Some(network2), ip_range.get_network(16, "172.16.0.0"));
1030    }
1031
1032    #[test]
1033    fn add_multiple_networks_joint6() {
1034        let mut ip_range = IpRange::new();
1035        let network1 = "172.16.5.0/24".parse().unwrap();
1036        let network2 = "0.0.0.0/0".parse().unwrap();
1037        ip_range.add(network1).add(network2).simplify();
1038
1039        assert_eq!(ip_range.into_iter().count(), 1);
1040        assert_eq!(Some(network2), ip_range.get_network(0, "0.0.0.0"));
1041    }
1042
1043    #[test]
1044    fn remove_networks_no_split() {
1045        let mut ip_range = IpRange::new();
1046        let network1 = "192.168.0.0/24".parse().unwrap();
1047        let network2 = "172.16.0.0/16".parse().unwrap();
1048        ip_range.add(network1).add(network2).simplify();
1049
1050        ip_range.remove(network1);
1051        assert_eq!(ip_range.into_iter().count(), 1);
1052        assert_eq!(Some(network2), ip_range.get_network(16, "172.16.0.0"));
1053    }
1054
1055    #[test]
1056    fn remove_networks_split1() {
1057        let mut ip_range = IpRange::new();
1058        ip_range.add("192.168.0.0/22".parse().unwrap());
1059        ip_range
1060            .remove("192.168.2.0/23".parse().unwrap())
1061            .simplify();
1062
1063        assert_eq!(ip_range.into_iter().count(), 1);
1064        assert_eq!(
1065            Some("192.168.0.0/23".parse().unwrap()),
1066            ip_range.get_network(23, "192.168.0.0")
1067        );
1068    }
1069
1070    #[test]
1071    fn remove_networks_split2() {
1072        let mut ip_range = IpRange::new();
1073        ip_range.add("192.168.0.0/22".parse().unwrap());
1074        ip_range
1075            .remove("192.168.0.0/23".parse().unwrap())
1076            .simplify();
1077
1078        assert_eq!(ip_range.into_iter().count(), 1);
1079        assert_eq!(
1080            Some("192.168.2.0/23".parse().unwrap()),
1081            ip_range.get_network(23, "192.168.2.0")
1082        );
1083    }
1084
1085    #[test]
1086    fn remove_networks_split3() {
1087        let mut ip_range = IpRange::new();
1088        ip_range.add("192.168.0.0/22".parse().unwrap());
1089        ip_range
1090            .remove("192.168.2.0/25".parse().unwrap())
1091            .simplify();
1092
1093        assert_eq!(ip_range.into_iter().count(), 3);
1094        assert_eq!(
1095            Some("192.168.0.0/23".parse().unwrap()),
1096            ip_range.get_network(23, "192.168.0.0")
1097        );
1098        assert_eq!(
1099            Some("192.168.2.128/25".parse().unwrap()),
1100            ip_range.get_network(25, "192.168.2.128")
1101        );
1102        assert_eq!(
1103            Some("192.168.3.0/24".parse().unwrap()),
1104            ip_range.get_network(24, "192.168.3.0")
1105        );
1106    }
1107
1108    impl IpRange<Ipv4Net> {
1109        fn contains_ip(&self, ip: &str) -> bool {
1110            self.contains(&ip.parse::<Ipv4Addr>().unwrap())
1111        }
1112
1113        fn find_network_by_ip(&self, ip: &str) -> Option<Ipv4Net> {
1114            self.supernet(&ip.parse::<Ipv4Addr>().unwrap())
1115        }
1116
1117        fn contains_network(&self, network: &str) -> bool {
1118            self.contains(&network.parse::<Ipv4Net>().unwrap())
1119        }
1120
1121        fn super_network_by_network(&self, network: &str) -> Option<Ipv4Net> {
1122            self.supernet(&network.parse::<Ipv4Net>().unwrap())
1123        }
1124    }
1125
1126    #[test]
1127    fn contains_ip_with_one_network() {
1128        let mut ip_range = IpRange::new();
1129        ip_range.add("192.168.0.0/24".parse().unwrap());
1130
1131        assert!(ip_range.contains_ip("192.168.0.0"));
1132        assert!(ip_range.contains_ip("192.168.0.128"));
1133        assert!(ip_range.contains_ip("192.168.0.255"));
1134        assert!(!ip_range.contains_ip("192.167.255.255"));
1135        assert!(!ip_range.contains_ip("192.168.1.0"));
1136    }
1137
1138    #[test]
1139    fn contains_ip_with_many_networks() {
1140        let mut ip_range = IpRange::new();
1141        ip_range
1142            .add("192.168.0.0/24".parse().unwrap())
1143            .add("172.16.0.0/16".parse().unwrap())
1144            .add("10.0.0.0/8".parse().unwrap())
1145            .simplify();
1146
1147        assert!(ip_range.contains_ip("192.168.0.128"));
1148        assert!(ip_range.contains_ip("172.16.32.1"));
1149        assert!(ip_range.contains_ip("10.10.10.10"));
1150        assert!(!ip_range.contains_ip("0.0.0.0"));
1151        assert!(!ip_range.contains_ip("8.8.8.8"));
1152        assert!(!ip_range.contains_ip("11.0.0.0"));
1153        assert!(!ip_range.contains_ip("192.167.255.255"));
1154        assert!(!ip_range.contains_ip("255.255.255.255"));
1155    }
1156
1157    #[test]
1158    fn contains_ip_boundary1() {
1159        let mut ip_range = IpRange::new();
1160        ip_range.add("0.0.0.0/0".parse().unwrap());
1161
1162        assert!(ip_range.contains_ip("0.0.0.0"));
1163        assert!(ip_range.contains_ip("8.8.8.8"));
1164        assert!(ip_range.contains_ip("192.168.0.0"));
1165        assert!(ip_range.contains_ip("192.168.1.1"));
1166    }
1167
1168    #[test]
1169    fn contains_ip_boundary2() {
1170        let mut ip_range = IpRange::new();
1171        ip_range.add("254.254.254.254/32".parse().unwrap());
1172
1173        assert!(!ip_range.contains_ip("0.0.0.0"));
1174        assert!(!ip_range.contains_ip("8.8.8.8"));
1175        assert!(!ip_range.contains_ip("192.168.0.0"));
1176        assert!(ip_range.contains_ip("254.254.254.254"));
1177    }
1178
1179    #[test]
1180    fn find_network_with_one_network() {
1181        let mut ip_range = IpRange::new();
1182        let network = "192.168.0.0/24".parse().unwrap();
1183        ip_range.add(network);
1184
1185        assert_eq!(Some(network), ip_range.find_network_by_ip("192.168.0.0"));
1186        assert_eq!(Some(network), ip_range.find_network_by_ip("192.168.0.128"));
1187        assert_eq!(Some(network), ip_range.find_network_by_ip("192.168.0.255"));
1188        assert_eq!(None, ip_range.find_network_by_ip("192.167.255.255"));
1189        assert_eq!(None, ip_range.find_network_by_ip("192.168.1.0"));
1190    }
1191
1192    #[test]
1193    fn find_network_with_many_networks() {
1194        let mut ip_range = IpRange::new();
1195        let network1 = "192.168.0.0/24".parse().unwrap();
1196        let network2 = "172.16.0.0/16".parse().unwrap();
1197        let network3 = "10.0.0.0/8".parse().unwrap();
1198        ip_range
1199            .add(network1)
1200            .add(network2)
1201            .add(network3)
1202            .simplify();
1203
1204        assert_eq!(Some(network1), ip_range.find_network_by_ip("192.168.0.128"));
1205        assert_eq!(Some(network2), ip_range.find_network_by_ip("172.16.32.1"));
1206        assert_eq!(Some(network3), ip_range.find_network_by_ip("10.10.10.10"));
1207        assert_eq!(None, ip_range.find_network_by_ip("0.0.0.0"));
1208        assert_eq!(None, ip_range.find_network_by_ip("8.8.8.8"));
1209        assert_eq!(None, ip_range.find_network_by_ip("11.0.0.0"));
1210        assert_eq!(None, ip_range.find_network_by_ip("192.167.255.255"));
1211        assert_eq!(None, ip_range.find_network_by_ip("255.255.255.255"));
1212    }
1213
1214    #[test]
1215    fn find_network_boundary1() {
1216        let mut ip_range = IpRange::new();
1217        let network = "0.0.0.0/0".parse().unwrap();
1218        ip_range.add(network);
1219
1220        assert_eq!(Some(network), ip_range.find_network_by_ip("0.0.0.0"));
1221        assert_eq!(Some(network), ip_range.find_network_by_ip("8.8.8.8"));
1222        assert_eq!(Some(network), ip_range.find_network_by_ip("192.168.0.0"));
1223        assert_eq!(Some(network), ip_range.find_network_by_ip("192.168.1.1"));
1224    }
1225
1226    #[test]
1227    fn find_network_boundary2() {
1228        let mut ip_range = IpRange::new();
1229        let network = "254.254.254.254/32".parse().unwrap();
1230        ip_range.add(network);
1231
1232        assert_eq!(None, ip_range.find_network_by_ip("0.0.0.0"));
1233        assert_eq!(None, ip_range.find_network_by_ip("8.8.8.8"));
1234        assert_eq!(None, ip_range.find_network_by_ip("192.168.0.0"));
1235        assert_eq!(
1236            Some(network),
1237            ip_range.find_network_by_ip("254.254.254.254")
1238        );
1239    }
1240
1241    #[test]
1242    fn contains_network_with_one_network() {
1243        let mut ip_range = IpRange::new();
1244        ip_range.add("192.168.0.0/24".parse().unwrap());
1245
1246        assert!(ip_range.contains_network("192.168.0.0/24"));
1247        assert!(ip_range.contains_network("192.168.0.128/25"));
1248        assert!(!ip_range.contains_network("192.168.0.0/23"));
1249        assert!(!ip_range.contains_network("192.168.1.0/24"));
1250        assert!(!ip_range.contains_network("192.167.0.0/24"));
1251    }
1252
1253    #[test]
1254    fn contains_network_with_many_networks() {
1255        let mut ip_range = IpRange::new();
1256        ip_range
1257            .add("192.168.0.0/24".parse().unwrap())
1258            .add("172.16.0.0/16".parse().unwrap())
1259            .add("10.0.0.0/8".parse().unwrap())
1260            .simplify();
1261
1262        assert!(ip_range.contains_network("192.168.0.128/25"));
1263        assert!(ip_range.contains_network("172.16.32.0/20"));
1264        assert!(ip_range.contains_network("10.10.0.0/16"));
1265        assert!(!ip_range.contains_network("0.0.0.0/0"));
1266        assert!(!ip_range.contains_network("8.0.0.0/6"));
1267        assert!(!ip_range.contains_network("8.0.0.0/7"));
1268        assert!(!ip_range.contains_network("11.0.0.0/9"));
1269        assert!(!ip_range.contains_network("192.167.255.255/32"));
1270        assert!(!ip_range.contains_network("255.0.0.0/8"));
1271    }
1272
1273    #[test]
1274    fn contains_network_boundary1() {
1275        let mut ip_range = IpRange::new();
1276        ip_range.add("0.0.0.0/0".parse().unwrap());
1277
1278        assert!(ip_range.contains_network("0.0.0.0/0"));
1279        assert!(ip_range.contains_network("8.0.0.0/6"));
1280        assert!(ip_range.contains_network("11.0.0.0/9"));
1281        assert!(ip_range.contains_network("192.168.0.128/25"));
1282        assert!(ip_range.contains_network("255.255.255.255/32"));
1283    }
1284
1285    #[test]
1286    fn contains_network_boundary2() {
1287        let mut ip_range = IpRange::new();
1288        ip_range.add("254.254.254.254/32".parse().unwrap());
1289
1290        assert!(!ip_range.contains_network("0.0.0.0/0"));
1291        assert!(!ip_range.contains_network("8.0.0.0/6"));
1292        assert!(!ip_range.contains_network("254.254.0.0/16"));
1293        assert!(ip_range.contains_network("254.254.254.254/32"));
1294        assert!(!ip_range.contains_network("255.255.255.255/32"));
1295    }
1296
1297    #[test]
1298    fn super_network_with_one_network() {
1299        let mut ip_range = IpRange::new();
1300        let network = "192.168.0.0/24".parse().unwrap();
1301        ip_range.add(network);
1302
1303        assert_eq!(
1304            Some(network),
1305            ip_range.super_network_by_network("192.168.0.0/24")
1306        );
1307        assert_eq!(
1308            Some(network),
1309            ip_range.super_network_by_network("192.168.0.128/25")
1310        );
1311        assert_eq!(None, ip_range.super_network_by_network("192.168.0.0/23"));
1312        assert_eq!(None, ip_range.super_network_by_network("192.168.1.0/24"));
1313        assert_eq!(None, ip_range.super_network_by_network("192.167.0.0/24"));
1314    }
1315
1316    #[test]
1317    fn super_network_with_many_networks() {
1318        let mut ip_range = IpRange::new();
1319        let network1 = "192.168.0.0/24".parse().unwrap();
1320        let network2 = "172.16.0.0/16".parse().unwrap();
1321        let network3 = "10.0.0.0/8".parse().unwrap();
1322        ip_range
1323            .add(network1)
1324            .add(network2)
1325            .add(network3)
1326            .simplify();
1327
1328        assert_eq!(
1329            Some(network1),
1330            ip_range.super_network_by_network("192.168.0.128/25")
1331        );
1332        assert_eq!(
1333            Some(network2),
1334            ip_range.super_network_by_network("172.16.32.0/20")
1335        );
1336        assert_eq!(
1337            Some(network3),
1338            ip_range.super_network_by_network("10.10.0.0/16")
1339        );
1340        assert_eq!(None, ip_range.super_network_by_network("0.0.0.0/0"));
1341        assert_eq!(None, ip_range.super_network_by_network("8.0.0.0/6"));
1342        assert_eq!(None, ip_range.super_network_by_network("8.0.0.0/7"));
1343        assert_eq!(None, ip_range.super_network_by_network("11.0.0.0/9"));
1344        assert_eq!(
1345            None,
1346            ip_range.super_network_by_network("192.167.255.255/32")
1347        );
1348        assert_eq!(None, ip_range.super_network_by_network("255.0.0.0/8"));
1349    }
1350
1351    #[test]
1352    fn super_network_boundary1() {
1353        let mut ip_range = IpRange::new();
1354        let network = "0.0.0.0/0".parse().unwrap();
1355        ip_range.add(network);
1356
1357        assert_eq!(
1358            Some(network),
1359            ip_range.super_network_by_network("0.0.0.0/0")
1360        );
1361        assert_eq!(
1362            Some(network),
1363            ip_range.super_network_by_network("8.0.0.0/6")
1364        );
1365        assert_eq!(
1366            Some(network),
1367            ip_range.super_network_by_network("11.0.0.0/9")
1368        );
1369        assert_eq!(
1370            Some(network),
1371            ip_range.super_network_by_network("192.168.0.128/25")
1372        );
1373        assert_eq!(
1374            Some(network),
1375            ip_range.super_network_by_network("255.255.255.255/32")
1376        );
1377    }
1378
1379    #[test]
1380    fn super_network_boundary2() {
1381        let mut ip_range = IpRange::new();
1382        let network = "254.254.254.254/32".parse().unwrap();
1383        ip_range.add(network);
1384
1385        assert_eq!(None, ip_range.super_network_by_network("0.0.0.0/0"));
1386        assert_eq!(None, ip_range.super_network_by_network("8.0.0.0/6"));
1387        assert_eq!(None, ip_range.super_network_by_network("254.254.0.0/16"));
1388        assert_eq!(
1389            Some(network),
1390            ip_range.super_network_by_network("254.254.254.254/32")
1391        );
1392        assert_eq!(
1393            None,
1394            ip_range.super_network_by_network("255.255.255.255/32")
1395        );
1396    }
1397
1398    #[test]
1399    fn merge_empty1() {
1400        let ip_range1 = IpRange::new();
1401        let mut ip_range2 = IpRange::new();
1402        let network1 = "10.0.0.0/8".parse().unwrap();
1403        let network2 = "172.16.0.0/16".parse().unwrap();
1404        let network3 = "192.168.1.0/24".parse().unwrap();
1405        let network4 = "254.254.254.254/32".parse().unwrap();
1406        ip_range2
1407            .add(network1)
1408            .add(network2)
1409            .add(network3)
1410            .add(network4)
1411            .simplify();
1412
1413        let ip_range = ip_range1.merge(&ip_range2);
1414        assert_eq!(ip_range.into_iter().count(), 4);
1415        assert_eq!(Some(network1), ip_range.get_network(8, "10.0.0.0"));
1416        assert_eq!(Some(network2), ip_range.get_network(16, "172.16.0.0"));
1417        assert_eq!(Some(network3), ip_range.get_network(24, "192.168.1.0"));
1418        assert_eq!(Some(network4), ip_range.get_network(32, "254.254.254.254"));
1419    }
1420
1421    #[test]
1422    fn merge_empty2() {
1423        let mut ip_range1 = IpRange::new();
1424        let ip_range2 = IpRange::new();
1425        let network1 = "10.0.0.0/8".parse().unwrap();
1426        let network2 = "172.16.0.0/16".parse().unwrap();
1427        let network3 = "192.168.1.0/24".parse().unwrap();
1428        let network4 = "254.254.254.254/32".parse().unwrap();
1429        ip_range1
1430            .add(network1)
1431            .add(network2)
1432            .add(network3)
1433            .add(network4)
1434            .simplify();
1435
1436        let ip_range = ip_range1.merge(&ip_range2);
1437        assert_eq!(ip_range.into_iter().count(), 4);
1438        assert_eq!(Some(network1), ip_range.get_network(8, "10.0.0.0"));
1439        assert_eq!(Some(network2), ip_range.get_network(16, "172.16.0.0"));
1440        assert_eq!(Some(network3), ip_range.get_network(24, "192.168.1.0"));
1441        assert_eq!(Some(network4), ip_range.get_network(32, "254.254.254.254"));
1442    }
1443
1444    #[test]
1445    fn merge_disjoint() {
1446        let mut ip_range1 = IpRange::new();
1447        let mut ip_range2 = IpRange::new();
1448        let network1 = "10.0.0.0/8".parse().unwrap();
1449        let network2 = "172.16.0.0/16".parse().unwrap();
1450        let network3 = "192.168.1.0/24".parse().unwrap();
1451        let network4 = "254.254.254.254/32".parse().unwrap();
1452        ip_range1.add(network1).add(network2);
1453        ip_range2.add(network3).add(network4);
1454
1455        let ip_range = ip_range1.merge(&ip_range2);
1456        assert_eq!(ip_range.into_iter().count(), 4);
1457        assert_eq!(Some(network1), ip_range.get_network(8, "10.0.0.0"));
1458        assert_eq!(Some(network2), ip_range.get_network(16, "172.16.0.0"));
1459        assert_eq!(Some(network3), ip_range.get_network(24, "192.168.1.0"));
1460        assert_eq!(Some(network4), ip_range.get_network(32, "254.254.254.254"));
1461    }
1462
1463    #[test]
1464    fn merge_joint1() {
1465        let mut ip_range1 = IpRange::new();
1466        let mut ip_range2 = IpRange::new();
1467        let network1 = "172.16.4.0/24".parse().unwrap();
1468        let network2 = "172.16.4.0/22".parse().unwrap();
1469        ip_range1.add(network1);
1470        ip_range2.add(network2);
1471
1472        let ip_range = ip_range1.merge(&ip_range2);
1473        assert_eq!(ip_range.into_iter().count(), 1);
1474        assert_eq!(Some(network2), ip_range.get_network(22, "172.16.4.0"));
1475    }
1476
1477    #[test]
1478    fn merge_joint2() {
1479        let mut ip_range1 = IpRange::new();
1480        let mut ip_range2 = IpRange::new();
1481        let network1 = "172.16.5.0/24".parse().unwrap();
1482        let network2 = "172.16.4.0/22".parse().unwrap();
1483        ip_range1.add(network1);
1484        ip_range2.add(network2);
1485
1486        let ip_range = ip_range1.merge(&ip_range2);
1487        assert_eq!(ip_range.into_iter().count(), 1);
1488        assert_eq!(Some(network2), ip_range.get_network(22, "172.16.4.0"));
1489    }
1490
1491    #[test]
1492    fn merge_sequent1() {
1493        let mut ip_range1 = IpRange::new();
1494        let mut ip_range2 = IpRange::new();
1495        let network1 = "172.16.4.0/24".parse().unwrap();
1496        let network2 = "172.16.5.0/24".parse().unwrap();
1497        let network3 = "172.16.6.0/24".parse().unwrap();
1498        ip_range1.add(network1);
1499        ip_range2.add(network2);
1500        ip_range2.add(network3);
1501
1502        let ip_range = ip_range1.merge(&ip_range2);
1503        assert_eq!(ip_range.into_iter().count(), 2);
1504        assert_eq!(
1505            "172.16.4.0/23".parse().ok(),
1506            ip_range.get_network(23, "172.16.4.0")
1507        );
1508        assert_eq!(
1509            "172.16.6.0/24".parse().ok(),
1510            ip_range.get_network(24, "172.16.6.0")
1511        );
1512    }
1513
1514    #[test]
1515    fn merge_sequent2() {
1516        let mut ip_range1 = IpRange::new();
1517        let mut ip_range2 = IpRange::new();
1518        let mut ip_range3 = IpRange::new();
1519        ip_range1
1520            .add("192.168.0.0/20".parse().unwrap())
1521            .add("192.168.24.0/21".parse().unwrap());
1522        ip_range2
1523            .add("192.168.16.0/22".parse().unwrap())
1524            .add("192.168.23.0/24".parse().unwrap());
1525        ip_range3
1526            .add("192.168.20.0/24".parse().unwrap())
1527            .add("192.168.21.0/24".parse().unwrap())
1528            .add("192.168.22.0/24".parse().unwrap());
1529
1530        let ip_range = ip_range1.merge(&ip_range2);
1531        let ip_range = ip_range.merge(&ip_range3);
1532        assert_eq!(ip_range.into_iter().count(), 1);
1533        assert_eq!(
1534            "192.168.0.0/19".parse().ok(),
1535            ip_range.get_network(19, "192.168.0.0")
1536        );
1537    }
1538
1539    #[test]
1540    fn intersect_disjoint() {
1541        let mut ip_range1 = IpRange::new();
1542        let mut ip_range2 = IpRange::new();
1543        let network1: Ipv4Net = "10.0.0.0/8".parse().unwrap();
1544        let network2 = "172.16.0.0/16".parse().unwrap();
1545        let network3 = "192.168.1.0/24".parse().unwrap();
1546        let network4 = "254.254.254.254/32".parse().unwrap();
1547        ip_range1.add(network1).add(network2);
1548        ip_range2.add(network3).add(network4);
1549
1550        let ip_range = ip_range1.intersect(&ip_range2);
1551        assert_eq!(ip_range.into_iter().count(), 0);
1552    }
1553
1554    #[test]
1555    fn intersect_joint1() {
1556        let mut ip_range1 = IpRange::new();
1557        let mut ip_range2 = IpRange::new();
1558        let network1 = "172.16.4.0/24".parse().unwrap();
1559        let network2 = "172.16.4.0/22".parse().unwrap();
1560        ip_range1.add(network1);
1561        ip_range2.add(network2);
1562
1563        let ip_range = ip_range1.intersect(&ip_range2);
1564        assert_eq!(ip_range.into_iter().count(), 1);
1565        assert_eq!(Some(network1), ip_range.get_network(24, "172.16.4.0"));
1566    }
1567
1568    #[test]
1569    fn intersect_joint2() {
1570        let mut ip_range1 = IpRange::new();
1571        let mut ip_range2 = IpRange::new();
1572        let network1 = "172.16.5.0/24".parse().unwrap();
1573        let network2 = "172.16.4.0/22".parse().unwrap();
1574        ip_range1.add(network1);
1575        ip_range2.add(network2);
1576
1577        let ip_range = ip_range1.intersect(&ip_range2);
1578        assert_eq!(ip_range.into_iter().count(), 1);
1579        assert_eq!(Some(network1), ip_range.get_network(24, "172.16.5.0"));
1580    }
1581
1582    #[test]
1583    fn intersect_joint3() {
1584        let mut ip_range1 = IpRange::new();
1585        let mut ip_range2 = IpRange::new();
1586        let network1 = "172.16.5.0/24".parse().unwrap();
1587        let network2 = "172.16.5.0/24".parse().unwrap();
1588        ip_range1.add(network1);
1589        ip_range2.add(network2);
1590
1591        let ip_range = ip_range1.intersect(&ip_range2);
1592        assert_eq!(ip_range.into_iter().count(), 1);
1593        assert_eq!(Some(network1), ip_range.get_network(24, "172.16.5.0"));
1594    }
1595
1596    #[test]
1597    fn intersect_joint4() {
1598        let mut ip_range1 = IpRange::new();
1599        let mut ip_range2 = IpRange::new();
1600        let network1 = "10.0.0.0/8".parse().unwrap();
1601        let network2 = "192.168.0.0/24".parse().unwrap();
1602        let network3 = "10.10.0.0/16".parse().unwrap();
1603        let network4 = "10.254.0.0/17".parse().unwrap();
1604        let network5 = "192.168.0.0/16".parse().unwrap();
1605        ip_range1.add(network1).add(network2);
1606        ip_range2.add(network3).add(network4).add(network5);
1607
1608        let ip_range = ip_range1.intersect(&ip_range2);
1609        assert_eq!(ip_range.into_iter().count(), 3);
1610        assert_eq!(Some(network3), ip_range.get_network(16, "10.10.0.0"));
1611        assert_eq!(Some(network4), ip_range.get_network(17, "10.254.0.0"));
1612        assert_eq!(Some(network2), ip_range.get_network(24, "192.168.0.0"));
1613    }
1614
1615    #[test]
1616    fn exclude_disjoint() {
1617        let mut ip_range1 = IpRange::new();
1618        let mut ip_range2 = IpRange::new();
1619        let network1: Ipv4Net = "10.0.0.0/8".parse().unwrap();
1620        let network2 = "172.16.0.0/16".parse().unwrap();
1621        let network3 = "192.168.1.0/24".parse().unwrap();
1622        let network4 = "254.254.254.254/32".parse().unwrap();
1623        ip_range1.add(network1).add(network2);
1624        ip_range2.add(network3).add(network4);
1625
1626        let ip_range = ip_range1.exclude(&ip_range2);
1627        assert_eq!(ip_range1, ip_range);
1628    }
1629
1630    #[test]
1631    fn exclude_larger() {
1632        let mut ip_range1 = IpRange::new();
1633        let mut ip_range2 = IpRange::new();
1634        let network1: Ipv4Net = "172.16.4.0/24".parse().unwrap();
1635        let network2 = "192.168.1.0/24".parse().unwrap();
1636        let network3 = "172.16.4.0/22".parse().unwrap();
1637        ip_range1.add(network1).add(network2);
1638        ip_range2.add(network3);
1639
1640        let ip_range = ip_range1.exclude(&ip_range2);
1641        assert_eq!(ip_range.into_iter().count(), 1);
1642        assert_eq!(Some(network2), ip_range.get_network(24, "192.168.1.0"));
1643    }
1644
1645    #[test]
1646    fn exclude_identical() {
1647        let mut ip_range1 = IpRange::new();
1648        let mut ip_range2 = IpRange::new();
1649        let network1: Ipv4Net = "172.16.5.0/24".parse().unwrap();
1650        let network2 = "192.168.1.0/24".parse().unwrap();
1651        let network3 = "172.16.4.0/22".parse().unwrap();
1652        let network4 = "10.0.0.0/8".parse().unwrap();
1653
1654        ip_range1.add(network1).add(network2);
1655        ip_range2.add(network3).add(network4);
1656
1657        let ip_range = ip_range1.exclude(&ip_range2);
1658        assert_eq!(ip_range.into_iter().count(), 1);
1659        assert_eq!(Some(network2), ip_range.get_network(24, "192.168.1.0"));
1660    }
1661
1662    #[test]
1663    fn exclude_split1() {
1664        let mut ip_range1 = IpRange::new();
1665        let mut ip_range2 = IpRange::new();
1666        let network1: Ipv4Net = "172.16.4.0/22".parse().unwrap();
1667        let network2 = "192.168.1.0/24".parse().unwrap();
1668        let network3 = "172.16.5.0/24".parse().unwrap();
1669        let network4 = "10.0.0.0/8".parse().unwrap();
1670
1671        ip_range1.add(network1).add(network2);
1672        ip_range2.add(network3).add(network4);
1673
1674        let ip_range = ip_range1.exclude(&ip_range2);
1675        assert_eq!(ip_range.into_iter().count(), 3);
1676        assert_eq!(Some(network2), ip_range.get_network(24, "192.168.1.0"));
1677        assert_eq!(
1678            "172.16.4.0/24".parse().ok(),
1679            ip_range.get_network(24, "172.16.4.0")
1680        );
1681        assert_eq!(
1682            "172.16.6.0/23".parse().ok(),
1683            ip_range.get_network(23, "172.16.6.0")
1684        );
1685    }
1686
1687    #[test]
1688    fn exclude_split2() {
1689        let mut ip_range1 = IpRange::new();
1690        let mut ip_range2 = IpRange::new();
1691        let network1: Ipv4Net = "172.16.4.0/22".parse().unwrap();
1692        let network2 = "192.168.1.0/24".parse().unwrap();
1693        let network3 = "172.16.4.0/24".parse().unwrap();
1694        let network4 = "10.0.0.0/8".parse().unwrap();
1695
1696        ip_range1.add(network1).add(network2);
1697        ip_range2.add(network3).add(network4);
1698
1699        let ip_range = ip_range1.exclude(&ip_range2);
1700        assert_eq!(ip_range.into_iter().count(), 3);
1701        assert_eq!(Some(network2), ip_range.get_network(24, "192.168.1.0"));
1702        assert_eq!(
1703            "172.16.5.0/24".parse().ok(),
1704            ip_range.get_network(24, "172.16.5.0")
1705        );
1706        assert_eq!(
1707            "172.16.6.0/23".parse().ok(),
1708            ip_range.get_network(23, "172.16.6.0")
1709        );
1710    }
1711
1712    #[test]
1713    fn iter_ipv4() {
1714        let mut data = vec!["1.0.1.0/24", "1.0.2.0/23", "1.0.8.0/21"];
1715        let ip_range: IpRange<Ipv4Net> = data.iter().map(|net| net.parse().unwrap()).collect();
1716        let mut nets: Vec<String> = ip_range.iter().map(|net| format!("{}", net)).collect();
1717        data.sort_unstable();
1718        nets.sort_unstable();
1719        assert_eq!(nets, data);
1720    }
1721
1722    #[test]
1723    fn iter_ipv6() {
1724        let mut data = vec![
1725            "2400:9a40::/32",
1726            "2400:9dc0::/32",
1727            "2400:9e00::/32",
1728            "2400:a040::/32",
1729        ];
1730        let ip_range: IpRange<Ipv6Net> = data.iter().map(|net| net.parse().unwrap()).collect();
1731        let mut nets: Vec<String> = ip_range.iter().map(|net| format!("{}", net)).collect();
1732        data.sort_unstable();
1733        nets.sort_unstable();
1734        assert_eq!(nets, data);
1735    }
1736
1737    #[test]
1738    fn debug_fmt() {
1739        let ip_range: IpRange<Ipv4Net> = IpRange::default();
1740        assert_eq!(format!("{:?}", ip_range), "IpRange []");
1741
1742        let ip_range: IpRange<Ipv4Net> = ["1.0.1.0/24", "1.0.2.0/23", "1.0.8.0/21"]
1743            .iter()
1744            .map(|net| net.parse().unwrap())
1745            .collect();
1746        assert_eq!(
1747            format!("{:?}", ip_range),
1748            "IpRange [1.0.8.0/21, 1.0.2.0/23, 1.0.1.0/24]"
1749        );
1750
1751        let ip_range: IpRange<Ipv4Net> = [
1752            "192.168.0.0/16",
1753            "1.0.2.0/23",
1754            "1.0.8.0/21",
1755            "127.0.0.0/8",
1756            "172.16.0.0/12",
1757        ]
1758        .iter()
1759        .map(|net| net.parse().unwrap())
1760        .collect();
1761        assert_eq!(
1762            format!("{:?}", ip_range),
1763            "IpRange [127.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, ...]"
1764        );
1765
1766        let ip_range: IpRange<Ipv6Net> = [
1767            "2001:4438::/32",
1768            "2001:4510::/29",
1769            "2400:1040::/32",
1770            "2400:12c0::/32",
1771            "2400:1340::/32",
1772            "2400:1380::/32",
1773            "2400:15c0::/32",
1774        ]
1775        .iter()
1776        .map(|net| net.parse().unwrap())
1777        .collect();
1778        assert_eq!(
1779            format!("{:?}", ip_range),
1780            "IpRange [2001:4510::/29, 2001:4438::/32, 2400:1040::/32, ...]"
1781        );
1782    }
1783
1784    #[test]
1785    fn remove_all() {
1786        let mut ip_range = IpRange::new();
1787        let network: Ipv4Net = "1.0.1.0/24".parse().unwrap();
1788        ip_range.add(network);
1789        ip_range.remove(network);
1790        assert!(ip_range.iter().next().is_none());
1791    }
1792
1793    #[test]
1794    fn add_to_all_zeros() {
1795        let mut ip_range: IpRange<Ipv4Net> = IpRange::new();
1796        ip_range.add("0.0.0.0/0".parse().unwrap());
1797        ip_range.add("127.0.0.1/32".parse().unwrap());
1798        assert!(ip_range.contains_network("0.0.0.0/0"));
1799    }
1800
1801    #[test]
1802    #[cfg(feature = "serde")]
1803    fn serialize_ipv4_as_binary() {
1804        let mut ip_range: IpRange<Ipv4Net> = IpRange::new();
1805        ip_range.add("0.0.0.0/0".parse().unwrap());
1806        ip_range.add("127.0.0.1/32".parse().unwrap());
1807        ip_range.add("254.254.254.254/32".parse().unwrap());
1808        let encoded: Vec<u8> = bincode::serialize(&ip_range).unwrap();
1809        let decoded_ip_range: IpRange<Ipv4Net> = bincode::deserialize(&encoded[..]).unwrap();
1810        assert_eq!(ip_range, decoded_ip_range);
1811    }
1812
1813    #[test]
1814    #[cfg(feature = "serde")]
1815    fn serialize_ipv6_as_binary() {
1816        let mut ip_range: IpRange<Ipv6Net> = IpRange::new();
1817        ip_range.add("2001:4438::/32".parse().unwrap());
1818        ip_range.add("2400:1040::/32".parse().unwrap());
1819        ip_range.add("2400:1340::/32".parse().unwrap());
1820        let encoded: Vec<u8> = bincode::serialize(&ip_range).unwrap();
1821        let decoded_ip_range: IpRange<Ipv6Net> = bincode::deserialize(&encoded[..]).unwrap();
1822        assert_eq!(ip_range, decoded_ip_range);
1823    }
1824}