Coverage Report

Created: 2026-07-25 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ipnet-2.12.0/src/ipnet.rs
Line
Count
Source
1
use alloc::vec::Vec;
2
use core::cmp::{min, max};
3
use core::cmp::Ordering::{Less, Equal};
4
use core::convert::From;
5
use core::fmt;
6
use core::iter::FusedIterator;
7
use core::option::Option::{Some, None};
8
#[cfg(not(feature = "std"))]
9
use core::error::Error;
10
#[cfg(feature = "std")]
11
use std::error::Error;
12
#[cfg(not(feature = "std"))]
13
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
14
#[cfg(feature = "std")]
15
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
16
17
use crate::ipext::{IpAdd, IpSub, IpStep, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
18
use 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)]
51
pub 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)]
84
pub 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)]
114
pub 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)]
123
pub struct PrefixLenError;
124
125
impl fmt::Display for PrefixLenError {
126
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
127
0
        fmt.write_str("invalid IP prefix length")
128
0
    }
129
}
130
131
impl Error for PrefixLenError {}
132
133
impl 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
0
    pub fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError> {
150
0
        Ok(match ip {
151
0
            IpAddr::V4(a) => Ipv4Net::new(a, prefix_len)?.into(),
152
0
            IpAddr::V6(a) => Ipv6Net::new(a, prefix_len)?.into(),
153
        })
154
0
    }
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
0
    pub const fn new_assert(ip: IpAddr, prefix_len: u8) -> IpNet {
182
0
        match ip {
183
0
            IpAddr::V4(a) => IpNet::V4(Ipv4Net::new_assert(a, prefix_len)),
184
0
            IpAddr::V6(a) => IpNet::V6(Ipv6Net::new_assert(a, prefix_len)),
185
        }
186
0
    }
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
0
    pub fn with_netmask(ip: IpAddr, netmask: IpAddr) -> Result<IpNet, PrefixLenError> {
203
0
        let prefix = ip_mask_to_prefix(netmask)?;
204
0
        Self::new(ip, prefix)
205
0
    }
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
0
    pub fn trunc(&self) -> IpNet {
226
0
        match *self {
227
0
            IpNet::V4(ref a) => IpNet::V4(a.trunc()),
228
0
            IpNet::V6(ref a) => IpNet::V6(a.trunc()),
229
        }
230
0
    }
231
232
    /// Returns the address.
233
0
    pub fn addr(&self) -> IpAddr {
234
0
        match *self {
235
0
            IpNet::V4(ref a) => IpAddr::V4(a.addr),
236
0
            IpNet::V6(ref a) => IpAddr::V6(a.addr),
237
        }
238
0
    }
239
240
    /// Returns the prefix length.
241
0
    pub fn prefix_len(&self) -> u8 {
242
0
        match *self {
243
0
            IpNet::V4(ref a) => a.prefix_len(),
244
0
            IpNet::V6(ref a) => a.prefix_len(),
245
        }
246
0
    }
247
248
    /// Returns the maximum valid prefix length.
249
0
    pub fn max_prefix_len(&self) -> u8 {
250
0
        match *self {
251
0
            IpNet::V4(ref a) => a.max_prefix_len(),
252
0
            IpNet::V6(ref a) => a.max_prefix_len(),
253
        }
254
0
    }
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
0
    pub fn netmask(&self) -> IpAddr {
271
0
        match *self {
272
0
            IpNet::V4(ref a) => IpAddr::V4(a.netmask()),
273
0
            IpNet::V6(ref a) => IpAddr::V6(a.netmask()),
274
        }
275
0
    }
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
0
    pub fn hostmask(&self) -> IpAddr {
292
0
        match *self {
293
0
            IpNet::V4(ref a) => IpAddr::V4(a.hostmask()),
294
0
            IpNet::V6(ref a) => IpAddr::V6(a.hostmask()),
295
        }
296
0
    }
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
0
    pub fn network(&self) -> IpAddr {
313
0
        match *self {
314
0
            IpNet::V4(ref a) => IpAddr::V4(a.network()),
315
0
            IpNet::V6(ref a) => IpAddr::V6(a.network()),
316
        }
317
0
    }    
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
0
    pub fn broadcast(&self) -> IpAddr {
334
0
        match *self {
335
0
            IpNet::V4(ref a) => IpAddr::V4(a.broadcast()),
336
0
            IpNet::V6(ref a) => IpAddr::V6(a.broadcast()),
337
        }
338
0
    }
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
0
    pub fn supernet(&self) -> Option<IpNet> {
362
0
        match *self {
363
0
            IpNet::V4(ref a) => a.supernet().map(IpNet::V4),
364
0
            IpNet::V6(ref a) => a.supernet().map(IpNet::V6),
365
        }
366
0
    }
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
0
    pub fn is_sibling(&self, other: &IpNet) -> bool {
390
0
        match (*self, *other) {
391
0
            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.is_sibling(b),
392
0
            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.is_sibling(b),
393
0
            _ => false,
394
        }
395
0
    }
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
0
    pub fn hosts(&self) -> IpAddrRange {
426
0
        match *self {
427
0
            IpNet::V4(ref a) => IpAddrRange::V4(a.hosts()),
428
0
            IpNet::V6(ref a) => IpAddrRange::V6(a.hosts()),
429
        }
430
0
    }
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
0
    pub fn subnets(&self, new_prefix_len: u8) -> Result<IpSubnets, PrefixLenError> {
469
0
        match *self {
470
0
            IpNet::V4(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V4),
471
0
            IpNet::V6(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V6),
472
        }
473
0
    }
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
0
    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
515
0
        Contains::contains(self, other)
516
0
    }
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
0
    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
0
        let mut ipv4nets: Vec<Ipv4Net> = Vec::new();
547
0
        let mut ipv6nets: Vec<Ipv6Net> = Vec::new();
548
549
0
        for n in networks {
550
0
            match *n {
551
0
                IpNet::V4(x) => ipv4nets.push(x),
552
0
                IpNet::V6(x) => ipv6nets.push(x),
553
            }
554
        }
555
556
0
        let mut res: Vec<IpNet> = Vec::new();
557
0
        let ipv4aggs = Ipv4Net::aggregate(&ipv4nets);
558
0
        let ipv6aggs = Ipv6Net::aggregate(&ipv6nets);
559
0
        res.extend::<Vec<IpNet>>(ipv4aggs.into_iter().map(IpNet::V4).collect::<Vec<IpNet>>());
560
0
        res.extend::<Vec<IpNet>>(ipv6aggs.into_iter().map(IpNet::V6).collect::<Vec<IpNet>>());
561
0
        res
562
0
    }
563
}
564
565
impl Default for IpNet {
566
0
    fn default() -> Self {
567
0
        Self::V4(Ipv4Net::default())
568
0
    }
569
}
570
571
impl fmt::Debug for IpNet {
572
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
573
0
        fmt::Display::fmt(self, fmt)
574
0
    }
