ipnet/ipnet.rs
1use alloc::vec::Vec;
2use core::cmp::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 than 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 than 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 /// Aggregate a `Vec` of `Ipv4Net`s and return the result as a new
927 /// `Vec`.
928 ///
929 /// # Examples
930 ///
931 /// ```
932 /// # use ipnet::Ipv4Net;
933 /// #
934 /// let nets = vec![
935 /// "10.0.0.0/24".parse::<Ipv4Net>().unwrap(),
936 /// "10.0.1.0/24".parse().unwrap(),
937 /// "10.0.2.0/24".parse().unwrap(),
938 /// ];
939 ///
940 /// assert_eq!(Ipv4Net::aggregate(&nets), vec![
941 /// "10.0.0.0/23".parse::<Ipv4Net>().unwrap(),
942 /// "10.0.2.0/24".parse().unwrap(),
943 /// ]);
944 pub fn aggregate(networks: &Vec<Ipv4Net>) -> Vec<Ipv4Net> {
945 if networks.is_empty() {
946 return Vec::new();
947 }
948
949 let mut intervals: Vec<(u32, u32)> = networks.iter().map(|n| {
950 (u32::from(n.network()), u32::from(n.broadcast()))
951 }).collect();
952
953 intervals.sort_unstable();
954
955 let mut merged: Vec<(u32, u32)> = Vec::with_capacity(intervals.len());
956
957 for (start, end) in intervals {
958 if let Some((_, current_end)) = merged.last_mut() {
959 if start <= current_end.saturating_add(1) {
960 *current_end = (*current_end).max(end);
961 continue;
962 }
963 }
964
965 merged.push((start, end));
966 }
967
968 let mut res: Vec<Ipv4Net> = Vec::new();
969
970 for (start, end) in merged {
971 res.extend(Ipv4Subnets::new(start.into(), end.into(), 0));
972 }
973
974 res
975 }
976}
977
978impl Default for Ipv4Net {
979 fn default() -> Self {
980 Self {
981 addr: Ipv4Addr::from(0),
982 prefix_len: 0,
983 }
984 }
985}
986
987impl fmt::Debug for Ipv4Net {
988 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
989 fmt::Display::fmt(self, fmt)
990 }
991}
992
993impl fmt::Display for Ipv4Net {
994 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
995 write!(fmt, "{}/{}", self.addr, self.prefix_len)
996 }
997}
998
999impl From<Ipv4Addr> for Ipv4Net {
1000 fn from(addr: Ipv4Addr) -> Ipv4Net {
1001 Ipv4Net { addr, prefix_len: 32 }
1002 }
1003}
1004
1005impl Ipv6Net {
1006 /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
1007 /// length.
1008 ///
1009 /// # Examples
1010 ///
1011 /// ```
1012 /// use std::net::Ipv6Addr;
1013 /// use ipnet::{Ipv6Net, PrefixLenError};
1014 ///
1015 /// let net = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1016 /// assert!(net.is_ok());
1017 ///
1018 /// let bad_prefix_len = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1019 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1020 /// ```
1021 #[inline]
1022 pub const fn new(ip: Ipv6Addr, prefix_len: u8) -> Result<Ipv6Net, PrefixLenError> {
1023 if prefix_len > 128 {
1024 return Err(PrefixLenError);
1025 }
1026 Ok(Ipv6Net { addr: ip, prefix_len: prefix_len })
1027 }
1028
1029 /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
1030 /// length. If called from a const context it will verify prefix length
1031 /// at compile time. Otherwise it will panic at runtime if prefix length
1032 /// is not less than or equal to 128.
1033 ///
1034 /// # Examples
1035 ///
1036 /// ```
1037 /// use std::net::Ipv6Addr;
1038 /// use ipnet::{Ipv6Net};
1039 ///
1040 /// // This code is verified at compile time:
1041 /// const NET: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1042 /// assert_eq!(NET.prefix_len(), 24);
1043 ///
1044 /// // This code is verified at runtime:
1045 /// let net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1046 /// assert_eq!(net.prefix_len(), 24);
1047 ///
1048 /// // This code does not compile:
1049 /// // const BAD_PREFIX_LEN: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1050 ///
1051 /// // This code panics at runtime:
1052 /// // let bad_prefix_len = Ipv6Addr::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1053 /// ```
1054 #[inline]
1055 pub const fn new_assert(ip: Ipv6Addr, prefix_len: u8) -> Ipv6Net {
1056 assert!(prefix_len <= 128, "prefix_len must be less than or equal to 128 for Ipv6Net");
1057 Ipv6Net { addr: ip, prefix_len: prefix_len }
1058 }
1059
1060 /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask.
1061 ///
1062 /// # Examples
1063 ///
1064 /// ```
1065 /// use std::net::Ipv6Addr;
1066 /// use ipnet::{Ipv6Net, PrefixLenError};
1067 ///
1068 /// 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));
1069 /// assert!(net.is_ok());
1070 ///
1071 /// 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));
1072 /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1073 /// ```
1074 pub fn with_netmask(ip: Ipv6Addr, netmask: Ipv6Addr) -> Result<Ipv6Net, PrefixLenError> {
1075 let prefix = ipv6_mask_to_prefix(netmask)?;
1076 Self::new(ip, prefix)
1077 }
1078
1079 /// Returns a copy of the network with the address truncated to the
1080 /// prefix length.
1081 ///
1082 /// # Examples
1083 ///
1084 /// ```
1085 /// # use ipnet::Ipv6Net;
1086 /// #
1087 /// assert_eq!(
1088 /// "fd00::1:2:3:4/16".parse::<Ipv6Net>().unwrap().trunc(),
1089 /// "fd00::/16".parse().unwrap()
1090 /// );
1091 /// ```
1092 pub fn trunc(&self) -> Ipv6Net {
1093 Ipv6Net::new(self.network(), self.prefix_len).unwrap()
1094 }
1095
1096 /// Returns the address.
1097 #[inline]
1098 pub const fn addr(&self) -> Ipv6Addr {
1099 self.addr
1100 }
1101
1102 /// Returns the prefix length.
1103 #[inline]
1104 pub const fn prefix_len(&self) -> u8 {
1105 self.prefix_len
1106 }
1107
1108 /// Returns the maximum valid prefix length.
1109 #[inline]
1110 pub const fn max_prefix_len(&self) -> u8 {
1111 128
1112 }
1113
1114 /// Returns the network mask.
1115 ///
1116 /// # Examples
1117 ///
1118 /// ```
1119 /// # use std::net::Ipv6Addr;
1120 /// # use ipnet::Ipv6Net;
1121 /// #
1122 /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1123 /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
1124 /// ```
1125 pub fn netmask(&self) -> Ipv6Addr {
1126 self.netmask_u128().into()
1127 }
1128
1129 fn netmask_u128(&self) -> u128 {
1130 u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value())
1131 }
1132
1133 /// Returns the host mask.
1134 ///
1135 /// # Examples
1136 ///
1137 /// ```
1138 /// # use std::net::Ipv6Addr;
1139 /// # use ipnet::Ipv6Net;
1140 /// #
1141 /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1142 /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1143 /// ```
1144 pub fn hostmask(&self) -> Ipv6Addr {
1145 self.hostmask_u128().into()
1146 }
1147
1148 fn hostmask_u128(&self) -> u128 {
1149 u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value())
1150 }
1151
1152 /// Returns the network address.
1153 ///
1154 /// # Examples
1155 ///
1156 /// ```
1157 /// # use std::net::Ipv6Addr;
1158 /// # use ipnet::Ipv6Net;
1159 /// #
1160 /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1161 /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
1162 /// ```
1163 pub fn network(&self) -> Ipv6Addr {
1164 (u128::from(self.addr) & self.netmask_u128()).into()
1165 }
1166
1167 /// Returns the last address.
1168 ///
1169 /// Technically there is no such thing as a broadcast address for
1170 /// IPv6. The name is used for consistency with colloquial usage.
1171 ///
1172 /// # Examples
1173 ///
1174 /// ```
1175 /// # use std::net::Ipv6Addr;
1176 /// # use ipnet::Ipv6Net;
1177 /// #
1178 /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1179 /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1180 /// ```
1181 pub fn broadcast(&self) -> Ipv6Addr {
1182 (u128::from(self.addr) | self.hostmask_u128()).into()
1183 }
1184
1185 /// Returns the `Ipv6Net` that contains this one.
1186 ///
1187 /// # Examples
1188 ///
1189 /// ```
1190 /// # use std::str::FromStr;
1191 /// # use ipnet::Ipv6Net;
1192 /// #
1193 /// let n1: Ipv6Net = "fd00:ff00::/24".parse().unwrap();
1194 /// let n2: Ipv6Net = "fd00:fe00::/23".parse().unwrap();
1195 /// let n3: Ipv6Net = "fd00:fe00::/0".parse().unwrap();
1196 ///
1197 /// assert_eq!(n1.supernet().unwrap(), n2);
1198 /// assert_eq!(n3.supernet(), None);
1199 /// ```
1200 pub fn supernet(&self) -> Option<Ipv6Net> {
1201 Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
1202 }
1203
1204 /// Returns `true` if this network and the given network are
1205 /// children of the same supernet.
1206 ///
1207 /// # Examples
1208 ///
1209 /// ```
1210 /// # use ipnet::Ipv6Net;
1211 /// #
1212 /// let n1: Ipv6Net = "fd00::/18".parse().unwrap();
1213 /// let n2: Ipv6Net = "fd00:4000::/18".parse().unwrap();
1214 /// let n3: Ipv6Net = "fd00:8000::/18".parse().unwrap();
1215 ///
1216 /// assert!(n1.is_sibling(&n2));
1217 /// assert!(!n2.is_sibling(&n3));
1218 /// ```
1219 pub fn is_sibling(&self, other: &Ipv6Net) -> bool {
1220 self.prefix_len > 0 &&
1221 self.prefix_len == other.prefix_len &&
1222 self.supernet().unwrap().contains(other)
1223 }
1224
1225 /// Return an `Iterator` over the host addresses in this network.
1226 ///
1227 /// # Examples
1228 ///
1229 /// ```
1230 /// # use std::net::Ipv6Addr;
1231 /// # use ipnet::Ipv6Net;
1232 /// #
1233 /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1234 /// assert_eq!(net.hosts().collect::<Vec<Ipv6Addr>>(), vec![
1235 /// "fd00::".parse::<Ipv6Addr>().unwrap(),
1236 /// "fd00::1".parse().unwrap(),
1237 /// "fd00::2".parse().unwrap(),
1238 /// "fd00::3".parse().unwrap(),
1239 /// ]);
1240 /// ```
1241 pub fn hosts(&self) -> Ipv6AddrRange {
1242 Ipv6AddrRange::new(self.network(), self.broadcast())
1243 }
1244
1245 /// Returns an `Iterator` over the subnets of this network with the
1246 /// given prefix length.
1247 ///
1248 /// # Examples
1249 ///
1250 /// ```
1251 /// # use ipnet::{Ipv6Net, PrefixLenError};
1252 /// #
1253 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1254 /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1255 /// "fd00::/18".parse::<Ipv6Net>().unwrap(),
1256 /// "fd00:4000::/18".parse().unwrap(),
1257 /// "fd00:8000::/18".parse().unwrap(),
1258 /// "fd00:c000::/18".parse().unwrap(),
1259 /// ]);
1260 ///
1261 /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1262 /// assert_eq!(net.subnets(128).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1263 /// "fd00::/128".parse::<Ipv6Net>().unwrap(),
1264 /// "fd00::1/128".parse().unwrap(),
1265 /// "fd00::2/128".parse().unwrap(),
1266 /// "fd00::3/128".parse().unwrap(),
1267 /// ]);
1268 ///
1269 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1270 /// assert_eq!(net.subnets(15), Err(PrefixLenError));
1271 ///
1272 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1273 /// assert_eq!(net.subnets(129), Err(PrefixLenError));
1274 /// ```
1275 pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv6Subnets, PrefixLenError> {
1276 if self.prefix_len > new_prefix_len || new_prefix_len > 128 {
1277 return Err(PrefixLenError);
1278 }
1279
1280 Ok(Ipv6Subnets::new(
1281 self.network(),
1282 self.broadcast(),
1283 new_prefix_len,
1284 ))
1285 }
1286
1287 /// Test if a network address contains either another network
1288 /// address or an IP address.
1289 ///
1290 /// # Examples
1291 ///
1292 /// ```
1293 /// # use std::net::Ipv6Addr;
1294 /// # use ipnet::Ipv6Net;
1295 /// #
1296 /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1297 /// let net_yes: Ipv6Net = "fd00::/17".parse().unwrap();
1298 /// let net_no: Ipv6Net = "fd00::/15".parse().unwrap();
1299 /// let ip_yes: Ipv6Addr = "fd00::1".parse().unwrap();
1300 /// let ip_no: Ipv6Addr = "fd01::".parse().unwrap();
1301 ///
1302 /// assert!(net.contains(&net));
1303 /// assert!(net.contains(&net_yes));
1304 /// assert!(!net.contains(&net_no));
1305 /// assert!(net.contains(&ip_yes));
1306 /// assert!(!net.contains(&ip_no));
1307 /// ```
1308 pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
1309 Contains::contains(self, other)
1310 }
1311
1312 /// Aggregate a `Vec` of `Ipv6Net`s and return the result as a new
1313 /// `Vec`.
1314 ///
1315 /// # Examples
1316 ///
1317 /// ```
1318 /// # use ipnet::Ipv6Net;
1319 /// #
1320 /// let nets = vec![
1321 /// "fd00::/18".parse::<Ipv6Net>().unwrap(),
1322 /// "fd00:4000::/18".parse().unwrap(),
1323 /// "fd00:8000::/18".parse().unwrap(),
1324 /// ];
1325 /// assert_eq!(Ipv6Net::aggregate(&nets), vec![
1326 /// "fd00::/17".parse::<Ipv6Net>().unwrap(),
1327 /// "fd00:8000::/18".parse().unwrap(),
1328 /// ]);
1329 /// ```
1330 pub fn aggregate(networks: &Vec<Ipv6Net>) -> Vec<Ipv6Net> {
1331 if networks.is_empty() {
1332 return Vec::new();
1333 }
1334
1335 let mut intervals: Vec<(u128, u128)> = networks.iter().map(|n| {
1336 (u128::from(n.network()), u128::from(n.broadcast()))
1337 }).collect();
1338
1339 intervals.sort_unstable();
1340
1341 let mut merged: Vec<(u128, u128)> = Vec::with_capacity(intervals.len());
1342
1343 for (start, end) in intervals {
1344 if let Some((_, current_end)) = merged.last_mut() {
1345 if start <= current_end.saturating_add(1) {
1346 *current_end = (*current_end).max(end);
1347 continue;
1348 }
1349 }
1350
1351 merged.push((start, end));
1352 }
1353
1354 let mut res: Vec<Ipv6Net> = Vec::new();
1355
1356 for (start, end) in merged {
1357 res.extend(Ipv6Subnets::new(start.into(), end.into(), 0));
1358 }
1359
1360 res
1361 }
1362}
1363
1364impl Default for Ipv6Net {
1365 fn default() -> Self {
1366 Self {
1367 addr: Ipv6Addr::from(0),
1368 prefix_len: 0,
1369 }
1370 }
1371}
1372
1373impl fmt::Debug for Ipv6Net {
1374 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1375 fmt::Display::fmt(self, fmt)
1376 }
1377}
1378
1379impl fmt::Display for Ipv6Net {
1380 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1381 write!(fmt, "{}/{}", self.addr, self.prefix_len)
1382 }
1383}
1384
1385impl From<Ipv6Addr> for Ipv6Net {
1386 fn from(addr: Ipv6Addr) -> Ipv6Net {
1387 Ipv6Net { addr, prefix_len: 128 }
1388 }
1389}
1390
1391/// Provides a method to test if a network address contains either
1392/// another network address or an IP address.
1393///
1394/// # Examples
1395///
1396/// ```
1397/// # use std::net::IpAddr;
1398/// # use ipnet::IpNet;
1399/// #
1400/// let n4_1: IpNet = "10.1.1.0/24".parse().unwrap();
1401/// let n4_2: IpNet = "10.1.1.0/26".parse().unwrap();
1402/// let n4_3: IpNet = "10.1.2.0/26".parse().unwrap();
1403/// let ip4_1: IpAddr = "10.1.1.1".parse().unwrap();
1404/// let ip4_2: IpAddr = "10.1.2.1".parse().unwrap();
1405///
1406/// let n6_1: IpNet = "fd00::/16".parse().unwrap();
1407/// let n6_2: IpNet = "fd00::/17".parse().unwrap();
1408/// let n6_3: IpNet = "fd01::/17".parse().unwrap();
1409/// let ip6_1: IpAddr = "fd00::1".parse().unwrap();
1410/// let ip6_2: IpAddr = "fd01::1".parse().unwrap();
1411///
1412/// assert!(n4_1.contains(&n4_2));
1413/// assert!(!n4_1.contains(&n4_3));
1414/// assert!(n4_1.contains(&ip4_1));
1415/// assert!(!n4_1.contains(&ip4_2));
1416///
1417/// assert!(n6_1.contains(&n6_2));
1418/// assert!(!n6_1.contains(&n6_3));
1419/// assert!(n6_1.contains(&ip6_1));
1420/// assert!(!n6_1.contains(&ip6_2));
1421///
1422/// assert!(!n4_1.contains(&n6_1) && !n6_1.contains(&n4_1));
1423/// assert!(!n4_1.contains(&ip6_1) && !n6_1.contains(&ip4_1));
1424/// ```
1425pub trait Contains<T> {
1426 fn contains(&self, other: T) -> bool;
1427}
1428
1429impl<'a> Contains<&'a IpNet> for IpNet {
1430 fn contains(&self, other: &IpNet) -> bool {
1431 match (*self, *other) {
1432 (IpNet::V4(ref a), IpNet::V4(ref b)) => a.contains(b),
1433 (IpNet::V6(ref a), IpNet::V6(ref b)) => a.contains(b),
1434 _ => false,
1435 }
1436 }
1437}
1438
1439impl<'a> Contains<&'a IpAddr> for IpNet {
1440 fn contains(&self, other: &IpAddr) -> bool {
1441 match (*self, *other) {
1442 (IpNet::V4(ref a), IpAddr::V4(ref b)) => a.contains(b),
1443 (IpNet::V6(ref a), IpAddr::V6(ref b)) => a.contains(b),
1444 _ => false,
1445 }
1446 }
1447}
1448
1449impl<'a> Contains<&'a Ipv4Net> for Ipv4Net {
1450 fn contains(&self, other: &'a Ipv4Net) -> bool {
1451 self.network() <= other.network() && other.broadcast() <= self.broadcast()
1452 }
1453}
1454
1455impl<'a> Contains<&'a Ipv4Addr> for Ipv4Net {
1456 fn contains(&self, other: &'a Ipv4Addr) -> bool {
1457 self.network() <= *other && *other <= self.broadcast()
1458 }
1459}
1460
1461impl<'a> Contains<&'a Ipv6Net> for Ipv6Net {
1462 fn contains(&self, other: &'a Ipv6Net) -> bool {
1463 self.network() <= other.network() && other.broadcast() <= self.broadcast()
1464 }
1465}
1466
1467impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net {
1468 fn contains(&self, other: &'a Ipv6Addr) -> bool {
1469 self.network() <= *other && *other <= self.broadcast()
1470 }
1471}
1472
1473/// An `Iterator` that generates IP network addresses, either IPv4 or
1474/// IPv6.
1475///
1476/// Generates the subnets between the provided `start` and `end` IP
1477/// addresses inclusive of `end`. Each iteration generates the next
1478/// network address of the largest valid size it can, while using a
1479/// prefix length not less than `min_prefix_len`.
1480///
1481/// # Examples
1482///
1483/// ```
1484/// # use std::net::{Ipv4Addr, Ipv6Addr};
1485/// # use std::str::FromStr;
1486/// # use ipnet::{IpNet, IpSubnets, Ipv4Subnets, Ipv6Subnets};
1487/// let subnets = IpSubnets::from(Ipv4Subnets::new(
1488/// "10.0.0.0".parse().unwrap(),
1489/// "10.0.0.239".parse().unwrap(),
1490/// 26,
1491/// ));
1492///
1493/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1494/// "10.0.0.0/26".parse().unwrap(),
1495/// "10.0.0.64/26".parse().unwrap(),
1496/// "10.0.0.128/26".parse().unwrap(),
1497/// "10.0.0.192/27".parse().unwrap(),
1498/// "10.0.0.224/28".parse().unwrap(),
1499/// ]);
1500///
1501/// let subnets = IpSubnets::from(Ipv6Subnets::new(
1502/// "fd00::".parse().unwrap(),
1503/// "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1504/// 26,
1505/// ));
1506///
1507/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1508/// "fd00::/26".parse().unwrap(),
1509/// "fd00:40::/26".parse().unwrap(),
1510/// "fd00:80::/26".parse().unwrap(),
1511/// "fd00:c0::/27".parse().unwrap(),
1512/// "fd00:e0::/28".parse().unwrap(),
1513/// ]);
1514/// ```
1515#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1516pub enum IpSubnets {
1517 V4(Ipv4Subnets),
1518 V6(Ipv6Subnets),
1519}
1520
1521/// An `Iterator` that generates IPv4 network addresses.
1522///
1523/// Generates the subnets between the provided `start` and `end` IP
1524/// addresses inclusive of `end`. Each iteration generates the next
1525/// network address of the largest valid size it can, while using a
1526/// prefix length not less than `min_prefix_len`.
1527///
1528/// # Examples
1529///
1530/// ```
1531/// # use std::net::Ipv4Addr;
1532/// # use std::str::FromStr;
1533/// # use ipnet::{Ipv4Net, Ipv4Subnets};
1534/// let subnets = Ipv4Subnets::new(
1535/// "10.0.0.0".parse().unwrap(),
1536/// "10.0.0.239".parse().unwrap(),
1537/// 26,
1538/// );
1539///
1540/// assert_eq!(subnets.collect::<Vec<Ipv4Net>>(), vec![
1541/// "10.0.0.0/26".parse().unwrap(),
1542/// "10.0.0.64/26".parse().unwrap(),
1543/// "10.0.0.128/26".parse().unwrap(),
1544/// "10.0.0.192/27".parse().unwrap(),
1545/// "10.0.0.224/28".parse().unwrap(),
1546/// ]);
1547/// ```
1548#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1549pub struct Ipv4Subnets {
1550 start: Ipv4Addr,
1551 end: Ipv4Addr, // end is inclusive
1552 min_prefix_len: u8,
1553}
1554
1555/// An `Iterator` that generates IPv6 network addresses.
1556///
1557/// Generates the subnets between the provided `start` and `end` IP
1558/// addresses inclusive of `end`. Each iteration generates the next
1559/// network address of the largest valid size it can, while using a
1560/// prefix length not less than `min_prefix_len`.
1561///
1562/// # Examples
1563///
1564/// ```
1565/// # use std::net::Ipv6Addr;
1566/// # use std::str::FromStr;
1567/// # use ipnet::{Ipv6Net, Ipv6Subnets};
1568/// let subnets = Ipv6Subnets::new(
1569/// "fd00::".parse().unwrap(),
1570/// "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1571/// 26,
1572/// );
1573///
1574/// assert_eq!(subnets.collect::<Vec<Ipv6Net>>(), vec![
1575/// "fd00::/26".parse().unwrap(),
1576/// "fd00:40::/26".parse().unwrap(),
1577/// "fd00:80::/26".parse().unwrap(),
1578/// "fd00:c0::/27".parse().unwrap(),
1579/// "fd00:e0::/28".parse().unwrap(),
1580/// ]);
1581/// ```
1582#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1583pub struct Ipv6Subnets {
1584 start: Ipv6Addr,
1585 end: Ipv6Addr, // end is inclusive
1586 min_prefix_len: u8,
1587}
1588
1589impl Ipv4Subnets {
1590 pub fn new(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Self {
1591 Ipv4Subnets {
1592 start: start,
1593 end: end,
1594 min_prefix_len: min_prefix_len,
1595 }
1596 }
1597}
1598
1599impl Ipv6Subnets {
1600 pub fn new(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Self {
1601 Ipv6Subnets {
1602 start: start,
1603 end: end,
1604 min_prefix_len: min_prefix_len,
1605 }
1606 }
1607}
1608
1609impl From<Ipv4Subnets> for IpSubnets {
1610 fn from(i: Ipv4Subnets) -> IpSubnets {
1611 IpSubnets::V4(i)
1612 }
1613}
1614
1615impl From<Ipv6Subnets> for IpSubnets {
1616 fn from(i: Ipv6Subnets) -> IpSubnets {
1617 IpSubnets::V6(i)
1618 }
1619}
1620
1621impl Iterator for IpSubnets {
1622 type Item = IpNet;
1623
1624 fn next(&mut self) -> Option<Self::Item> {
1625 match *self {
1626 IpSubnets::V4(ref mut a) => a.next().map(IpNet::V4),
1627 IpSubnets::V6(ref mut a) => a.next().map(IpNet::V6),
1628 }
1629 }
1630}
1631
1632fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
1633 let range = u32::from(end) - u32::from(start);
1634 let range_lz = range.leading_zeros();
1635 let range_pl = if range_lz + range.trailing_ones() == u32::BITS { range_lz } else { range_lz + 1 };
1636 let start_pl = 32 - u32::from(start).trailing_zeros();
1637 let new_prefix_len = max(max(range_pl as u8, start_pl as u8), min_prefix_len);
1638 Ipv4Net::new(start, new_prefix_len).unwrap()
1639}
1640
1641fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
1642 let range = u128::from(end) - u128::from(start);
1643 let range_lz = range.leading_zeros();
1644 let range_pl = if range_lz + range.trailing_ones() == u128::BITS { range_lz } else { range_lz + 1 };
1645 let start_pl = 128 - u128::from(start).trailing_zeros();
1646 let new_prefix_len = max(max(range_pl as u8, start_pl as u8), min_prefix_len);
1647 Ipv6Net::new(start, new_prefix_len).unwrap()
1648}
1649
1650impl Iterator for Ipv4Subnets {
1651 type Item = Ipv4Net;
1652
1653 fn next(&mut self) -> Option<Self::Item> {
1654 match self.start.partial_cmp(&self.end) {
1655 Some(Less) => {
1656 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1657 self.start = next.broadcast().saturating_add(1);
1658
1659 // Stop the iterator if we saturated self.start.
1660 if self.start == next.broadcast() {
1661 self.end.replace_zero();
1662 }
1663 Some(next)
1664 },
1665 Some(Equal) => {
1666 let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1667 self.start = next.broadcast().saturating_add(1);
1668 self.end.replace_zero();
1669 Some(next)
1670 },
1671 _ => None,
1672 }
1673 }
1674}
1675
1676impl Iterator for Ipv6Subnets {
1677 type Item = Ipv6Net;
1678
1679 fn next(&mut self) -> Option<Self::Item> {
1680 match self.start.partial_cmp(&self.end) {
1681 Some(Less) => {
1682 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1683 self.start = next.broadcast().saturating_add(1);
1684
1685 // Stop the iterator if we saturated self.start.
1686 if self.start == next.broadcast() {
1687 self.end.replace_zero();
1688 }
1689 Some(next)
1690 },
1691 Some(Equal) => {
1692 let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1693 self.start = next.broadcast().saturating_add(1);
1694 self.end.replace_zero();
1695 Some(next)
1696 },
1697 _ => None,
1698 }
1699 }
1700}
1701
1702impl FusedIterator for IpSubnets {}
1703impl FusedIterator for Ipv4Subnets {}
1704impl FusedIterator for Ipv6Subnets {}
1705
1706#[cfg(test)]
1707mod tests {
1708 use super::*;
1709
1710 macro_rules! make_ipnet_vec {
1711 ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
1712 ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
1713 }
1714
1715 #[test]
1716 fn test_make_ipnet_vec() {
1717 assert_eq!(
1718 make_ipnet_vec![
1719 "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
1720 "fd00::1/128", "fd00::2/127", "fd00::3/126",
1721 ],
1722 vec![
1723 "10.1.1.1/32".parse().unwrap(),
1724 "10.2.2.2/24".parse().unwrap(),
1725 "10.3.3.3/16".parse().unwrap(),
1726 "fd00::1/128".parse().unwrap(),
1727 "fd00::2/127".parse().unwrap(),
1728 "fd00::3/126".parse().unwrap(),
1729 ]
1730 );
1731 }
1732
1733 macro_rules! make_ipv4_subnets_test {
1734 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1735 #[test]
1736 fn $name() {
1737 let subnets = IpSubnets::from(Ipv4Subnets::new(
1738 $start.parse().unwrap(),
1739 $end.parse().unwrap(),
1740 $min_prefix_len,
1741 ));
1742 let results = make_ipnet_vec![$($x),*];
1743 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1744 }
1745 );
1746 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1747 make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1748 );
1749 }
1750
1751 macro_rules! make_ipv6_subnets_test {
1752 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1753 #[test]
1754 fn $name() {
1755 let subnets = IpSubnets::from(Ipv6Subnets::new(
1756 $start.parse().unwrap(),
1757 $end.parse().unwrap(),
1758 $min_prefix_len,
1759 ));
1760 let results = make_ipnet_vec![$($x),*];
1761 assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1762 }
1763 );
1764 ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1765 make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1766 );
1767 }
1768
1769 make_ipv4_subnets_test!(
1770 test_ipv4_subnets_zero_zero,
1771 "0.0.0.0", "0.0.0.0", 0,
1772 "0.0.0.0/32",
1773 );
1774
1775 make_ipv4_subnets_test!(
1776 test_ipv4_subnets_zero_max,
1777 "0.0.0.0", "255.255.255.255", 0,
1778 "0.0.0.0/0",
1779 );
1780
1781 make_ipv4_subnets_test!(
1782 test_ipv4_subnets_max_max,
1783 "255.255.255.255", "255.255.255.255", 0,
1784 "255.255.255.255/32",
1785 );
1786
1787 make_ipv4_subnets_test!(
1788 test_ipv4_subnets_none,
1789 "0.0.0.1", "0.0.0.0", 0,
1790 );
1791
1792 make_ipv4_subnets_test!(
1793 test_ipv4_subnets_one,
1794 "0.0.0.0", "0.0.0.1", 0,
1795 "0.0.0.0/31",
1796 );
1797
1798 make_ipv4_subnets_test!(
1799 test_ipv4_subnets_two,
1800 "0.0.0.0", "0.0.0.2", 0,
1801 "0.0.0.0/31",
1802 "0.0.0.2/32",
1803 );
1804
1805 make_ipv4_subnets_test!(
1806 test_ipv4_subnets_taper,
1807 "0.0.0.0", "0.0.0.10", 30,
1808 "0.0.0.0/30",
1809 "0.0.0.4/30",
1810 "0.0.0.8/31",
1811 "0.0.0.10/32",
1812 );
1813
1814 make_ipv6_subnets_test!(
1815 test_ipv6_subnets_zero_zero,
1816 "::", "::", 0,
1817 "::/128",
1818 );
1819
1820 make_ipv6_subnets_test!(
1821 test_ipv6_subnets_zero_max,
1822 "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1823 "::/0",
1824 );
1825
1826 make_ipv6_subnets_test!(
1827 test_ipv6_subnets_max_max,
1828 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1829 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
1830 );
1831
1832 make_ipv6_subnets_test!(
1833 test_ipv6_subnets_none,
1834 "::1", "::", 0,
1835 );
1836
1837 make_ipv6_subnets_test!(
1838 test_ipv6_subnets_one,
1839 "::", "::1", 0,
1840 "::/127",
1841 );
1842
1843 make_ipv6_subnets_test!(
1844 test_ipv6_subnets_two,
1845 "::", "::2", 0,
1846 "::/127",
1847 "::2/128",
1848 );
1849
1850 make_ipv6_subnets_test!(
1851 test_ipv6_subnets_taper,
1852 "::", "::a", 126,
1853 "::/126",
1854 "::4/126",
1855 "::8/127",
1856 "::a/128",
1857 );
1858
1859 // Issue #70
1860 #[test]
1861 fn test_ipv4_subnets_zero_max_minus_one() {
1862 let subnets: Vec<Ipv4Net> = Ipv4Subnets::new(Ipv4Addr::from(0u32), Ipv4Addr::from(u32::MAX-1), 0).collect();
1863 assert!(!subnets[0].contains(&Ipv4Addr::from(u32::MAX)));
1864 }
1865
1866 // Issue #70
1867 #[test]
1868 fn test_ipv6_subnets_zero_max_minus_one() {
1869 let subnets: Vec<Ipv6Net> = Ipv6Subnets::new(Ipv6Addr::from(0u128), Ipv6Addr::from(u128::MAX-1), 0).collect();
1870 assert!(!subnets[0].contains(&Ipv6Addr::from(u128::MAX)));
1871 }
1872
1873 #[test]
1874 fn ipnet_aggregate() {
1875 let ip_nets = make_ipnet_vec![
1876 "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
1877 "10.0.2.0/24",
1878 "10.1.0.0/24", "10.1.1.0/24",
1879 "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
1880 "fd00::/32", "fd00:1::/32",
1881 "fd00:2::/32",
1882 ];
1883
1884 let ip_aggs = make_ipnet_vec![
1885 "10.0.0.0/23",
1886 "10.0.2.0/24",
1887 "10.1.0.0/23",
1888 "192.168.0.0/22",
1889 "fd00::/31",
1890 "fd00:2::/32",
1891 ];
1892
1893 assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
1894
1895 // Issue #44
1896 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["128.0.0.0/1"]), make_ipnet_vec!["128.0.0.0/1"]);
1897 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["0.0.0.0/1", "128.0.0.0/1"]), make_ipnet_vec!["0.0.0.0/0"]);
1898 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["8000::/1"]), make_ipnet_vec!["8000::/1"]);
1899 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["::/1", "8000::/1"]), make_ipnet_vec!["::/0"]);
1900
1901 // Issue #71
1902 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["255.255.255.254/32"]), make_ipnet_vec!["255.255.255.254/32"]);
1903 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["255.255.255.255/32"]), make_ipnet_vec!["255.255.255.255/32"]);
1904 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["255.255.255.252/31", "255.255.255.254/32"]), make_ipnet_vec!["255.255.255.252/31", "255.255.255.254/32"]);
1905 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]), make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]);
1906 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"]), make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"]);
1907 assert_eq!(IpNet::aggregate(&make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc/127", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]), make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc/127", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]);
1908 }
1909
1910 #[test]
1911 fn ipnet_default() {
1912 let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
1913 assert_eq!(ipnet, IpNet::default());
1914 }
1915
1916 #[test]
1917 fn ipv4net_default() {
1918 let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
1919 assert_eq!(ipnet, Ipv4Net::default());
1920 }
1921
1922 #[test]
1923 fn ipv6net_default() {
1924 let ipnet: Ipv6Net = "::/0".parse().unwrap();
1925 assert_eq!(ipnet, Ipv6Net::default());
1926 }
1927
1928 #[test]
1929 fn new_assert() {
1930 const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1931 const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1932 const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1933 const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1934
1935 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1936 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1937 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1938 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1939 }
1940
1941 #[test]
1942 #[should_panic]
1943 fn ipv4net_new_assert_panics() {
1944 let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 33);
1945 }
1946
1947 #[test]
1948 #[should_panic]
1949 fn ipv6net_new_assert_panics() {
1950 let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 129);
1951 }
1952}