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