575
}
576
577
impl fmt::Display for IpNet {
578
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
579
0
        match *self {
580
0
            IpNet::V4(ref a) => a.fmt(fmt),
581
0
            IpNet::V6(ref a) => a.fmt(fmt),
582
        }
583
0
    }
584
}
585
586
impl From<Ipv4Net> for IpNet {
587
0
    fn from(net: Ipv4Net) -> IpNet {
588
0
        IpNet::V4(net)
589
0
    }
590
}
591
592
impl From<Ipv6Net> for IpNet {
593
0
    fn from(net: Ipv6Net) -> IpNet {
594
0
        IpNet::V6(net)
595
0
    }
596
}
597
598
impl From<IpAddr> for IpNet {
599
0
    fn from(addr: IpAddr) -> IpNet {
600
0
        match addr {
601
0
            IpAddr::V4(a) => IpNet::V4(a.into()),
602
0
            IpAddr::V6(a) => IpNet::V6(a.into()),
603
        }
604
0
    }
605
}
606
607
impl 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
0
    pub const fn new(ip: Ipv4Addr, prefix_len: u8) -> Result<Ipv4Net, PrefixLenError> {
625
0
        if prefix_len > 32 {
626
0
            return Err(PrefixLenError);
627
0
        }
628
0
        Ok(Ipv4Net { addr: ip, prefix_len: prefix_len })
629
0
    }
Unexecuted instantiation: <ipnet::ipnet::Ipv4Net>::new
Unexecuted instantiation: <ipnet::ipnet::Ipv4Net>::new
630
631
    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
632
    /// length. If called from a const context it will verify prefix length
633
    /// at compile time. Otherwise it will panic at runtime if prefix length
634
    /// is not less then or equal to 32.
635
    ///
636
    /// # Examples
637
    ///
638
    /// ```
639
    /// use std::net::Ipv4Addr;
640
    /// use ipnet::{Ipv4Net};
641
    ///
642
    /// // This code is verified at compile time:
643
    /// const NET: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
644
    /// assert_eq!(NET.prefix_len(), 24);
645
    ///
646
    /// // This code is verified at runtime:
647
    /// let net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
648
    /// assert_eq!(NET.prefix_len(), 24);
649
    ///
650
    /// // This code does not compile:
651
    /// // const BAD_PREFIX_LEN: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
652
    ///
653
    /// // This code panics at runtime:
654
    /// // let bad_prefix_len = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
655
    /// ```
656
    #[inline]
657
0
    pub const fn new_assert(ip: Ipv4Addr, prefix_len: u8) -> Ipv4Net {
658
0
        assert!(prefix_len <= 32, "PREFIX_LEN must be less then or equal to 32 for Ipv4Net");
659
0
        Ipv4Net { addr: ip, prefix_len: prefix_len }
660
0
    }
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
0
    pub fn with_netmask(ip: Ipv4Addr, netmask: Ipv4Addr) -> Result<Ipv4Net, PrefixLenError> {
677
0
        let prefix = ipv4_mask_to_prefix(netmask)?;
678
0
        Self::new(ip, prefix)
679
0
    }
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
0
    pub fn trunc(&self) -> Ipv4Net {
695
0
        Ipv4Net::new(self.network(), self.prefix_len).unwrap()
696
0
    }
697
698
    /// Returns the address.
699
    #[inline]
700
0
    pub const fn addr(&self) -> Ipv4Addr {
701
0
        self.addr
702
0
    }
703
704
    /// Returns the prefix length.
705
    #[inline]
706
0
    pub const fn prefix_len(&self) -> u8 {
707
0
        self.prefix_len
708
0
    }
709
710
    /// Returns the maximum valid prefix length.
711
    #[inline]
712
0
    pub const fn max_prefix_len(&self) -> u8 {
713
0
        32
714
0
    }
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
0
    pub fn netmask(&self) -> Ipv4Addr {
728
0
        Ipv4Addr::from(self.netmask_u32())
729
0
    }
730
731
0
    fn netmask_u32(&self) -> u32 {
732
0
        u32::max_value().checked_shl(32 - self.prefix_len as u32).unwrap_or(0)
733
0
    }
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
0
    pub fn hostmask(&self) -> Ipv4Addr {
747
0
        Ipv4Addr::from(self.hostmask_u32())
748
0
    }
749
750
0
    fn hostmask_u32(&self) -> u32 {
751
0
        u32::max_value().checked_shr(self.prefix_len as u32).unwrap_or(0)
752
0
    }
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
0
    pub fn network(&self) -> Ipv4Addr {
766
0
        Ipv4Addr::from(u32::from(self.addr) & self.netmask_u32())
767
0
    }
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
0
    pub fn broadcast(&self) -> Ipv4Addr {
781
0
        Ipv4Addr::from(u32::from(self.addr) | self.hostmask_u32())
782
0
    }
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
0
    pub fn supernet(&self) -> Option<Ipv4Net> {
799
0
        Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
800
0
    }
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
0
    pub fn is_sibling(&self, other: &Ipv4Net) -> bool {
818
0
        self.prefix_len > 0 &&
819
0
        self.prefix_len == other.prefix_len &&
820
0
        self.supernet().unwrap().contains(other)
821
0
    }
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
0
    pub fn hosts(&self) -> Ipv4AddrRange {
848
0
        let mut start = self.network();
849
0
        let mut end = self.broadcast();
850
        
851
0
        if self.prefix_len < 31 {
852
0
            start = start.saturating_add(1);
853
0
            end = end.saturating_sub(1);
854
0
        }
855
        
856
0
        Ipv4AddrRange::new(start, end)
857
0
    }
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
0
    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv4Subnets, PrefixLenError> {
890
0
        if self.prefix_len > new_prefix_len || new_prefix_len > 32 {
891
0
            return Err(PrefixLenError);
892
0
        }
893
        
894
0
        Ok(Ipv4Subnets::new(
895
0
            self.network(),
896
0
            self.broadcast(),
897
0
            new_prefix_len,
898
0
        ))
899
0
    }
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
0
    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
923
0
        Contains::contains(self, other)
924
0
    }
Unexecuted instantiation: <ipnet::ipnet::Ipv4Net>::contains::<&ipnet::ipnet::Ipv4Net>
Unexecuted instantiation: <ipnet::ipnet::Ipv4Net>::contains::<&core::net::ip_addr::Ipv4Addr>
925
926
    // It is significantly faster to work on u32 than Ipv4Addr.
927
0
    fn interval(&self) -> (u32, u32) {
928
0
        (
929
0
            u32::from(self.network()),
930
0
            u32::from(self.broadcast()).saturating_add(1),
931
0
        )
932
0
    }
933
934
    /// Aggregate a `Vec` of `Ipv4Net`s and return the result as a new
935
    /// `Vec`.
