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