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