936
    ///
937
    /// # Examples
938
    ///
939
    /// ```
940
    /// # use ipnet::Ipv4Net;
941
    /// #
942
    /// let nets = vec![
943
    ///     "10.0.0.0/24".parse::<Ipv4Net>().unwrap(),
944
    ///     "10.0.1.0/24".parse().unwrap(),
945
    ///     "10.0.2.0/24".parse().unwrap(),
946
    /// ];
947
    ///
948
    /// assert_eq!(Ipv4Net::aggregate(&nets), vec![
949
    ///     "10.0.0.0/23".parse::<Ipv4Net>().unwrap(),
950
    ///     "10.0.2.0/24".parse().unwrap(),
951
    /// ]);
952
0
    pub fn aggregate(networks: &Vec<Ipv4Net>) -> Vec<Ipv4Net> {
953
0
        let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
954
0
        intervals = merge_intervals(intervals);
955
0
        let mut res: Vec<Ipv4Net> = Vec::new();
956
        
957
0
        for (start, mut end) in intervals {
958
0
            if end != core::u32::MAX {
959
0
                end = end.saturating_sub(1)
960
0
            }
961
0
            let iter = Ipv4Subnets::new(start.into(), end.into(), 0);
962
0
            res.extend(iter);
963
        }
964
0
        res
965
0
    }
966
}
967
968
impl Default for Ipv4Net {
969
0
    fn default() -> Self {
970
0
        Self {
971
0
            addr: Ipv4Addr::from(0),
972
0
            prefix_len: 0,
973
0
        }
974
0
    }
975
}
976
977
impl fmt::Debug for Ipv4Net {
978
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
979
0
        fmt::Display::fmt(self, fmt)
980
0
    }
981
}
982
983
impl fmt::Display for Ipv4Net {
984
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
985
0
        write!(fmt, "{}/{}", self.addr, self.prefix_len)
986
0
    }
987
}
988
989
impl From<Ipv4Addr> for Ipv4Net {
990
0
    fn from(addr: Ipv4Addr) -> Ipv4Net {
991
0
        Ipv4Net { addr, prefix_len: 32 }
992
0
    }
993
}
994
995
impl Ipv6Net {    
996
    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
997
    /// length.
998
    ///
999
    /// # Examples
1000
    ///
1001
    /// ```
1002
    /// use std::net::Ipv6Addr;
1003
    /// use ipnet::{Ipv6Net, PrefixLenError};
1004
    ///
1005
    /// let net = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1006
    /// assert!(net.is_ok());
1007
    ///
1008
    /// let bad_prefix_len = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1009
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1010
    /// ```
1011
    #[inline]
1012
0
    pub const fn new(ip: Ipv6Addr, prefix_len: u8) -> Result<Ipv6Net, PrefixLenError> {
1013
0
        if prefix_len > 128 {
1014
0
            return Err(PrefixLenError);
1015
0
        }
1016
0
        Ok(Ipv6Net { addr: ip, prefix_len: prefix_len })
1017
0
    }
Unexecuted instantiation: <ipnet::ipnet::Ipv6Net>::new
Unexecuted instantiation: <ipnet::ipnet::Ipv6Net>::new
1018
1019
    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
1020
    /// length. If called from a const context it will verify prefix length
1021
    /// at compile time. Otherwise it will panic at runtime if prefix length
1022
    /// is not less then or equal to 128.
1023
    ///
1024
    /// # Examples
1025
    ///
1026
    /// ```
1027
    /// use std::net::Ipv6Addr;
1028
    /// use ipnet::{Ipv6Net};
1029
    ///
1030
    /// // This code is verified at compile time:
1031
    /// const NET: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1032
    /// assert_eq!(NET.prefix_len(), 24);
1033
    ///
1034
    /// // This code is verified at runtime:
1035
    /// let net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1036
    /// assert_eq!(net.prefix_len(), 24);
1037
    ///
1038
    /// // This code does not compile:
1039
    /// // const BAD_PREFIX_LEN: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1040
    ///
1041
    /// // This code panics at runtime:
1042
    /// // let bad_prefix_len = Ipv6Addr::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1043
    /// ```
1044
    #[inline]
1045
0
    pub const fn new_assert(ip: Ipv6Addr, prefix_len: u8) -> Ipv6Net {
1046
0
        assert!(prefix_len <= 128, "PREFIX_LEN must be less then or equal to 128 for Ipv6Net");
1047
0
        Ipv6Net { addr: ip, prefix_len: prefix_len }
1048
0
    }
1049
1050
    /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask.
1051
    ///
1052
    /// # Examples
1053
    ///
1054
    /// ```
1055
    /// use std::net::Ipv6Addr;
1056
    /// use ipnet::{Ipv6Net, PrefixLenError};
1057
    ///
1058
    /// let net = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0000_0000_0000_0000));
1059
    /// assert!(net.is_ok());
1060
    ///
1061
    /// let bad_prefix_len = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0001_0000_0000_0000));
1062
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1063
    /// ```
1064
0
    pub fn with_netmask(ip: Ipv6Addr, netmask: Ipv6Addr) -> Result<Ipv6Net, PrefixLenError> {
1065
0
        let prefix = ipv6_mask_to_prefix(netmask)?;
1066
0
        Self::new(ip, prefix)
1067
0
    }
1068
1069
    /// Returns a copy of the network with the address truncated to the
1070
    /// prefix length.
1071
    ///
1072
    /// # Examples
1073
    ///
1074
    /// ```
1075
    /// # use ipnet::Ipv6Net;
1076
    /// #
1077
    /// assert_eq!(
1078
    ///     "fd00::1:2:3:4/16".parse::<Ipv6Net>().unwrap().trunc(),
1079
    ///     "fd00::/16".parse().unwrap()
1080
    /// );
1081
    /// ```
1082
0
    pub fn trunc(&self) -> Ipv6Net {
1083
0
        Ipv6Net::new(self.network(), self.prefix_len).unwrap()
1084
0
    }
1085
    
1086
    /// Returns the address.
1087
    #[inline]
1088
0
    pub const fn addr(&self) -> Ipv6Addr {
1089
0
        self.addr
1090
0
    }
1091
1092
    /// Returns the prefix length.
1093
    #[inline]
1094
0
    pub const fn prefix_len(&self) -> u8 {
1095
0
        self.prefix_len
1096
0
    }
1097
    
1098
    /// Returns the maximum valid prefix length.
1099
    #[inline]
1100
0
    pub const fn max_prefix_len(&self) -> u8 {
1101
0
        128
1102
0
    }
1103
1104
    /// Returns the network mask.
1105
    ///
1106
    /// # Examples
1107
    ///
1108
    /// ```
1109
    /// # use std::net::Ipv6Addr;
1110
    /// # use ipnet::Ipv6Net;
1111
    /// #
1112
    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1113
    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
1114
    /// ```
1115
0
    pub fn netmask(&self) -> Ipv6Addr {
1116
0
        self.netmask_u128().into()
1117
0
    }
1118
1119
0
    fn netmask_u128(&self) -> u128 {
1120
0
        u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value())
1121
0
    }
