1use std::cmp::{min, max};
2use std::cmp::Ordering::{Less, Equal};
3use std::convert::From;
4use std::error::Error;
5use std::fmt;
6use std::iter::FusedIterator;
7use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
8use std::option::Option::{Some, None};
9
10use crate::ipext::{IpAdd, IpSub, IpStep, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
11use crate::mask::{ip_mask_to_prefix, ipv4_mask_to_prefix, ipv6_mask_to_prefix};
12
13/// An IP network address, either IPv4 or IPv6.
14///
15/// This enum can contain either an [`Ipv4Net`] or an [`Ipv6Net`]. A
16/// [`From`] implementation is provided to convert these into an
17/// `IpNet`.
18///
19/// # Textual representation
20///
21/// `IpNet` provides a [`FromStr`] implementation for parsing network
22/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
23/// CIDR notation.
24///
25/// [`Ipv4Net`]: struct.Ipv4Net.html
26/// [`Ipv6Net`]: struct.Ipv6Net.html
27/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
28/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
29/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
30///
31/// # Examples
32///
33/// ```
34/// use std::net::IpAddr;
35/// use ipnet::IpNet;
36///
37/// let net: IpNet = "10.1.1.0/24".parse().unwrap();
38/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
39///
40/// let net: IpNet = "fd00::/32".parse().unwrap();
41/// assert_eq!(Ok(net.network()), "fd00::".parse());
42/// ```
43#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
44pub enum IpNet {
45 V4(Ipv4Net),
46 V6(Ipv6Net),
47}
48
49/// An IPv4 network address.
50///
51/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
52/// addresses.
53///
54/// # Textual representation
55///
56/// `Ipv4Net` provides a [`FromStr`] implementation for parsing network
57/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
58/// CIDR notation.
59///
60/// [`IpNet`]: enum.IpNet.html
61/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
62/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
63///
64/// # Examples
65///
66/// ```
67/// use std::net::Ipv4Addr;
68/// use ipnet::Ipv4Net;
69///
70/// let net: Ipv4Net = "10.1.1.0/24".parse().unwrap();
71/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
72/// ```
73#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
74pub struct Ipv4Net {
75 addr: Ipv4Addr,
76 prefix_len: u8,
77}
78
79/// An IPv6 network address.
80///
81/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
82/// addresses.
83///
84/// # Textual representation
85///
86/// `Ipv6Net` provides a [`FromStr`] implementation for parsing network
87/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
88/// CIDR notation.
89///
90/// [`IpNet`]: enum.IpNet.html
91/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
92/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
93///
94/// # Examples
95///
96/// ```
97/// use std::net::Ipv6Addr;
98/// use ipnet::Ipv6Net;
99///
100/// let net: Ipv6Net = "fd00::/32".parse().unwrap();
101/// assert_eq!(Ok(net.network()), "fd00::".parse());
102/// ```
103#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
104pub struct Ipv6Net {
105 addr: Ipv6Addr,
106 prefix_len: u8,
107}
108
109/// An error which can be returned when the prefix length is invalid.
110///
111/// Valid prefix lengths are 0 to 32 for IPv4 and 0 to 128 for IPv6.
112#[derive(Debug, Clone, PartialEq, Eq)]
113pub struct PrefixLenError;
114
115impl fmt::Display for PrefixLenError {
116 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
117 fmt.write_str(data:"invalid IP prefix length")
118 }
119}
120
121impl Error for PrefixLenError {}
122
123impl IpNet {
124 /// Creates a new IP network address from an `IpAddr` and prefix
125 /// length.
126 ///
127 /// # Examples
128 ///
129 /// ```
130 /// use std::net::Ipv6Addr;
131 /// use ipnet::{IpNet, PrefixLenError};
132 ///
133 /// let net = IpNet::new(Ipv6Addr::LOCALHOST.into(), 48);
134 /// assert!(net.is_ok());
135 ///
136 /// let bad_prefix_len = IpNet::new(Ipv6Addr::LOCALHOST.into(), 129);
137 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
138 /// ```
139 pub fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError> {
140 Ok(match ip {
141 IpAddr::V4(a) => Ipv4Net::new(a, prefix_len)?.into(),
142 IpAddr::V6(a) => Ipv6Net::new(a, prefix_len)?.into(),
143 })
144 }
145
146 /// Creates a new IP network address from an `IpAddr` and netmask.
147 ///
148 /// # Examples
149 ///
150 /// ```
151 /// use std::net::Ipv6Addr;
152 /// use ipnet::{IpNet, PrefixLenError};
153 ///
154 /// let net = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0000_0000_0000_0000).into());
155 /// assert!(net.is_ok());
156 ///
157 /// let bad_prefix_len = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0001_0000_0000_0000).into());
158 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
159 /// ```
160 pub fn with_netmask(ip: IpAddr, netmask: IpAddr) -> Result<IpNet, PrefixLenError> {
161 let prefix = ip_mask_to_prefix(netmask)?;
162 Self::new(ip, prefix)
163 }
164
165 /// Returns a copy of the network with the address truncated to the
166 /// prefix length.
167 ///
168 /// # Examples
169 ///
170 /// ```
171 /// # use ipnet::IpNet;
172 /// #
173 /// assert_eq!(
174 /// "192.168.12.34/16".parse::<IpNet>().unwrap().trunc(),
175 /// "192.168.0.0/16".parse().unwrap()
176 /// );
177 ///
178 /// assert_eq!(
179 /// "fd00::1:2:3:4/16".parse::<IpNet>().unwrap().trunc(),
180 /// "fd00::/16".parse().unwrap()
181 /// );
182 /// ```
183 pub fn trunc(&self) -> IpNet {
184 match *self {
185 IpNet::V4(ref a) => IpNet::V4(a.trunc()),
186 IpNet::V6(ref a) => IpNet::V6(a.trunc()),
187 }
188 }
189
190 /// Returns the address.
191 pub fn addr(&self) -> IpAddr {
192 match *self {
193 IpNet::V4(ref a) => IpAddr::V4(a.addr),
194 IpNet::V6(ref a) => IpAddr::V6(a.addr),
195 }
196 }
197
198 /// Returns the prefix length.
199 pub fn prefix_len(&self) -> u8 {
200 match *self {
201 IpNet::V4(ref a) => a.prefix_len(),
202 IpNet::V6(ref a) => a.prefix_len(),
203 }
204 }
205
206 /// Returns the maximum valid prefix length.
207 pub fn max_prefix_len(&self) -> u8 {
208 match *self {
209 IpNet::V4(ref a) => a.max_prefix_len(),
210 IpNet::V6(ref a) => a.max_prefix_len(),
211 }
212 }
213
214 /// Returns the network mask.
215 ///
216 /// # Examples
217 ///
218 /// ```
219 /// # use std::net::IpAddr;
220 /// # use ipnet::IpNet;
221 /// #
222 /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
223 /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
224 ///
225 /// let net: IpNet = "fd00::/24".parse().unwrap();
226 /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
227 /// ```
228 pub fn netmask(&self) -> IpAddr {
229 match *self {
230 IpNet::V4(ref a) => IpAddr::V4(a.netmask()),
231 IpNet::V6(ref a) => IpAddr::V6(a.netmask()),
232 }
233 }
234
235 /// Returns the host mask.
236 ///
237 /// # Examples
238 ///
239 /// ```
240 /// # use std::net::IpAddr;
241 /// # use ipnet::IpNet;
242 /// #
243 /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
244 /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
245 ///
246 /// let net: IpNet = "fd00::/24".parse().unwrap();
247 /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
248 /// ```
249 pub fn hostmask(&self) -> IpAddr {
250 match *self {
251 IpNet::V4(ref a) => IpAddr::V4(a.hostmask()),
252 IpNet::V6(ref a) => IpAddr::V6(a.hostmask()),
253 }
254 }
255
256 /// Returns the network address.
257 ///
258 /// # Examples
259 ///
260 /// ```
261 /// # use std::net::IpAddr;
262 /// # use ipnet::IpNet;
263 /// #
264 /// let net: IpNet = "172.16.123.123/16".parse().unwrap();
265 /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
266 ///
267 /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
268 /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
269 /// ```
270 pub fn network(&self) -> IpAddr {
271 match *self {
272 IpNet::V4(ref a) => IpAddr::V4(a.network()),
273 IpNet::V6(ref a) => IpAddr::V6(a.network()),
274 }
275 }
276
277 /// Returns the broadcast address.
278 ///
279 /// # Examples
280 ///
281 /// ```
282 /// # use std::net::IpAddr;
283 /// # use ipnet::IpNet;
284 /// #
285 /// let net: IpNet = "172.16.0.0/22".parse().unwrap();
286 /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
287 ///
288 /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
289 /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
290 /// ```
291 pub fn broadcast(&self) -> IpAddr {
292 match *self {
293 IpNet::V4(ref a) => IpAddr::V4(a.broadcast()),
294 IpNet::V6(ref a) => IpAddr::V6(a.broadcast()),
295 }
296 }
297
298 /// Returns the `IpNet` that contains this one.
299 ///
300 /// # Examples
301 ///
302 /// ```
303 /// # use ipnet::IpNet;
304 /// #
305 /// let n1: IpNet = "172.16.1.0/24".parse().unwrap();
306 /// let n2: IpNet = "172.16.0.0/23".parse().unwrap();
307 /// let n3: IpNet = "172.16.0.0/0".parse().unwrap();
308 ///
309 /// assert_eq!(n1.supernet().unwrap(), n2);
310 /// assert_eq!(n3.supernet(), None);
311 ///
312 /// let n1: IpNet = "fd00:ff00::/24".parse().unwrap();
313 /// let n2: IpNet = "fd00:fe00::/23".parse().unwrap();
314 /// let n3: IpNet = "fd00:fe00::/0".parse().unwrap();
315 ///
316 /// assert_eq!(n1.supernet().unwrap(), n2);
317 /// assert_eq!(n3.supernet(), None);
318 /// ```
319 pub fn supernet(&self) -> Option<IpNet> {
320 match *self {
321 IpNet::V4(ref a) => a.supernet().map(IpNet::V4),
322 IpNet::V6(ref a) => a.supernet().map(IpNet::V6),
323 }
324 }
325
326 /// Returns `true` if this network and the given network are
327 /// children of the same supernet.
328 ///
329 /// # Examples
330 ///
331 /// ```
332 /// # use ipnet::IpNet;
333 /// #
334 /// let n4_1: IpNet = "10.1.0.0/24".parse().unwrap();
335 /// let n4_2: IpNet = "10.1.1.0/24".parse().unwrap();
336 /// let n4_3: IpNet = "10.1.2.0/24".parse().unwrap();
337 /// let n6_1: IpNet = "fd00::/18".parse().unwrap();
338 /// let n6_2: IpNet = "fd00:4000::/18".parse().unwrap();
339 /// let n6_3: IpNet = "fd00:8000::/18".parse().unwrap();
340 ///
341 /// assert!( n4_1.is_sibling(&n4_2));
342 /// assert!(!n4_2.is_sibling(&n4_3));
343 /// assert!( n6_1.is_sibling(&n6_2));
344 /// assert!(!n6_2.is_sibling(&n6_3));
345 /// assert!(!n4_1.is_sibling(&n6_2));
346 /// ```
347 pub fn is_sibling(&self, other: &IpNet) -> bool {
348 match (*self, *other) {
349 (IpNet::V4(ref a), IpNet::V4(ref b)) => a.is_sibling(b),
350 (IpNet::V6(ref a), IpNet::V6(ref b)) => a.is_sibling(b),
351 _ => false,
352 }
353 }
354
355 /// Return an `Iterator` over the host addresses in this network.
356 ///
357 /// # Examples
358 ///
359 /// ```
360 /// # use std::net::IpAddr;
361 /// # use ipnet::IpNet;
362 /// #
363 /// let net: IpNet = "10.0.0.0/30".parse().unwrap();
364 /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
365 /// "10.0.0.1".parse::<IpAddr>().unwrap(),
366 /// "10.0.0.2".parse().unwrap(),
367 /// ]);
368 ///
369 /// let net: IpNet = "10.0.0.0/31".parse().unwrap();
370 /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
371 /// "10.0.0.0".parse::<IpAddr>().unwrap(),
372 /// "10.0.0.1".parse().unwrap(),
373 /// ]);
374 ///
375 /// let net: IpNet = "fd00::/126".parse().unwrap();
376 /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
377 /// "fd00::".parse::<IpAddr>().unwrap(),
378 /// "fd00::1".parse().unwrap(),
379 /// "fd00::2".parse().unwrap(),
380 /// "fd00::3".parse().unwrap(),
381 /// ]);
382 /// ```
383 pub fn hosts(&self) -> IpAddrRange {
384 match *self {
385 IpNet::V4(ref a) => IpAddrRange::V4(a.hosts()),
386 IpNet::V6(ref a) => IpAddrRange::V6(a.hosts()),
387 }
388 }
389
390 /// Returns an `Iterator` over the subnets of this network with the
391 /// given prefix length.
392 ///
393 /// # Examples
394 ///
395 /// ```
396 /// # use ipnet::{IpNet, PrefixLenError};
397 /// #
398 /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
399 /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<IpNet>>(), vec![
400 /// "10.0.0.0/26".parse::<IpNet>().unwrap(),
401 /// "10.0.0.64/26".parse().unwrap(),
402 /// "10.0.0.128/26".parse().unwrap(),
403 /// "10.0.0.192/26".parse().unwrap(),
404 /// ]);
405 ///
406 /// let net: IpNet = "fd00::/16".parse().unwrap();
407 /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<IpNet>>(), vec![
408 /// "fd00::/18".parse::<IpNet>().unwrap(),
409 /// "fd00:4000::/18".parse().unwrap(),
410 /// "fd00:8000::/18".parse().unwrap(),
411 /// "fd00:c000::/18".parse().unwrap(),
412 /// ]);
413 ///
414 /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
415 /// assert_eq!(net.subnets(23), Err(PrefixLenError));
416 ///
417 /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
418 /// assert_eq!(net.subnets(33), Err(PrefixLenError));
419 ///
420 /// let net: IpNet = "fd00::/16".parse().unwrap();
421 /// assert_eq!(net.subnets(15), Err(PrefixLenError));
422 ///
423 /// let net: IpNet = "fd00::/16".parse().unwrap();
424 /// assert_eq!(net.subnets(129), Err(PrefixLenError));
425 /// ```
426 pub fn subnets(&self, new_prefix_len: u8) -> Result<IpSubnets, PrefixLenError> {
427 match *self {
428 IpNet::V4(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V4),
429 IpNet::V6(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V6),
430 }
431 }
432
433 /// Test if a network address contains either another network
434 /// address or an IP address.
435 ///
436 /// # Examples
437 ///
438 /// ```
439 /// # use std::net::IpAddr;
440 /// # use ipnet::IpNet;
441 /// #
442 /// let net4: IpNet = "192.168.0.0/24".parse().unwrap();
443 /// let net4_yes: IpNet = "192.168.0.0/25".parse().unwrap();
444 /// let net4_no: IpNet = "192.168.0.0/23".parse().unwrap();
445 /// let ip4_yes: IpAddr = "192.168.0.1".parse().unwrap();
446 /// let ip4_no: IpAddr = "192.168.1.0".parse().unwrap();
447 ///
448 /// assert!(net4.contains(&net4));
449 /// assert!(net4.contains(&net4_yes));
450 /// assert!(!net4.contains(&net4_no));
451 /// assert!(net4.contains(&ip4_yes));
452 /// assert!(!net4.contains(&ip4_no));
453 ///
454 ///
455 /// let net6: IpNet = "fd00::/16".parse().unwrap();
456 /// let net6_yes: IpNet = "fd00::/17".parse().unwrap();
457 /// let net6_no: IpNet = "fd00::/15".parse().unwrap();
458 /// let ip6_yes: IpAddr = "fd00::1".parse().unwrap();
459 /// let ip6_no: IpAddr = "fd01::".parse().unwrap();
460 ///
461 /// assert!(net6.contains(&net6));
462 /// assert!(net6.contains(&net6_yes));
463 /// assert!(!net6.contains(&net6_no));
464 /// assert!(net6.contains(&ip6_yes));
465 /// assert!(!net6.contains(&ip6_no));
466 ///
467 /// assert!(!net4.contains(&net6));
468 /// assert!(!net6.contains(&net4));
469 /// assert!(!net4.contains(&ip6_no));
470 /// assert!(!net6.contains(&ip4_no));
471 /// ```
472 pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
473 Contains::contains(self, other)
474 }
475
476 /// Aggregate a `Vec` of `IpNet`s and return the result as a new
477 /// `Vec`.
478 ///
479 /// # Examples
480 ///
481 /// ```
482 /// # use ipnet::IpNet;
483 /// #
484 /// let nets = vec![
485 /// "10.0.0.0/24".parse::<IpNet>().unwrap(),
486 /// "10.0.1.0/24".parse().unwrap(),
487 /// "10.0.2.0/24".parse().unwrap(),
488 /// "fd00::/18".parse().unwrap(),
489 /// "fd00:4000::/18".parse().unwrap(),
490 /// "fd00:8000::/18".parse().unwrap(),
491 /// ];
492 ///
493 /// assert_eq!(IpNet::aggregate(&nets), vec![
494 /// "10.0.0.0/23".parse::<IpNet>().unwrap(),
495 /// "10.0.2.0/24".parse().unwrap(),
496 /// "fd00::/17".parse().unwrap(),
497 /// "fd00:8000::/18".parse().unwrap(),
498 /// ]);
499 /// ```
500 pub fn aggregate(networks: &Vec<IpNet>) -> Vec<IpNet> {
501 // It's 2.5x faster to split the input up and run them using the
502 // specific IPv4 and IPV6 implementations. merge_intervals() and
503 // the comparisons are much faster running over integers.
504 let mut ipv4nets: Vec<Ipv4Net> = Vec::new();
505 let mut ipv6nets: Vec<Ipv6Net> = Vec::new();
506
507 for n in networks {
508 match *n {
509 IpNet::V4(x) => ipv4nets.push(x),
510 IpNet::V6(x) => ipv6nets.push(x),
511 }
512 }
513
514 let mut res: Vec<IpNet> = Vec::new();
515 let ipv4aggs = Ipv4Net::aggregate(&ipv4nets);
516 let ipv6aggs = Ipv6Net::aggregate(&ipv6nets);
517 res.extend::<Vec<IpNet>>(ipv4aggs.into_iter().map(IpNet::V4).collect::<Vec<IpNet>>());
518 res.extend::<Vec<IpNet>>(ipv6aggs.into_iter().map(IpNet::V6).collect::<Vec<IpNet>>());
519 res
520 }
521}
522
523impl Default for IpNet {
524 fn default() -> Self {
525 Self::V4(Ipv4Net::default())
526 }
527}
528
529impl fmt::Debug for IpNet {
530 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
531 fmt::Display::fmt(self, f:fmt)
532 }
533}
534
535impl fmt::Display for IpNet {
536 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
537 match *self {
538 IpNet::V4(ref a: &Ipv4Net) => a.fmt(fmt),
539 IpNet::V6(ref a: &Ipv6Net) => a.fmt(fmt),
540 }
541 }
542}
543
544impl From<Ipv4Net> for IpNet {
545 fn from(net: Ipv4Net) -> IpNet {
546 IpNet::V4(net)
547 }
548}
549
550impl From<Ipv6Net> for IpNet {
551 fn from(net: Ipv6Net) -> IpNet {
552 IpNet::V6(net)
553 }
554}
555
556impl From<IpAddr> for IpNet {
557 fn from(addr: IpAddr) -> IpNet {
558 match addr {
559 IpAddr::V4(a: Ipv4Addr) => IpNet::V4(a.into()),
560 IpAddr::V6(a: Ipv6Addr) => IpNet::V6(a.into()),
561 }
562 }
563}
564
565impl Ipv4Net {
566 /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
567 /// length.
568 ///
569 /// # Examples
570 ///
571 /// ```
572 /// use std::net::Ipv4Addr;
573 /// use ipnet::{Ipv4Net, PrefixLenError};
574 ///
575 /// let net = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 24);
576 /// assert!(net.is_ok());
577 ///
578 /// let bad_prefix_len = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 33);
579 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
580 /// ```
581 #[inline]
582 pub const fn new(ip: Ipv4Addr, prefix_len: u8) -> Result<Ipv4Net, PrefixLenError> {
583 if prefix_len > 32 {
584 return Err(PrefixLenError);
585 }
586 Ok(Ipv4Net { addr: ip, prefix_len: prefix_len })
587 }
588
589 /// Creates a new IPv4 network address from an `Ipv4Addr` and netmask.
590 ///
591 /// # Examples
592 ///
593 /// ```
594 /// use std::net::Ipv4Addr;
595 /// use ipnet::{Ipv4Net, PrefixLenError};
596 ///
597 /// let net = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 255, 0));
598 /// assert!(net.is_ok());
599 ///
600 /// let bad_prefix_len = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 0, 1));
601 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
602 /// ```
603 pub fn with_netmask(ip: Ipv4Addr, netmask: Ipv4Addr) -> Result<Ipv4Net, PrefixLenError> {
604 let prefix = ipv4_mask_to_prefix(netmask)?;
605 Self::new(ip, prefix)
606 }
607
608 /// Returns a copy of the network with the address truncated to the
609 /// prefix length.
610 ///
611 /// # Examples
612 ///
613 /// ```
614 /// # use ipnet::Ipv4Net;
615 /// #
616 /// assert_eq!(
617 /// "192.168.12.34/16".parse::<Ipv4Net>().unwrap().trunc(),
618 /// "192.168.0.0/16".parse().unwrap()
619 /// );
620 /// ```
621 pub fn trunc(&self) -> Ipv4Net {
622 Ipv4Net::new(self.network(), self.prefix_len).unwrap()
623 }
624
625 /// Returns the address.
626 #[inline]
627 pub const fn addr(&self) -> Ipv4Addr {
628 self.addr
629 }
630
631 /// Returns the prefix length.
632 #[inline]
633 pub const fn prefix_len(&self) -> u8 {
634 self.prefix_len
635 }
636
637 /// Returns the maximum valid prefix length.
638 #[inline]
639 pub const fn max_prefix_len(&self) -> u8 {
640 32
641 }
642
643 /// Returns the network mask.
644 ///
645 /// # Examples
646 ///
647 /// ```
648 /// # use std::net::Ipv4Addr;
649 /// # use ipnet::Ipv4Net;
650 /// #
651 /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
652 /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
653 /// ```
654 pub fn netmask(&self) -> Ipv4Addr {
655 Ipv4Addr::from(self.netmask_u32())
656 }
657
658 fn netmask_u32(&self) -> u32 {
659 u32::max_value().checked_shl(32 - self.prefix_len as u32).unwrap_or(0)
660 }
661
662 /// Returns the host mask.
663 ///
664 /// # Examples
665 ///
666 /// ```
667 /// # use std::net::Ipv4Addr;
668 /// # use ipnet::Ipv4Net;
669 /// #
670 /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
671 /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
672 /// ```
673 pub fn hostmask(&self) -> Ipv4Addr {
674 Ipv4Addr::from(self.hostmask_u32())
675 }
676
677 fn hostmask_u32(&self) -> u32 {
678 u32::max_value().checked_shr(self.prefix_len as u32).unwrap_or(0)
679 }
680
681 /// Returns the network address.
682 ///
683 /// # Examples
684 ///
685 /// ```
686 /// # use std::net::Ipv4Addr;
687 /// # use ipnet::Ipv4Net;
688 /// #
689 /// let net: Ipv4Net = "172.16.123.123/16".parse().unwrap();
690 /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
691 /// ```
692 pub fn network(&self) -> Ipv4Addr {
693 Ipv4Addr::from(u32::from(self.addr) & self.netmask_u32())
694 }
695
696 /// Returns the broadcast address.
697 ///
698 /// # Examples
699 ///
700 /// ```
701 /// # use std::net::Ipv4Addr;
702 /// # use ipnet::Ipv4Net;
703 /// #
704 /// let net: Ipv4Net = "172.16.0.0/22".parse().unwrap();
705 /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
706 /// ```
707 pub fn broadcast(&self) -> Ipv4Addr {
708 Ipv4Addr::from(u32::from(self.addr) | self.hostmask_u32())
709 }
710
711 /// Returns the `Ipv4Net` that contains this one.
712 ///
713 /// # Examples
714 ///
715 /// ```
716 /// # use ipnet::Ipv4Net;
717 /// #
718 /// let n1: Ipv4Net = "172.16.1.0/24".parse().unwrap();
719 /// let n2: Ipv4Net = "172.16.0.0/23".parse().unwrap();
720 /// let n3: Ipv4Net = "172.16.0.0/0".parse().unwrap();
721 ///
722 /// assert_eq!(n1.supernet().unwrap(), n2);
723 /// assert_eq!(n3.supernet(), None);
724 /// ```
725 pub fn supernet(&self) -> Option<Ipv4Net> {
726 Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
727 }
728
729 /// Returns `true` if this network and the given network are
730 /// children of the same supernet.
731 ///
732 /// # Examples
733 ///
734 /// ```
735 /// # use ipnet::Ipv4Net;
736 /// #
737 /// let n1: Ipv4Net = "10.1.0.0/24".parse().unwrap();
738 /// let n2: Ipv4Net = "10.1.1.0/24".parse().unwrap();
739 /// let n3: Ipv4Net = "10.1.2.0/24".parse().unwrap();
740 ///
741 /// assert!(n1.is_sibling(&n2));
742 /// assert!(!n2.is_sibling(&n3));
743 /// ```
744 pub fn is_sibling(&self, other: &Ipv4Net) -> bool {
745 self.prefix_len > 0 &&
746 self.prefix_len == other.prefix_len &&
747 self.supernet().unwrap().contains(other)
748 }
749
750 /// Return an `Iterator` over the host addresses in this network.
751 ///
752 /// If the prefix length is less than 31 both the network address
753 /// and broadcast address are excluded. These are only valid host
754 /// addresses when the prefix length is 31.
755 ///
756 /// # Examples
757 ///
758 /// ```
759 /// # use std::net::Ipv4Addr;
760 /// # use ipnet::Ipv4Net;
761 /// #
762 /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
763 /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
764 /// "10.0.0.1".parse::<Ipv4Addr>().unwrap(),
765 /// "10.0.0.2".parse().unwrap(),
766 /// ]);
767 ///
768 /// let net: Ipv4Net = "10.0.0.0/31".parse().unwrap();
769 /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
770 /// "10.0.0.0".parse::<Ipv4Addr>().unwrap(),
771 /// "10.0.0.1".parse().unwrap(),
772 /// ]);
773 /// ```
774 pub fn hosts(&self) -> Ipv4AddrRange {
775 let mut start = self.network();
776 let mut end = self.broadcast();
777
778 if self.prefix_len < 31 {
779 start = start.saturating_add(1);
780 end = end.saturating_sub(1);
781 }
782
783 Ipv4AddrRange::new(start, end)
784 }
785
786 /// Returns an `Iterator` over the subnets of this network with the
787 /// given prefix length.
788 ///
789 /// # Examples
790 ///
791 /// ```
792 /// # use ipnet::{Ipv4Net, PrefixLenError};
793 /// #
794 /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
795 /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<Ipv4Net>>(), vec![
796 /// "10.0.0.0/26".parse::<Ipv4Net>().unwrap(),
797 /// "10.0.0.64/26".parse().unwrap(),
798 /// "10.0.0.128/26".parse().unwrap(),
799 /// "10.0.0.192/26".parse().unwrap(),
800 /// ]);
801 ///
802 /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
803 /// assert_eq!(net.subnets(32).unwrap().collect::<Vec<Ipv4Net>>(), vec![
804 /// "10.0.0.0/32".parse::<Ipv4Net>().unwrap(),
805 /// "10.0.0.1/32".parse().unwrap(),
806 /// "10.0.0.2/32".parse().unwrap(),
807 /// "10.0.0.3/32".parse().unwrap(),
808 /// ]);
809 ///
810 /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
811 /// assert_eq!(net.subnets(23), Err(PrefixLenError));
812 ///
813 /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
814 /// assert_eq!(net.subnets(33), Err(PrefixLenError));
815 /// ```
816 pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv4Subnets, PrefixLenError> {
817 if self.prefix_len > new_prefix_len || new_prefix_len > 32 {
818 return Err(PrefixLenError);
819 }
820
821 Ok(Ipv4Subnets::new(
822 self.network(),
823 self.broadcast(),
824 new_prefix_len,
825 ))
826 }
827
828 /// Test if a network address contains either another network
829 /// address or an IP address.
830 ///
831 /// # Examples
832 ///
833 /// ```
834 /// # use std::net::Ipv4Addr;
835 /// # use ipnet::Ipv4Net;
836 /// #
837 /// let net: Ipv4Net = "192.168.0.0/24".parse().unwrap();
838 /// let net_yes: Ipv4Net = "192.168.0.0/25".parse().unwrap();
839 /// let net_no: Ipv4Net = "192.168.0.0/23".parse().unwrap();
840 /// let ip_yes: Ipv4Addr = "192.168.0.1".parse().unwrap();
841 /// let ip_no: Ipv4Addr = "192.168.1.0".parse().unwrap();
842 ///
843 /// assert!(net.contains(&net));
844 /// assert!(net.contains(&net_yes));
845 /// assert!(!net.contains(&net_no));
846 /// assert!(net.contains(&ip_yes));
847 /// assert!(!net.contains(&ip_no));
848 /// ```
849 pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
850 Contains::contains(self, other)
851 }
852
853 // It is significantly faster to work on u32 than Ipv4Addr.
854 fn interval(&self) -> (u32, u32) {
855 (
856 u32::from(self.network()),
857 u32::from(self.broadcast()).saturating_add(1),
858 )
859 }
860
861 /// Aggregate a `Vec` of `Ipv4Net`s and return the result as a new
862 /// `Vec`.
863 ///
864 /// # Examples
865 ///
866 /// ```
867 /// # use ipnet::Ipv4Net;
868 /// #
869 /// let nets = vec![
870 /// "10.0.0.0/24".parse::<Ipv4Net>().unwrap(),
871 /// "10.0.1.0/24".parse().unwrap(),
872 /// "10.0.2.0/24".parse().unwrap(),
873 /// ];
874 ///
875 /// assert_eq!(Ipv4Net::aggregate(&nets), vec![
876 /// "10.0.0.0/23".parse::<Ipv4Net>().unwrap(),
877 /// "10.0.2.0/24".parse().unwrap(),
878 /// ]);
879 pub fn aggregate(networks: &Vec<Ipv4Net>) -> Vec<Ipv4Net> {
880 let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
881 intervals = merge_intervals(intervals);
882 let mut res: Vec<Ipv4Net> = Vec::new();
883
884 for (start, mut end) in intervals {
885 if end != std::u32::MAX {
886 end = end.saturating_sub(1)
887 }
888 let iter = Ipv4Subnets::new(start.into(), end.into(), 0);
889 res.extend(iter);
890 }
891 res
892 }
893}
894
895impl Default for Ipv4Net {
896 fn default() -> Self {
897 Self {
898 addr: Ipv4Addr::from(0),
899 prefix_len: 0,
900 }
901 }
902}
903
904impl fmt::Debug for Ipv4Net {
905 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
906 fmt::Display::fmt(self, f:fmt)
907 }
908}
909
910impl fmt::Display for Ipv4Net {
911 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
912 write!(fmt, "{}/{}", self.addr, self.prefix_len)
913 }
914}
915
916impl From<Ipv4Addr> for Ipv4Net {
917 fn from(addr: Ipv4Addr) -> Ipv4Net {
918 Ipv4Net { addr, prefix_len: 32 }
919 }
920}
921
922impl Ipv6Net {
923 /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
924 /// length.
925 ///
926 /// # Examples
927 ///
928 /// ```
929 /// use std::net::Ipv6Addr;
930 /// use ipnet::{Ipv6Net, PrefixLenError};
931 ///
932 /// let net = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
933 /// assert!(net.is_ok());
934 ///
935 /// let bad_prefix_len = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
936 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
937 /// ```
938 #[inline]
939 pub const fn new(ip: Ipv6Addr, prefix_len: u8) -> Result<Ipv6Net, PrefixLenError> {
940 if prefix_len > 128 {
941 return Err(PrefixLenError);
942 }
943 Ok(Ipv6Net { addr: ip, prefix_len: prefix_len })
944 }
945
946 /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask.
947 ///
948 /// # Examples
949 ///
950 /// ```
951 /// use std::net::Ipv6Addr;
952 /// use ipnet::{Ipv6Net, PrefixLenError};
953 ///
954 /// let net = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0000_0000_0000_0000));
955 /// assert!(net.is_ok());
956 ///
957 /// let bad_prefix_len = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0001_0000_0000_0000));
958 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
959 /// ```
960 pub fn with_netmask(ip: Ipv6Addr, netmask: Ipv6Addr) -> Result<Ipv6Net, PrefixLenError> {
961 let prefix = ipv6_mask_to_prefix(netmask)?;
962 Self::new(ip, prefix)
963 }
964
965 /// Returns a copy of the network with the address truncated to the
966 /// prefix length.
967 ///
968 /// # Examples
969 ///
970 /// ```
971 /// # use ipnet::Ipv6Net;
972 /// #
973 /// assert_eq!(
974 /// "fd00::1:2:3:4/16".parse::<Ipv6Net>().unwrap().trunc(),
975 /// "fd00::/16".parse().unwrap()
976 /// );
977 /// ```
978 pub fn trunc(&self) -> Ipv6Net {
979 Ipv6Net::new(self.network(), self.prefix_len).unwrap()
980 }
981
982 /// Returns the address.
983 #[inline]
984 pub const fn addr(&self) -> Ipv6Addr {
985 self.addr
986 }
987
988 /// Returns the prefix length.
989 #[inline]
990 pub const fn prefix_len(&self) -> u8 {
991 self.prefix_len
992 }
993
994 /// Returns the maximum valid prefix length.
995 #[inline]
996 pub const fn max_prefix_len(&self) -> u8 {
997 128
998 }
999
1000 /// Returns the network mask.
1001 ///
1002 /// # Examples
1003 ///
1004 /// ```
1005 /// # use std::net::Ipv6Addr;
1006 /// # use ipnet::Ipv6Net;
1007 /// #
1008 /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1009 /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
1010 /// ```
1011 pub fn netmask(&self) -> Ipv6Addr {
1012 self.netmask_u128().into()
1013 }
1014
1015 fn netmask_u128(&self) -> u128 {
1016 u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value())
1017 }
1018
1019 /// Returns the host mask.
1020 ///
1021 /// # Examples
1022 ///
1023 /// ```
1024 /// # use std::net::Ipv6Addr;
1025 /// # use ipnet::Ipv6Net;
1026 /// #
1027 /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1028 /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1029 /// ```
1030 pub fn hostmask(&self) -> Ipv6Addr {
1031 self.hostmask_u128().into()
1032 }
1033
1034 fn hostmask_u128(&self) -> u128 {
1035 u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value())
1036 }
1037
1038 /// Returns the network address.
1039 ///
1040 /// # Examples
1041 ///
1042 /// ```
1043 /// # use std::net::Ipv6Addr;
1044 /// # use ipnet::Ipv6Net;
1045 /// #
1046 /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1047 /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
1048 /// ```
1049 pub fn network(&self) -> Ipv6Addr {
1050 (u128::from(self.addr) & self.netmask_u128()).into()
1051 }
1052
1053 /// Returns the last address.
1054 ///
1055 /// Technically there is no such thing as a broadcast address for
1056 /// IPv6. The name is used for consistency with colloquial usage.
1057 ///
1058 /// # Examples
1059 ///
1060 /// ```
1061 /// # use std::net::Ipv6Addr;
1062 /// # use ipnet::Ipv6Net;
1063 /// #
1064 /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1065 /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1066 /// ```
1067 pub fn broadcast(&self) -> Ipv6Addr {
1068 (u128::from(self.addr) | self.hostmask_u128()).into()
1069 }
1070
1071 /// Returns the `Ipv6Net` that contains this one.
1072 ///
1073 /// # Examples
1074 ///
1075 /// ```
1076 /// # use std::str::FromStr;
1077 /// # use ipnet::Ipv6Net;
1078 /// #
1079 /// let n1: Ipv6Net = "fd00:ff00::/24".parse().unwrap();
1080 /// let n2: Ipv6Net = "fd00:fe00::/23".parse().unwrap();
1081 /// let n3: Ipv6Net = "fd00:fe00::/0".parse().unwrap();
1082 ///
1083 /// assert_eq!(n1.supernet().unwrap(), n2);
1084 /// assert_eq!(n3.supernet(), None);
1085 /// ```
1086 pub fn supernet(&self) -> Option<Ipv6Net> {
1087 Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
1088 }
1089
1090 /// Returns `true` if this network and the given network are
1091 /// children of the same supernet.
1092 ///
1093 /// # Examples
1094 ///
1095 /// ```
1096 /// # use ipnet::Ipv6Net;
1097 /// #
1098 /// let n1: Ipv6Net = "fd00::/18".parse().unwrap();
1099 /// let n2: Ipv6Net = "fd00:4000::/18".parse().unwrap();
1100 /// let n3: Ipv6Net = "fd00:8000::/18".parse().unwrap();
1101 ///
1102 /// assert!(n1.is_sibling(&n2));
1103 /// assert!(!n2.is_sibling(&n3));
1104 /// ```
1105 pub fn is_sibling(&self, other: &Ipv6Net) -> bool {
1106 self.prefix_len > 0 &&
1107 self.prefix_len == other.prefix_len &&
1108 self.supernet().unwrap().contains(other)
1109 }
1110
1111 /// Return an `Iterator` over the host addresses in this network.
1112 ///
1113 /// # Examples
1114 ///
1115 /// ```
1116 /// # use std::net::Ipv6Addr;
1117 /// # use ipnet::Ipv6Net;
1118 /// #
1119 /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1120 /// assert_eq!(net.hosts().collect::<Vec<Ipv6Addr>>(), vec![
1121 /// "fd00::".parse::<Ipv6Addr>().unwrap(),
1122 /// "fd00::1".parse().unwrap(),
1123 /// "fd00::2".parse().unwrap(),
1124 /// "fd00::3".parse().unwrap(),
1125 /// ]);
1126 /// ```
1127 pub fn hosts(&self) -> Ipv6AddrRange {
1128 Ipv6AddrRange::new(self.network(), self.broadcast())
1129 }
1130
1131 /// Returns an `Iterator` over the subnets of this network with the
1132 /// given prefix length.
1133 ///
1134 /// # Examples
1135 ///
1136 /// ```
1137 /// # use ipnet::{Ipv6Net, PrefixLenError};
1138 /// #
1139 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1140 /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1141 /// "fd00::/18".parse::<Ipv6Net>().unwrap(),
1142 /// "fd00:4000::/18".parse().unwrap(),
1143 /// "fd00:8000::/18".parse().unwrap(),
1144 /// "fd00:c000::/18".parse().unwrap(),
1145 /// ]);
1146 ///
1147 /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1148 /// assert_eq!(net.subnets(128).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1149 /// "fd00::/128".parse::<Ipv6Net>().unwrap(),
1150 /// "fd00::1/128".parse().unwrap(),
1151 /// "fd00::2/128".parse().unwrap(),
1152 /// "fd00::3/128".parse().unwrap(),
1153 /// ]);
1154 ///
1155 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1156 /// assert_eq!(net.subnets(15), Err(PrefixLenError));
1157 ///
1158 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1159 /// assert_eq!(net.subnets(129), Err(PrefixLenError));
1160 /// ```
1161 pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv6Subnets, PrefixLenError> {
1162 if self.prefix_len > new_prefix_len || new_prefix_len > 128 {
1163 return Err(PrefixLenError);
1164 }
1165
1166 Ok(Ipv6Subnets::new(
1167 self.network(),
1168 self.broadcast(),
1169 new_prefix_len,
1170 ))
1171 }
1172
1173 /// Test if a network address contains either another network
1174 /// address or an IP address.
1175 ///
1176 /// # Examples
1177 ///
1178 /// ```
1179 /// # use std::net::Ipv6Addr;
1180 /// # use ipnet::Ipv6Net;
1181 /// #
1182 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1183 /// let net_yes: Ipv6Net = "fd00::/17".parse().unwrap();
1184 /// let net_no: Ipv6Net = "fd00::/15".parse().unwrap();
1185 /// let ip_yes: Ipv6Addr = "fd00::1".parse().unwrap();
1186 /// let ip_no: Ipv6Addr = "fd01::".parse().unwrap();
1187 ///
1188 /// assert!(net.contains(&net));
1189 /// assert!(net.contains(&net_yes));
1190 /// assert!(!net.contains(&net_no));
1191 /// assert!(net.contains(&ip_yes));
1192 /// assert!(!net.contains(&ip_no));
1193 /// ```
1194 pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
1195 Contains::contains(self, other)
1196 }
1197
1198 // It is significantly faster to work on u128 that Ipv6Addr.
1199 fn interval(&self) -> (u128, u128) {
1200 (
1201 u128::from(self.network()),
1202 u128::from(self.broadcast()).saturating_add(1),
1203 )
1204 }
1205
1206 /// Aggregate a `Vec` of `Ipv6Net`s and return the result as a new
1207 /// `Vec`.
1208 ///
1209 /// # Examples
1210 ///
1211 /// ```
1212 /// # use ipnet::Ipv6Net;
1213 /// #
1214 /// let nets = vec![
1215 /// "fd00::/18".parse::<Ipv6Net>().unwrap(),
1216 /// "fd00:4000::/18".parse().unwrap(),
1217 /// "fd00:8000::/18".parse().unwrap(),
1218 /// ];
1219 /// assert_eq!(Ipv6Net::aggregate(&nets), vec![
1220 /// "fd00::/17".parse::<Ipv6Net>().unwrap(),
1221 /// "fd00:8000::/18".parse().unwrap(),
1222 /// ]);
1223 /// ```
1224 pub fn aggregate(networks: &Vec<Ipv6Net>) -> Vec<Ipv6Net> {
1225 let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
1226 intervals = merge_intervals(intervals);
1227 let mut res: Vec<Ipv6Net> = Vec::new();
1228
1229 for (start, mut end) in intervals {
1230 if end != std::u128::MAX {
1231 end = end.saturating_sub(1)
1232 }
1233 let iter = Ipv6Subnets::new(start.into(), end.into(), 0);
1234 res.extend(iter);
1235 }
1236 res
1237 }
1238}
1239
1240impl Default for Ipv6Net {
1241 fn default() -> Self {
1242 Self {
1243 addr: Ipv6Addr::from(0),
1244 prefix_len: 0,
1245 }
1246 }
1247}
1248
1249impl fmt::Debug for Ipv6Net {
1250 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1251 fmt::Display::fmt(self, f:fmt)
1252 }
1253}
1254
1255impl fmt::Display for Ipv6Net {
1256 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1257 write!(fmt, "{}/{}", self.addr, self.prefix_len)
1258 }
1259}
1260
1261impl From<Ipv6Addr> for Ipv6Net {
1262 fn from(addr: Ipv6Addr) -> Ipv6Net {
1263 Ipv6Net { addr, prefix_len: 128 }
1264 }
1265}
1266
1267/// Provides a method to test if a network address contains either
1268/// another network address or an IP address.
1269///
1270/// # Examples
1271///
1272/// ```
1273/// # use std::net::IpAddr;
1274/// # use ipnet::IpNet;
1275/// #
1276/// let n4_1: IpNet = "10.1.1.0/24".parse().unwrap();
1277/// let n4_2: IpNet = "10.1.1.0/26".parse().unwrap();
1278/// let n4_3: IpNet = "10.1.2.0/26".parse().unwrap();
1279/// let ip4_1: IpAddr = "10.1.1.1".parse().unwrap();
1280/// let ip4_2: IpAddr = "10.1.2.1".parse().unwrap();
1281///
1282/// let n6_1: IpNet = "fd00::/16".parse().unwrap();
1283/// let n6_2: IpNet = "fd00::/17".parse().unwrap();
1284/// let n6_3: IpNet = "fd01::/17".parse().unwrap();
1285/// let ip6_1: IpAddr = "fd00::1".parse().unwrap();
1286/// let ip6_2: IpAddr = "fd01::1".parse().unwrap();
1287///
1288/// assert!(n4_1.contains(&n4_2));
1289/// assert!(!n4_1.contains(&n4_3));
1290/// assert!(n4_1.contains(&ip4_1));
1291/// assert!(!n4_1.contains(&ip4_2));
1292///
1293/// assert!(n6_1.contains(&n6_2));
1294/// assert!(!n6_1.contains(&n6_3));
1295/// assert!(n6_1.contains(&ip6_1));
1296/// assert!(!n6_1.contains(&ip6_2));
1297///
1298/// assert!(!n4_1.contains(&n6_1) && !n6_1.contains(&n4_1));
1299/// assert!(!n4_1.contains(&ip6_1) && !n6_1.contains(&ip4_1));
1300/// ```
1301pub trait Contains<T> {
1302 fn contains(&self, other: T) -> bool;
1303}
1304
1305impl<'a> Contains<&'a IpNet> for IpNet {
1306 fn contains(&self, other: &IpNet) -> bool {
1307 match (*self, *other) {
1308 (IpNet::V4(ref a: &Ipv4Net), IpNet::V4(ref b: &Ipv4Net)) => a.contains(b),
1309 (IpNet::V6(ref a: &Ipv6Net), IpNet::V6(ref b: &Ipv6Net)) => a.contains(b),
1310 _ => false,
1311 }
1312 }
1313}
1314
1315impl<'a> Contains<&'a IpAddr> for IpNet {
1316 fn contains(&self, other: &IpAddr) -> bool {
1317 match (*self, *other) {
1318 (IpNet::V4(ref a: &Ipv4Net), IpAddr::V4(ref b: &Ipv4Addr)) => a.contains(b),
1319 (IpNet::V6(ref a: &Ipv6Net), IpAddr::V6(ref b: &Ipv6Addr)) => a.contains(b),
1320 _ => false,
1321 }
1322 }
1323}
1324
1325impl<'a> Contains<&'a Ipv4Net> for Ipv4Net {
1326 fn contains(&self, other: &'a Ipv4Net) -> bool {
1327 self.network() <= other.network() && other.broadcast() <= self.broadcast()
1328 }
1329}
1330
1331impl<'a> Contains<&'a Ipv4Addr> for Ipv4Net {
1332 fn contains(&self, other: &'a Ipv4Addr) -> bool {
1333 self.network() <= *other && *other <= self.broadcast()
1334 }
1335}
1336
1337impl<'a> Contains<&'a Ipv6Net> for Ipv6Net {
1338 fn contains(&self, other: &'a Ipv6Net) -> bool {
1339 self.network() <= other.network() && other.broadcast() <= self.broadcast()
1340 }
1341}
1342
1343impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net {
1344 fn contains(&self, other: &'a Ipv6Addr) -> bool {
1345 self.network() <= *other && *other <= self.broadcast()
1346 }
1347}
1348
1349/// An `Iterator` that generates IP network addresses, either IPv4 or
1350/// IPv6.
1351///
1352/// Generates the subnets between the provided `start` and `end` IP
1353/// addresses inclusive of `end`. Each iteration generates the next
1354/// network address of the largest valid size it can, while using a
1355/// prefix length not less than `min_prefix_len`.
1356///
1357/// # Examples
1358///
1359/// ```
1360/// # use std::net::{Ipv4Addr, Ipv6Addr};
1361/// # use std::str::FromStr;
1362/// # use ipnet::{IpNet, IpSubnets, Ipv4Subnets, Ipv6Subnets};
1363/// let subnets = IpSubnets::from(Ipv4Subnets::new(
1364/// "10.0.0.0".parse().unwrap(),
1365/// "10.0.0.239".parse().unwrap(),
1366/// 26,
1367/// ));
1368///
1369/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1370/// "10.0.0.0/26".parse().unwrap(),
1371/// "10.0.0.64/26".parse().unwrap(),
1372/// "10.0.0.128/26".parse().unwrap(),
1373/// "10.0.0.192/27".parse().unwrap(),
1374/// "10.0.0.224/28".parse().unwrap(),
1375/// ]);
1376///
1377/// let subnets = IpSubnets::from(Ipv6Subnets::new(
1378/// "fd00::".parse().unwrap(),
1379/// "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1380/// 26,
1381/// ));
1382///
1383/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1384/// "fd00::/26".parse().unwrap(),
1385/// "fd00:40::/26".parse().unwrap(),
1386/// "fd00:80::/26".parse().unwrap(),
1387/// "fd00:c0::/27".parse().unwrap(),
1388/// "fd00:e0::/28".parse().unwrap(),
1389/// ]);
1390/// ```
1391#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1392pub enum IpSubnets {
1393 V4(Ipv4Subnets),
1394 V6(Ipv6Subnets),
1395}
1396
1397/// An `Iterator` that generates IPv4 network addresses.
1398///
1399/// Generates the subnets between the provided `start` and `end` IP
1400/// addresses inclusive of `end`. Each iteration generates the next
1401/// network address of the largest valid size it can, while using a
1402/// prefix length not less than `min_prefix_len`.
1403///
1404/// # Examples
1405///
1406/// ```
1407/// # use std::net::Ipv4Addr;
1408/// # use std::str::FromStr;
1409/// # use ipnet::{Ipv4Net, Ipv4Subnets};
1410/// let subnets = Ipv4Subnets::new(
1411/// "10.0.0.0".parse().unwrap(),
1412/// "10.0.0.239".parse().unwrap(),
1413/// 26,
1414/// );
1415///
1416/// assert_eq!(subnets.collect::<Vec<Ipv4Net>>(), vec![
1417/// "10.0.0.0/26".parse().unwrap(),
1418/// "10.0.0.64/26".parse().unwrap(),
1419/// "10.0.0.128/26".parse().unwrap(),
1420/// "10.0.0.192/27".parse().unwrap(),
1421/// "10.0.0.224/28".parse().unwrap(),
1422/// ]);
1423/// ```
1424#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1425pub struct Ipv4Subnets {
1426 start: Ipv4Addr,
1427 end: Ipv4Addr, // end is inclusive
1428 min_prefix_len: u8,
1429}
1430
1431/// An `Iterator` that generates IPv6 network addresses.
1432///
1433/// Generates the subnets between the provided `start` and `end` IP
1434/// addresses inclusive of `end`. Each iteration generates the next
1435/// network address of the largest valid size it can, while using a
1436/// prefix length not less than `min_prefix_len`.
1437///
1438/// # Examples
1439///
1440/// ```
1441/// # use std::net::Ipv6Addr;
1442/// # use std::str::FromStr;
1443/// # use ipnet::{Ipv6Net, Ipv6Subnets};
1444/// let subnets = Ipv6Subnets::new(
1445/// "fd00::".parse().unwrap(),
1446/// "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1447/// 26,
1448/// );
1449///
1450/// assert_eq!(subnets.collect::<Vec<Ipv6Net>>(), vec![
1451/// "fd00::/26".parse().unwrap(),
1452/// "fd00:40::/26".parse().unwrap(),
1453/// "fd00:80::/26".parse().unwrap(),
1454/// "fd00:c0::/27".parse().unwrap(),
1455/// "fd00:e0::/28".parse().unwrap(),
1456/// ]);
1457/// ```
1458#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1459pub struct Ipv6Subnets {
1460 start: Ipv6Addr,
1461 end: Ipv6Addr, // end is inclusive
1462 min_prefix_len: u8,
1463}
1464
1465impl Ipv4Subnets {
1466 pub fn new(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Self {
1467 Ipv4Subnets {
1468 start: start,
1469 end: end,
1470 min_prefix_len: min_prefix_len,
1471 }
1472 }
1473}
1474
1475impl Ipv6Subnets {
1476 pub fn new(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Self {
1477 Ipv6Subnets {
1478 start: start,
1479 end: end,
1480 min_prefix_len: min_prefix_len,
1481 }
1482 }
1483}
1484
1485impl From<Ipv4Subnets> for IpSubnets {
1486 fn from(i: Ipv4Subnets) -> IpSubnets {
1487 IpSubnets::V4(i)
1488 }
1489}
1490
1491impl From<Ipv6Subnets> for IpSubnets {
1492 fn from(i: Ipv6Subnets) -> IpSubnets {
1493 IpSubnets::V6(i)
1494 }
1495}
1496
1497impl Iterator for IpSubnets {
1498 type Item = IpNet;
1499
1500 fn next(&mut self) -> Option<Self::Item> {
1501 match *self {
1502 IpSubnets::V4(ref mut a: &mut Ipv4Subnets) => a.next().map(IpNet::V4),
1503 IpSubnets::V6(ref mut a: &mut Ipv6Subnets) => a.next().map(IpNet::V6),
1504 }
1505 }
1506}
1507
1508fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
1509 let range: u32 = end.saturating_sub(start).saturating_add(1);
1510 if range == std::u32::MAX && min_prefix_len == 0 {
1511 Ipv4Net::new(ip:start, min_prefix_len).unwrap()
1512 }
1513 else {
1514 let range_bits: u32 = 32u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1515 let start_tz: u32 = u32::from(start).trailing_zeros();
1516 let new_prefix_len: u32 = 32 - min(v1:range_bits, v2:start_tz);
1517 let next_prefix_len: u8 = max(v1:new_prefix_len as u8, v2:min_prefix_len);
1518 Ipv4Net::new(ip:start, next_prefix_len).unwrap()
1519 }
1520}
1521
1522fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
1523 let range: u128 = end.saturating_sub(start).saturating_add(1);
1524 if range == std::u128::MAX && min_prefix_len == 0 {
1525 Ipv6Net::new(ip:start, min_prefix_len).unwrap()
1526 }
1527 else {
1528 let range: u128 = end.saturating_sub(start).saturating_add(1);
1529 let range_bits: u32 = 128u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1530 let start_tz: u32 = u128::from(start).trailing_zeros();
1531 let new_prefix_len: u32 = 128 - min(v1:range_bits, v2:start_tz);
1532 let next_prefix_len: u8 = max(v1:new_prefix_len as u8, v2:min_prefix_len);
1533 Ipv6Net::new(ip:start, next_prefix_len).unwrap()
1534 }
1535}
1536
1537impl Iterator for Ipv4Subnets {
1538 type Item = Ipv4Net;
1539
1540 fn next(&mut self) -> Option<Self::Item> {
1541 match self.start.partial_cmp(&self.end) {
1542 Some(Less) => {
1543 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1544 self.start = next.broadcast().saturating_add(1);
1545
1546 // Stop the iterator if we saturated self.start. This
1547 // check worsens performance slightly but overall this
1548 // approach of operating on Ipv4Addr types is faster
1549 // than what we were doing before using Ipv4Net.
1550 if self.start == next.broadcast() {
1551 self.end.replace_zero();
1552 }
1553 Some(next)
1554 },
1555 Some(Equal) => {
1556 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1557 self.start = next.broadcast().saturating_add(1);
1558 self.end.replace_zero();
1559 Some(next)
1560 },
1561 _ => None,
1562 }
1563 }
1564}
1565
1566impl Iterator for Ipv6Subnets {
1567 type Item = Ipv6Net;
1568
1569 fn next(&mut self) -> Option<Self::Item> {
1570 match self.start.partial_cmp(&self.end) {
1571 Some(Less) => {
1572 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1573 self.start = next.broadcast().saturating_add(1);
1574
1575 // Stop the iterator if we saturated self.start. This
1576 // check worsens performance slightly but overall this
1577 // approach of operating on Ipv6Addr types is faster
1578 // than what we were doing before using Ipv6Net.
1579 if self.start == next.broadcast() {
1580 self.end.replace_zero();
1581 }
1582 Some(next)
1583 },
1584 Some(Equal) => {
1585 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1586 self.start = next.broadcast().saturating_add(1);
1587 self.end.replace_zero();
1588 Some(next)
1589 },
1590 _ => None,
1591 }
1592 }
1593}
1594
1595impl FusedIterator for IpSubnets {}
1596impl FusedIterator for Ipv4Subnets {}
1597impl FusedIterator for Ipv6Subnets {}
1598
1599// Generic function for merging a vector of intervals.
1600fn merge_intervals<T: Copy + Ord>(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> {
1601 if intervals.len() == 0 {
1602 return intervals;
1603 }
1604
1605 intervals.sort();
1606 let mut res: Vec<(T, T)> = Vec::new();
1607 let (mut start, mut end) = intervals[0];
1608
1609 let mut i = 1;
1610 let len = intervals.len();
1611 while i < len {
1612 let (next_start, next_end) = intervals[i];
1613 if end >= next_start {
1614 start = min(start, next_start);
1615 end = max(end, next_end);
1616 }
1617 else {
1618 res.push((start, end));
1619 start = next_start;
1620 end = next_end;
1621 }
1622 i += 1;
1623 }
1624
1625 res.push((start, end));
1626 res
1627}
1628
1629#[cfg(test)]
1630mod tests {
1631 use super::*;
1632
1633 macro_rules! make_ipnet_vec {
1634 ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
1635 ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
1636 }
1637
1638 #[test]
1639 fn test_make_ipnet_vec() {
1640 assert_eq!(
1641 make_ipnet_vec![
1642 "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
1643 "fd00::1/128", "fd00::2/127", "fd00::3/126",
1644 ],
1645 vec![
1646 "10.1.1.1/32".parse().unwrap(),
1647 "10.2.2.2/24".parse().unwrap(),
1648 "10.3.3.3/16".parse().unwrap(),
1649 "fd00::1/128".parse().unwrap(),
1650 "fd00::2/127".parse().unwrap(),
1651 "fd00::3/126".parse().unwrap(),
1652 ]
1653 );
1654 }
1655
1656 #[test]
1657 fn test_merge_intervals() {
1658 let v = vec![
1659 (0, 1), (1, 2), (2, 3),
1660 (11, 12), (13, 14), (10, 15), (11, 13),
1661 (20, 25), (24, 29),
1662 ];
1663
1664 let v_ok = vec![
1665 (0, 3),
1666 (10, 15),
1667 (20, 29),
1668 ];
1669
1670 let vv = vec![
1671 ([0, 1], [0, 2]), ([0, 2], [0, 3]), ([0, 0], [0, 1]),
1672 ([10, 15], [11, 0]), ([10, 0], [10, 16]),
1673 ];
1674
1675 let vv_ok = vec![
1676 ([0, 0], [0, 3]),
1677 ([10, 0], [11, 0]),
1678 ];
1679
1680 assert_eq!(merge_intervals(v), v_ok);
1681 assert_eq!(merge_intervals(vv), vv_ok);
1682 }
1683
1684 macro_rules! make_ipv4_subnets_test {
1685 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1686 #[test]
1687 fn $name() {
1688 let subnets = IpSubnets::from(Ipv4Subnets::new(
1689 $start.parse().unwrap(),
1690 $end.parse().unwrap(),
1691 $min_prefix_len,
1692 ));
1693 let results = make_ipnet_vec![$($x),*];
1694 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1695 }
1696 );
1697 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1698 make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1699 );
1700 }
1701
1702 macro_rules! make_ipv6_subnets_test {
1703 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1704 #[test]
1705 fn $name() {
1706 let subnets = IpSubnets::from(Ipv6Subnets::new(
1707 $start.parse().unwrap(),
1708 $end.parse().unwrap(),
1709 $min_prefix_len,
1710 ));
1711 let results = make_ipnet_vec![$($x),*];
1712 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1713 }
1714 );
1715 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1716 make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1717 );
1718 }
1719
1720 make_ipv4_subnets_test!(
1721 test_ipv4_subnets_zero_zero,
1722 "0.0.0.0", "0.0.0.0", 0,
1723 "0.0.0.0/32",
1724 );
1725
1726 make_ipv4_subnets_test!(
1727 test_ipv4_subnets_zero_max,
1728 "0.0.0.0", "255.255.255.255", 0,
1729 "0.0.0.0/0",
1730 );
1731
1732 make_ipv4_subnets_test!(
1733 test_ipv4_subnets_max_max,
1734 "255.255.255.255", "255.255.255.255", 0,
1735 "255.255.255.255/32",
1736 );
1737
1738 make_ipv4_subnets_test!(
1739 test_ipv4_subnets_none,
1740 "0.0.0.1", "0.0.0.0", 0,
1741 );
1742
1743 make_ipv4_subnets_test!(
1744 test_ipv4_subnets_one,
1745 "0.0.0.0", "0.0.0.1", 0,
1746 "0.0.0.0/31",
1747 );
1748
1749 make_ipv4_subnets_test!(
1750 test_ipv4_subnets_two,
1751 "0.0.0.0", "0.0.0.2", 0,
1752 "0.0.0.0/31",
1753 "0.0.0.2/32",
1754 );
1755
1756 make_ipv4_subnets_test!(
1757 test_ipv4_subnets_taper,
1758 "0.0.0.0", "0.0.0.10", 30,
1759 "0.0.0.0/30",
1760 "0.0.0.4/30",
1761 "0.0.0.8/31",
1762 "0.0.0.10/32",
1763 );
1764
1765 make_ipv6_subnets_test!(
1766 test_ipv6_subnets_zero_zero,
1767 "::", "::", 0,
1768 "::/128",
1769 );
1770
1771 make_ipv6_subnets_test!(
1772 test_ipv6_subnets_zero_max,
1773 "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1774 "::/0",
1775 );
1776
1777 make_ipv6_subnets_test!(
1778 test_ipv6_subnets_max_max,
1779 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1780 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
1781 );
1782
1783 make_ipv6_subnets_test!(
1784 test_ipv6_subnets_none,
1785 "::1", "::", 0,
1786 );
1787
1788 make_ipv6_subnets_test!(
1789 test_ipv6_subnets_one,
1790 "::", "::1", 0,
1791 "::/127",
1792 );
1793
1794 make_ipv6_subnets_test!(
1795 test_ipv6_subnets_two,
1796 "::", "::2", 0,
1797 "::/127",
1798 "::2/128",
1799 );
1800
1801 make_ipv6_subnets_test!(
1802 test_ipv6_subnets_taper,
1803 "::", "::a", 126,
1804 "::/126",
1805 "::4/126",
1806 "::8/127",
1807 "::a/128",
1808 );
1809
1810 #[test]
1811 fn test_aggregate() {
1812 let ip_nets = make_ipnet_vec![
1813 "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
1814 "10.0.2.0/24",
1815 "10.1.0.0/24", "10.1.1.0/24",
1816 "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
1817 "fd00::/32", "fd00:1::/32",
1818 "fd00:2::/32",
1819 ];
1820
1821 let ip_aggs = make_ipnet_vec![
1822 "10.0.0.0/23",
1823 "10.0.2.0/24",
1824 "10.1.0.0/23",
1825 "192.168.0.0/22",
1826 "fd00::/31",
1827 "fd00:2::/32",
1828 ];
1829
1830 let ipv4_nets: Vec<Ipv4Net> = ip_nets.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1831 let ipv4_aggs: Vec<Ipv4Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1832 let ipv6_nets: Vec<Ipv6Net> = ip_nets.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1833 let ipv6_aggs: Vec<Ipv6Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1834
1835 assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
1836 assert_eq!(Ipv4Net::aggregate(&ipv4_nets), ipv4_aggs);
1837 assert_eq!(Ipv6Net::aggregate(&ipv6_nets), ipv6_aggs);
1838 }
1839
1840 #[test]
1841 fn test_aggregate_issue44() {
1842 let nets: Vec<Ipv4Net> = vec!["128.0.0.0/1".parse().unwrap()];
1843 assert_eq!(Ipv4Net::aggregate(&nets), nets);
1844
1845 let nets: Vec<Ipv4Net> = vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()];
1846 assert_eq!(Ipv4Net::aggregate(&nets), vec!["0.0.0.0/0".parse().unwrap()]);
1847
1848 let nets: Vec<Ipv6Net> = vec!["8000::/1".parse().unwrap()];
1849 assert_eq!(Ipv6Net::aggregate(&nets), nets);
1850
1851 let nets: Vec<Ipv6Net> = vec!["::/1".parse().unwrap(), "8000::/1".parse().unwrap()];
1852 assert_eq!(Ipv6Net::aggregate(&nets), vec!["::/0".parse().unwrap()]);
1853 }
1854
1855 #[test]
1856 fn ipnet_default() {
1857 let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
1858 assert_eq!(ipnet, IpNet::default());
1859 }
1860
1861 #[test]
1862 fn ipv4net_default() {
1863 let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
1864 assert_eq!(ipnet, Ipv4Net::default());
1865 }
1866
1867 #[test]
1868 fn ipv6net_default() {
1869 let ipnet: Ipv6Net = "::/0".parse().unwrap();
1870 assert_eq!(ipnet, Ipv6Net::default());
1871 }
1872}
1873