1122
1123
    /// Returns the host mask.
1124
    ///
1125
    /// # Examples
1126
    ///
1127
    /// ```
1128
    /// # use std::net::Ipv6Addr;
1129
    /// # use ipnet::Ipv6Net;
1130
    /// #
1131
    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1132
    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1133
    /// ```
1134
0
    pub fn hostmask(&self) -> Ipv6Addr {
1135
0
        self.hostmask_u128().into()
1136
0
    }
1137
1138
0
    fn hostmask_u128(&self) -> u128 {
1139
0
        u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value())
1140
0
    }
1141
1142
    /// Returns the network address.
1143
    ///
1144
    /// # Examples
1145
    ///
1146
    /// ```
1147
    /// # use std::net::Ipv6Addr;
1148
    /// # use ipnet::Ipv6Net;
1149
    /// #
1150
    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1151
    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
1152
    /// ```
1153
0
    pub fn network(&self) -> Ipv6Addr {
1154
0
        (u128::from(self.addr) & self.netmask_u128()).into()
1155
0
    }
1156
    
1157
    /// Returns the last address.
1158
    ///
1159
    /// Technically there is no such thing as a broadcast address for
1160
    /// IPv6. The name is used for consistency with colloquial usage.
1161
    ///
1162
    /// # Examples
1163
    ///
1164
    /// ```
1165
    /// # use std::net::Ipv6Addr;
1166
    /// # use ipnet::Ipv6Net;
1167
    /// #
1168
    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1169
    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1170
    /// ```
1171
0
    pub fn broadcast(&self) -> Ipv6Addr {
1172
0
        (u128::from(self.addr) | self.hostmask_u128()).into()
1173
0
    }
1174
1175
    /// Returns the `Ipv6Net` that contains this one.
1176
    ///
1177
    /// # Examples
1178
    ///
1179
    /// ```
1180
    /// # use std::str::FromStr;
1181
    /// # use ipnet::Ipv6Net;
1182
    /// #
1183
    /// let n1: Ipv6Net = "fd00:ff00::/24".parse().unwrap();
1184
    /// let n2: Ipv6Net = "fd00:fe00::/23".parse().unwrap();
1185
    /// let n3: Ipv6Net = "fd00:fe00::/0".parse().unwrap();
1186
    ///
1187
    /// assert_eq!(n1.supernet().unwrap(), n2);
1188
    /// assert_eq!(n3.supernet(), None);
1189
    /// ```
1190
0
    pub fn supernet(&self) -> Option<Ipv6Net> {
1191
0
        Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
1192
0
    }
1193
1194
    /// Returns `true` if this network and the given network are 
1195
    /// children of the same supernet.
1196
    ///
1197
    /// # Examples
1198
    ///
1199
    /// ```
1200
    /// # use ipnet::Ipv6Net;
1201
    /// #
1202
    /// let n1: Ipv6Net = "fd00::/18".parse().unwrap();
1203
    /// let n2: Ipv6Net = "fd00:4000::/18".parse().unwrap();
1204
    /// let n3: Ipv6Net = "fd00:8000::/18".parse().unwrap();
1205
    ///
1206
    /// assert!(n1.is_sibling(&n2));
1207
    /// assert!(!n2.is_sibling(&n3));
1208
    /// ```
1209
0
    pub fn is_sibling(&self, other: &Ipv6Net) -> bool {
1210
0
        self.prefix_len > 0 &&
1211
0
        self.prefix_len == other.prefix_len &&
1212
0
        self.supernet().unwrap().contains(other)
1213
0
    }
1214
    
1215
    /// Return an `Iterator` over the host addresses in this network.
1216
    ///
1217
    /// # Examples
1218
    ///
1219
    /// ```
1220
    /// # use std::net::Ipv6Addr;
1221
    /// # use ipnet::Ipv6Net;
1222
    /// #
1223
    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1224
    /// assert_eq!(net.hosts().collect::<Vec<Ipv6Addr>>(), vec![
1225
    ///     "fd00::".parse::<Ipv6Addr>().unwrap(),
1226
    ///     "fd00::1".parse().unwrap(),
1227
    ///     "fd00::2".parse().unwrap(),
1228
    ///     "fd00::3".parse().unwrap(),
1229
    /// ]);
1230
    /// ```
1231
0
    pub fn hosts(&self) -> Ipv6AddrRange {
1232
0
        Ipv6AddrRange::new(self.network(), self.broadcast())
1233
0
    }
1234
1235
    /// Returns an `Iterator` over the subnets of this network with the
1236
    /// given prefix length.
1237
    ///
1238
    /// # Examples
1239
    ///
1240
    /// ```
1241
    /// # use ipnet::{Ipv6Net, PrefixLenError};
1242
    /// #
1243
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1244
    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1245
    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1246
    ///     "fd00:4000::/18".parse().unwrap(),
1247
    ///     "fd00:8000::/18".parse().unwrap(),
1248
    ///     "fd00:c000::/18".parse().unwrap(),
1249
    /// ]);
1250
    ///
1251
    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1252
    /// assert_eq!(net.subnets(128).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1253
    ///     "fd00::/128".parse::<Ipv6Net>().unwrap(),
1254
    ///     "fd00::1/128".parse().unwrap(),
1255
    ///     "fd00::2/128".parse().unwrap(),
1256
    ///     "fd00::3/128".parse().unwrap(),
1257
    /// ]);
1258
    ///
1259
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1260
    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
1261
    ///
1262
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1263
    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
1264
    /// ```
1265
0
    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv6Subnets, PrefixLenError> {
1266
0
        if self.prefix_len > new_prefix_len || new_prefix_len > 128 {
1267
0
            return Err(PrefixLenError);
1268
0
        }
1269
        
1270
0
        Ok(Ipv6Subnets::new(
1271
0
            self.network(),
1272
0
            self.broadcast(),
1273
0
            new_prefix_len,
1274
0
        ))
1275
0
    }
1276
1277
    /// Test if a network address contains either another network
1278
    /// address or an IP address.
1279
    ///
1280
    /// # Examples
1281
    ///
1282
    /// ```
1283
    /// # use std::net::Ipv6Addr;
1284
    /// # use ipnet::Ipv6Net;
1285
    /// #
1286
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1287
    /// let net_yes: Ipv6Net = "fd00::/17".parse().unwrap();
1288
    /// let net_no: Ipv6Net = "fd00::/15".parse().unwrap();
1289
    /// let ip_yes: Ipv6Addr = "fd00::1".parse().unwrap();
1290
    /// let ip_no: Ipv6Addr = "fd01::".parse().unwrap();
1291
    ///
1292
    /// assert!(net.contains(&net));
1293
    /// assert!(net.contains(&net_yes));
1294
    /// assert!(!net.contains(&net_no));
1295
    /// assert!(net.contains(&ip_yes));
1296
    /// assert!(!net.contains(&ip_no));
1297
    /// ```
1298
0
    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
1299
0
        Contains::contains(self, other)
1300
0
    }
Unexecuted instantiation: <ipnet::ipnet::Ipv6Net>::contains::<&ipnet::ipnet::Ipv6Net>
Unexecuted instantiation: <ipnet::ipnet::Ipv6Net>::contains::<&core::net::ip_addr::Ipv6Addr>
1301
1302
    // It is significantly faster to work on u128 that Ipv6Addr.
1303
0
    fn interval(&self) -> (u128, u128) {
1304
0
        (
1305
0
            u128::from(self.network()),
1306
0
            u128::from(self.broadcast()).saturating_add(1),
1307
0
        )
1308
0
    }
1309
1310
    /// Aggregate a `Vec` of `Ipv6Net`s and return the result as a new
1311
    /// `Vec`.
1312
    ///
1313
    /// # Examples
1314
    ///
1315
    /// ```
1316
    /// # use ipnet::Ipv6Net;
1317
    /// #
1318
    /// let nets = vec![
1319
    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1320
    ///     "fd00:4000::/18".parse().unwrap(),
1321
    ///     "fd00:8000::/18".parse().unwrap(),
1322
    /// ];
1323
    /// assert_eq!(Ipv6Net::aggregate(&nets), vec![
1324
    ///     "fd00::/17".parse::<Ipv6Net>().unwrap(),
1325
    ///     "fd00:8000::/18".parse().unwrap(),
1326
    /// ]);
1327
    /// ```
1328
0
    pub fn aggregate(networks: &Vec<Ipv6Net>) -> Vec<Ipv6Net> {
1329
0
        let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
1330
0
        intervals = merge_intervals(intervals);
1331
0
        let mut res: Vec<Ipv6Net> = Vec::new();
1332
1333
0
        for (start, mut end) in intervals {
1334
0
            if end != core::u128::MAX {
1335
0
                end = end.saturating_sub(1)
1336
0
            }
1337
0
            let iter = Ipv6Subnets::new(start.into(), end.into(), 0);
1338
0
            res.extend(iter);
1339
        }
1340
0
        res
1341
0
    }
1342
}
1343
1344
impl Default for Ipv6Net {
1345
0
    fn default() -> Self {
1346
0
        Self {
1347
0
            addr: Ipv6Addr::from(0),
1348
0
            prefix_len: 0,
1349
0
        }
1350
0
    }
1351
}
1352
1353
impl fmt::Debug for Ipv6Net {
1354
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1355
0
        fmt::Display::fmt(self, fmt)
1356
0
    }
1357
}
1358
1359
impl fmt::Display for Ipv6Net {
1360
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1361
0
        write!(fmt, "{}/{}", self.addr, self.prefix_len)
1362
0
    }
1363
}
1364
1365
impl From<Ipv6Addr> for Ipv6Net {
1366
0
    fn from(addr: Ipv6Addr) -> Ipv6Net {
1367
0
        Ipv6Net { addr, prefix_len: 128 }
1368
0
    }
1369
}
1370
1371
/// Provides a method to test if a network address contains either
1372
/// another network address or an IP address.
1373
///
1374
/// # Examples
1375
///
1376
/// ```
1377
/// # use std::net::IpAddr;
1378
/// # use ipnet::IpNet;
1379
/// #
1380
/// let n4_1: IpNet = "10.1.1.0/24".parse().unwrap();
1381
/// let n4_2: IpNet = "10.1.1.0/26".parse().unwrap();
1382
/// let n4_3: IpNet = "10.1.2.0/26".parse().unwrap();
1383
/// let ip4_1: IpAddr = "10.1.1.1".parse().unwrap();
1384
/// let ip4_2: IpAddr = "10.1.2.1".parse().unwrap();
1385
///
1386
/// let n6_1: IpNet = "fd00::/16".parse().unwrap();
1387
/// let n6_2: IpNet = "fd00::/17".parse().unwrap();
1388
/// let n6_3: IpNet = "fd01::/17".parse().unwrap();
1389
/// let ip6_1: IpAddr = "fd00::1".parse().unwrap();
1390
/// let ip6_2: IpAddr = "fd01::1".parse().unwrap();
1391
///
1392
/// assert!(n4_1.contains(&n4_2));
1393
/// assert!(!n4_1.contains(&n4_3));
1394
/// assert!(n4_1.contains(&ip4_1));
1395
/// assert!(!n4_1.contains(&ip4_2));
1396
///
1397
/// assert!(n6_1.contains(&n6_2));
1398
/// assert!(!n6_1.contains(&n6_3));
1399
/// assert!(n6_1.contains(&ip6_1));
1400
/// assert!(!n6_1.contains(&ip6_2));
1401
///
1402
/// assert!(!n4_1.contains(&n6_1) && !n6_1.contains(&n4_1));
1403
/// assert!(!n4_1.contains(&ip6_1) && !n6_1.contains(&ip4_1));
1404
/// ```
1405
pub trait Contains<T> {
1406
    fn contains(&self, other: T) -> bool;
1407
}
1408
1409
impl<'a> Contains<&'a IpNet> for IpNet {
1410
0
    fn contains(&self, other: &IpNet) -> bool {
1411
0
        match (*self, *other) {
1412
0
            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.contains(b),
1413
0
            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.contains(b),
1414
0
            _ => false,
1415
        }
1416
0
    }
1417
}
1418
1419
impl<'a> Contains<&'a IpAddr> for IpNet {
1420
0
    fn contains(&self, other: &IpAddr) -> bool {
1421
0
        match (*self, *other) {
1422
0
            (IpNet::V4(ref a), IpAddr::V4(ref b)) => a.contains(b),
1423
0
            (IpNet::V6(ref a), IpAddr::V6(ref b)) => a.contains(b),
1424
0
            _ => false,
1425
        }
1426
0
    }
1427
}
1428
1429
impl<'a> Contains<&'a Ipv4Net> for Ipv4Net {
1430
0
    fn contains(&self, other: &'a Ipv4Net) -> bool {
1431
0
        self.network() <= other.network() && other.broadcast() <= self.broadcast()
1432
0
    }
1433
}
1434
1435
impl<'a> Contains<&'a Ipv4Addr> for Ipv4Net {
1436
0
    fn contains(&self, other: &'a Ipv4Addr) -> bool {
1437
0
        self.network() <= *other && *other <= self.broadcast()
1438
0
    }
1439
}
1440
1441
impl<'a> Contains<&'a Ipv6Net> for Ipv6Net {
1442
0
    fn contains(&self, other: &'a Ipv6Net) -> bool {
1443
0
        self.network() <= other.network() && other.broadcast() <= self.broadcast()
1444
0
    }
1445
}
1446
1447
impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net {
1448
0
    fn contains(&self, other: &'a Ipv6Addr) -> bool {
1449
0
        self.network() <= *other && *other <= self.broadcast()
1450
0
    }
1451
}
1452
1453
/// An `Iterator` that generates IP network addresses, either IPv4 or
1454
/// IPv6.
1455
///
1456
/// Generates the subnets between the provided `start` and `end` IP
1457
/// addresses inclusive of `end`. Each iteration generates the next
1458
/// network address of the largest valid size it can, while using a
1459
/// prefix length not less than `min_prefix_len`.
1460
///
1461
/// # Examples
1462
///
1463
/// ```
1464
/// # use std::net::{Ipv4Addr, Ipv6Addr};
1465
/// # use std::str::FromStr;
1466
/// # use ipnet::{IpNet, IpSubnets, Ipv4Subnets, Ipv6Subnets};
1467
/// let subnets = IpSubnets::from(Ipv4Subnets::new(
1468
///     "10.0.0.0".parse().unwrap(),
1469
///     "10.0.0.239".parse().unwrap(),
1470
///     26,
1471
/// ));
1472
/// 
1473
/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1474
///     "10.0.0.0/26".parse().unwrap(),
1475
///     "10.0.0.64/26".parse().unwrap(),
1476
///     "10.0.0.128/26".parse().unwrap(),
1477
///     "10.0.0.192/27".parse().unwrap(),
1478
///     "10.0.0.224/28".parse().unwrap(),
1479
/// ]);
1480
///
1481
/// let subnets = IpSubnets::from(Ipv6Subnets::new(
1482
///     "fd00::".parse().unwrap(),
1483
///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1484
///     26,
1485
/// ));
1486
/// 
1487
/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1488
///     "fd00::/26".parse().unwrap(),
1489
///     "fd00:40::/26".parse().unwrap(),
1490
///     "fd00:80::/26".parse().unwrap(),
1491
///     "fd00:c0::/27".parse().unwrap(),
1492
///     "fd00:e0::/28".parse().unwrap(),
1493
/// ]);
1494
/// ```
1495
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1496
pub enum IpSubnets {
1497
    V4(Ipv4Subnets),
1498
    V6(Ipv6Subnets),
1499
}
1500
1501
/// An `Iterator` that generates IPv4 network addresses.
1502
///
1503
/// Generates the subnets between the provided `start` and `end` IP
1504
/// addresses inclusive of `end`. Each iteration generates the next
1505
/// network address of the largest valid size it can, while using a
1506
/// prefix length not less than `min_prefix_len`.
1507
///
1508
/// # Examples
1509
///
1510
/// ```
1511
/// # use std::net::Ipv4Addr;
1512
/// # use std::str::FromStr;
1513
/// # use ipnet::{Ipv4Net, Ipv4Subnets};
1514
/// let subnets = Ipv4Subnets::new(
1515
///     "10.0.0.0".parse().unwrap(),
1516
///     "10.0.0.239".parse().unwrap(),
1517
///     26,
1518
/// );
1519
/// 
1520
/// assert_eq!(subnets.collect::<Vec<Ipv4Net>>(), vec![
1521
///     "10.0.0.0/26".parse().unwrap(),
1522
///     "10.0.0.64/26".parse().unwrap(),
1523
///     "10.0.0.128/26".parse().unwrap(),
1524
///     "10.0.0.192/27".parse().unwrap(),
1525
///     "10.0.0.224/28".parse().unwrap(),
1526
/// ]);
1527
/// ```
1528
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1529
pub struct Ipv4Subnets {
1530
    start: Ipv4Addr,
1531
    end: Ipv4Addr, // end is inclusive
1532
    min_prefix_len: u8,
1533
}
1534
1535
/// An `Iterator` that generates IPv6 network addresses.
1536
///
1537
/// Generates the subnets between the provided `start` and `end` IP
1538
/// addresses inclusive of `end`. Each iteration generates the next
1539
/// network address of the largest valid size it can, while using a
1540
/// prefix length not less than `min_prefix_len`.
1541
///
1542
/// # Examples
1543
///
1544
/// ```
1545
/// # use std::net::Ipv6Addr;
1546
/// # use std::str::FromStr;
1547
/// # use ipnet::{Ipv6Net, Ipv6Subnets};
1548
/// let subnets = Ipv6Subnets::new(
1549
///     "fd00::".parse().unwrap(),
1550
///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1551
///     26,
1552
/// );
1553
/// 
1554
/// assert_eq!(subnets.collect::<Vec<Ipv6Net>>(), vec![
1555
///     "fd00::/26".parse().unwrap(),
1556
///     "fd00:40::/26".parse().unwrap(),
1557
///     "fd00:80::/26".parse().unwrap(),
1558
///     "fd00:c0::/27".parse().unwrap(),
1559
///     "fd00:e0::/28".parse().unwrap(),
1560
/// ]);
1561
/// ```
1562
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1563
pub struct Ipv6Subnets {
1564
    start: Ipv6Addr,
1565
    end: Ipv6Addr, // end is inclusive
1566
    min_prefix_len: u8,
1567
}
1568
1569
impl Ipv4Subnets {
1570
0
    pub fn new(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Self {
1571
0
        Ipv4Subnets {
1572
0
            start: start,
1573
0
            end: end,
1574
0
            min_prefix_len: min_prefix_len,
1575
0
        }
1576
0
    }
1577
}
1578
1579
impl Ipv6Subnets {
1580
0
    pub fn new(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Self {
1581
0
        Ipv6Subnets {
1582
0
            start: start,
1583
0
            end: end,
1584
0
            min_prefix_len: min_prefix_len,
1585
0
        }
1586
0
    }
1587
}
1588
1589
impl From<Ipv4Subnets> for IpSubnets {
1590
0
    fn from(i: Ipv4Subnets) -> IpSubnets {
1591
0
        IpSubnets::V4(i)
1592
0
    }
1593
}
1594
1595
impl From<Ipv6Subnets> for IpSubnets {
1596
0
    fn from(i: Ipv6Subnets) -> IpSubnets {
1597
0
        IpSubnets::V6(i)
1598
0
    }
1599
}
1600
1601
impl Iterator for IpSubnets {
1602
    type Item = IpNet;
1603
1604
0
    fn next(&mut self) -> Option<Self::Item> {
1605
0
        match *self {
1606
0
            IpSubnets::V4(ref mut a) => a.next().map(IpNet::V4),
1607
0
            IpSubnets::V6(ref mut a) => a.next().map(IpNet::V6),
1608
        }
1609
0
    }
1610
}
1611
1612
0
fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
1613
0
    let range = end.saturating_sub(start).saturating_add(1);
1614
0
    if range == core::u32::MAX && min_prefix_len == 0 {
1615
0
        Ipv4Net::new(start, min_prefix_len).unwrap()
1616
    }
1617
    else {
1618
0
        let range_bits = 32u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1619
0
        let start_tz = u32::from(start).trailing_zeros();
1620
0
        let new_prefix_len = 32 - min(range_bits, start_tz);
1621
0
        let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
1622
0
        Ipv4Net::new(start, next_prefix_len).unwrap()
1623
    }
1624
0
}
1625
1626
0
fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
1627
0
    let range = end.saturating_sub(start).saturating_add(1);
1628
0
    if range == core::u128::MAX && min_prefix_len == 0 {
1629
0
        Ipv6Net::new(start, min_prefix_len).unwrap()
1630
    }
1631
    else {
1632
0
        let range = end.saturating_sub(start).saturating_add(1);
1633
0
        let range_bits = 128u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
1634
0
        let start_tz = u128::from(start).trailing_zeros();
1635
0
        let new_prefix_len = 128 - min(range_bits, start_tz);
1636
0
        let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
1637
0
        Ipv6Net::new(start, next_prefix_len).unwrap()
1638
    }
1639
0
}
1640
1641
impl Iterator for Ipv4Subnets {
1642
    type Item = Ipv4Net;
1643
1644
0
    fn next(&mut self) -> Option<Self::Item> {
1645
0
        match self.start.partial_cmp(&self.end) {
1646
            Some(Less) => {
1647
0
                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1648
0
                self.start = next.broadcast().saturating_add(1);
1649
1650
                // Stop the iterator if we saturated self.start. This
1651
                // check worsens performance slightly but overall this
1652
                // approach of operating on Ipv4Addr types is faster
1653
                // than what we were doing before using Ipv4Net.
1654
0
                if self.start == next.broadcast() {
1655
0
                    self.end.replace_zero();
1656
0
                }
1657
0
                Some(next)
1658
            },
1659
            Some(Equal) => {
1660
0
                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1661
0
                self.start = next.broadcast().saturating_add(1);
1662
0
                self.end.replace_zero();
1663
0
                Some(next)
1664
            },
1665
0
            _ => None,
1666
        }
1667
0
    }
1668
}
1669
1670
impl Iterator for Ipv6Subnets {
1671
    type Item = Ipv6Net;
1672
1673
0
    fn next(&mut self) -> Option<Self::Item> {
1674
0
        match self.start.partial_cmp(&self.end) {
1675
            Some(Less) => {
1676
0
                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1677
0
                self.start = next.broadcast().saturating_add(1);
1678
1679
                // Stop the iterator if we saturated self.start. This
1680
                // check worsens performance slightly but overall this
1681
                // approach of operating on Ipv6Addr types is faster
1682
                // than what we were doing before using Ipv6Net.
1683
0
                if self.start == next.broadcast() {
1684
0
                    self.end.replace_zero();
1685
0
                }
1686
0
                Some(next)
1687
            },
1688
            Some(Equal) => {
1689
0
                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1690
0
                self.start = next.broadcast().saturating_add(1);
1691
0
                self.end.replace_zero();
1692
0
                Some(next)
1693
            },
1694
0
            _ => None,
1695
        }
1696
0
    }
1697
}
1698
1699
impl FusedIterator for IpSubnets {}
1700
impl FusedIterator for Ipv4Subnets {}
1701
impl FusedIterator for Ipv6Subnets {}
1702
1703
// Generic function for merging a vector of intervals.
1704
0
fn merge_intervals<T: Copy + Ord>(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> {
1705
0
    if intervals.len() == 0 {
1706
0
        return intervals;
1707
0
    }
1708
1709
0
    intervals.sort();
1710
0
    let mut res: Vec<(T, T)> = Vec::new();
1711
0
    let (mut start, mut end) = intervals[0];
1712
    
1713
0
    let mut i = 1;
1714
0
    let len = intervals.len();
1715
0
    while i < len {
1716
0
        let (next_start, next_end) = intervals[i];
1717
0
        if end >= next_start {
1718
0
            start = min(start, next_start);
1719
0
            end = max(end, next_end);
1720
0
        }
1721
0
        else {
1722
0
            res.push((start, end));
1723
0
            start = next_start;
1724
0
            end = next_end;
1725
0
        }
1726
0
        i += 1;
1727
    }
1728
1729
0
    res.push((start, end));
1730
0
    res
1731
0
}
Unexecuted instantiation: ipnet::ipnet::merge_intervals::<u32>
Unexecuted instantiation: ipnet::ipnet::merge_intervals::<u128>
1732
1733
#[cfg(test)]
1734
mod tests {
1735
    use super::*;
1736
1737
    macro_rules! make_ipnet_vec {
1738
        ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
1739
        ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
1740
    }
1741
1742
    #[test]
1743
    fn test_make_ipnet_vec() {
1744
        assert_eq!(
1745
            make_ipnet_vec![
1746
                "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
1747
                "fd00::1/128", "fd00::2/127", "fd00::3/126",
1748
            ],
1749
            vec![
1750
                "10.1.1.1/32".parse().unwrap(),
1751
                "10.2.2.2/24".parse().unwrap(),
1752
                "10.3.3.3/16".parse().unwrap(),
1753
                "fd00::1/128".parse().unwrap(),
1754
                "fd00::2/127".parse().unwrap(),
1755
                "fd00::3/126".parse().unwrap(),
1756
            ]
1757
        );
1758
    }
1759
1760
    #[test]
1761
    fn test_merge_intervals() {
1762
        let v = vec![
1763
            (0, 1), (1, 2), (2, 3),
1764
            (11, 12), (13, 14), (10, 15), (11, 13),
1765
            (20, 25), (24, 29),
1766
        ];
1767
1768
        let v_ok = vec![
1769
            (0, 3),
1770
            (10, 15),
1771
            (20, 29),
1772
        ];
1773
1774
        let vv = vec![
1775
            ([0, 1], [0, 2]), ([0, 2], [0, 3]), ([0, 0], [0, 1]),
1776
            ([10, 15], [11, 0]), ([10, 0], [10, 16]),
1777
        ];
1778
1779
        let vv_ok = vec![
1780
            ([0, 0], [0, 3]),
1781
            ([10, 0], [11, 0]),
1782
        ];
1783
1784
        assert_eq!(merge_intervals(v), v_ok);
1785
        assert_eq!(merge_intervals(vv), vv_ok);
1786
    }
1787
1788
    macro_rules! make_ipv4_subnets_test {
1789
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1790
            #[test]
1791
            fn $name() {
1792
                let subnets = IpSubnets::from(Ipv4Subnets::new(
1793
                    $start.parse().unwrap(),
1794
                    $end.parse().unwrap(),
1795
                    $min_prefix_len,
1796
                ));
1797
                let results = make_ipnet_vec![$($x),*];
1798
                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1799
            }
1800
        );
1801
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1802
            make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1803
        );
1804
    }
1805
1806
    macro_rules! make_ipv6_subnets_test {
1807
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1808
            #[test]
1809
            fn $name() {
1810
                let subnets = IpSubnets::from(Ipv6Subnets::new(
1811
                    $start.parse().unwrap(),
1812
                    $end.parse().unwrap(),
1813
                    $min_prefix_len,
1814
                ));
1815
                let results = make_ipnet_vec![$($x),*];
1816
                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1817
            }
1818
        );
1819
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1820
            make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1821
        );
1822
    }
1823
1824
    make_ipv4_subnets_test!(
1825
        test_ipv4_subnets_zero_zero,
1826
        "0.0.0.0", "0.0.0.0", 0,
1827
        "0.0.0.0/32",
1828
    );
1829
1830
    make_ipv4_subnets_test!(
1831
        test_ipv4_subnets_zero_max,
1832
        "0.0.0.0", "255.255.255.255", 0,
1833
        "0.0.0.0/0",
1834
    );
1835
1836
    make_ipv4_subnets_test!(
1837
        test_ipv4_subnets_max_max,
1838
        "255.255.255.255", "255.255.255.255", 0,
1839
        "255.255.255.255/32",
1840
    );
1841
    
1842
    make_ipv4_subnets_test!(
1843
        test_ipv4_subnets_none,
1844
        "0.0.0.1", "0.0.0.0", 0,
1845
    );
1846
    
1847
    make_ipv4_subnets_test!(
1848
        test_ipv4_subnets_one,
1849
        "0.0.0.0", "0.0.0.1", 0,
1850
        "0.0.0.0/31",
1851
    );
1852
1853
    make_ipv4_subnets_test!(
1854
        test_ipv4_subnets_two,
1855
        "0.0.0.0", "0.0.0.2", 0,
1856
        "0.0.0.0/31",
1857
        "0.0.0.2/32",
1858
    );
1859
    
1860
    make_ipv4_subnets_test!(
1861
        test_ipv4_subnets_taper,
1862
        "0.0.0.0", "0.0.0.10", 30,
1863
        "0.0.0.0/30",
1864
        "0.0.0.4/30",
1865
        "0.0.0.8/31",
1866
        "0.0.0.10/32",
1867
    );
1868
    
1869
    make_ipv6_subnets_test!(
1870
        test_ipv6_subnets_zero_zero,
1871
        "::", "::", 0,
1872
        "::/128",
1873
    );
1874
1875
    make_ipv6_subnets_test!(
1876
        test_ipv6_subnets_zero_max,
1877
        "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1878
        "::/0",
1879
    );
1880
1881
    make_ipv6_subnets_test!(
1882
        test_ipv6_subnets_max_max,
1883
        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1884
        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
1885
    );
1886
    
1887
    make_ipv6_subnets_test!(
1888
        test_ipv6_subnets_none,
1889
        "::1", "::", 0,
1890
    );
1891
    
1892
    make_ipv6_subnets_test!(
1893
        test_ipv6_subnets_one,
1894
        "::", "::1", 0,
1895
        "::/127",
1896
    );
1897
1898
    make_ipv6_subnets_test!(
1899
        test_ipv6_subnets_two,
1900
        "::", "::2", 0,
1901
        "::/127",
1902
        "::2/128",
1903
    );
1904
1905
    make_ipv6_subnets_test!(
1906
        test_ipv6_subnets_taper,
1907
        "::", "::a", 126,
1908
        "::/126",
1909
        "::4/126",
1910
        "::8/127",
1911
        "::a/128",
1912
    );
1913
1914
    #[test]
1915
    fn test_aggregate() {
1916
        let ip_nets = make_ipnet_vec![
1917
            "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
1918
            "10.0.2.0/24",
1919
            "10.1.0.0/24", "10.1.1.0/24",
1920
            "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
1921
            "fd00::/32", "fd00:1::/32",
1922
            "fd00:2::/32",
1923
        ];
1924
1925
        let ip_aggs = make_ipnet_vec![
1926
            "10.0.0.0/23",
1927
            "10.0.2.0/24",
1928
            "10.1.0.0/23",
1929
            "192.168.0.0/22",
1930
            "fd00::/31",
1931
            "fd00:2::/32",
1932
        ];
1933
1934
        let ipv4_nets: Vec<Ipv4Net> = ip_nets.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1935
        let ipv4_aggs: Vec<Ipv4Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
1936
        let ipv6_nets: Vec<Ipv6Net> = ip_nets.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1937
        let ipv6_aggs: Vec<Ipv6Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
1938
1939
        assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
1940
        assert_eq!(Ipv4Net::aggregate(&ipv4_nets), ipv4_aggs);
1941
        assert_eq!(Ipv6Net::aggregate(&ipv6_nets), ipv6_aggs);
1942
    }
1943
    
1944
    #[test]
1945
    fn test_aggregate_issue44() {
1946
        let nets: Vec<Ipv4Net> = vec!["128.0.0.0/1".parse().unwrap()];
1947
        assert_eq!(Ipv4Net::aggregate(&nets), nets);
1948
1949
        let nets: Vec<Ipv4Net> = vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()];
1950
        assert_eq!(Ipv4Net::aggregate(&nets), vec!["0.0.0.0/0".parse().unwrap()]);
1951
1952
        let nets: Vec<Ipv6Net> = vec!["8000::/1".parse().unwrap()];
1953
        assert_eq!(Ipv6Net::aggregate(&nets), nets);
1954
1955
        let nets: Vec<Ipv6Net> = vec!["::/1".parse().unwrap(), "8000::/1".parse().unwrap()];
1956
        assert_eq!(Ipv6Net::aggregate(&nets), vec!["::/0".parse().unwrap()]);
1957
    }
1958
1959
    #[test]
1960
    fn ipnet_default() {
1961
        let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
1962
        assert_eq!(ipnet, IpNet::default());
1963
    }
1964
1965
    #[test]
1966
    fn ipv4net_default() {
1967
        let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
1968
        assert_eq!(ipnet, Ipv4Net::default());
1969
    }
1970
1971
    #[test]
1972
    fn ipv6net_default() {
1973
        let ipnet: Ipv6Net = "::/0".parse().unwrap();
1974
        assert_eq!(ipnet, Ipv6Net::default());
1975
    }
1976
1977
    #[test]
1978
    fn new_assert() {
1979
        const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1980
        const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1981
        const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1982
        const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1983
1984
        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1985
        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1986
        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1987
        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1988
    }
1989
1990
    #[test]
1991
    #[should_panic]
1992
    fn ipv4net_new_assert_panics() {
1993
        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 33);
1994
    }
1995
1996
    #[test]
1997
    #[should_panic]
1998
    fn ipv6net_new_assert_panics() {
1999
        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 129);
2000
    }
2001
}