• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

src/H03-May-2022-3,4231,924

.cargo-checksum.jsonH A D03-May-202289 11

.cargo_vcs_info.jsonH A D01-Jan-197074 65

.gitignoreH A D01-Jan-197031 43

.travis.ymlH A D01-Jan-1970143 119

Cargo.tomlH A D01-Jan-19701.5 KiB3230

Cargo.toml.orig-cargoH A D01-Jan-19701.1 KiB2117

LICENSE-APACHEH A D01-Jan-197011.1 KiB202169

LICENSE-MITH A D01-Jan-19701 KiB84

README.mdH A D01-Jan-19707.2 KiB184129

RELEASES.mdH A D01-Jan-19703 KiB5628

README.md

1[![Build Status](https://travis-ci.org/krisprice/ipnet.svg?branch=master)](https://travis-ci.org/krisprice/ipnet)
2
3This module provides types and useful methods for working with IPv4 and IPv6 network addresses, commonly called IP prefixes. The new `IpNet`, `Ipv4Net`, and `Ipv6Net` types build on the existing `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` types already provided in Rust's standard library and align to their design to stay consistent.
4
5The module also provides the `IpSubnets`, `Ipv4Subnets`, and `Ipv6Subnets` types for interating over the subnets contained in an IP address range. The `IpAddrRange`, `Ipv4AddrRange`, and `Ipv6AddrRange` types for iterating over IP addresses in a range. And traits that extend `Ipv4Addr` and `Ipv6Addr` with methods for addition, subtraction, bitwise-and, and bitwise-or operations that are missing in Rust's standard library.
6
7The module only uses stable features so it is guaranteed to compile using the stable toolchain. Tests aim for thorough coverage and can be found in both the test modules and doctests. Please file an [issue on GitHub] if you have any problems, requests, or suggested improvements.
8
9Read the [documentation] for the full details. And find it on [Crates.io].
10
11[documentation]: https://docs.rs/ipnet/
12[Crates.io]: https://crates.io/crates/ipnet
13[issue on GitHub]: https://github.com/krisprice/ipnet/issues
14
15## Release 2.0 requirements
16
17Release 2.0 requires Rust 1.26 or later. Release 1.0 used a custom emulated 128-bit integer type (`Emu128`) to fully support IPv6 addresses. This has been replaced with Rust's built-in 128-bit integer, which is now stable as of Rust 1.26. There are reports of issues using Rust's 128-bit integers on some targets (e.g. Emscripten). If you have issues on your chosen target, please continue to use the 1.0 release until that has been resolved.
18
19## Examples
20
21### Create a network address and print the hostmask and netmask
22
23```rust
24extern crate ipnet;
25use std::net::{Ipv4Addr, Ipv6Addr};
26use std::str::FromStr;
27use ipnet::{IpNet, Ipv4Net, Ipv6Net};
28
29fn main() {
30    // Create an Ipv4Net and Ipv6Net from their constructors.
31
32    let net4 = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 24).unwrap();
33    let net6 = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24).unwrap();
34
35    // They can also be created from string representations.
36
37    let net4 = Ipv4Net::from_str("10.1.1.0/24").unwrap();
38    let net6 = Ipv6Net::from_str("fd00::/24").unwrap();
39
40    // Or alternatively as follows.
41
42    let net4: Ipv4Net = "10.1.1.0/24".parse().unwrap();
43    let net6: Ipv6Net = "fd00::/24".parse().unwrap();
44
45    // IpNet can represent either an IPv4 or IPv6 network address.
46
47    let net = IpNet::from(net4);
48
49    // It can also be created from string representations.
50
51    let net = IpNet::from_str("10.1.1.0/24").unwrap();
52    let net: IpNet = "10.1.1.0/24".parse().unwrap();
53
54    // There are a number of methods that can be used. Read the
55    // documentation for the full details.
56
57    println!("{} hostmask = {}", net, net.hostmask());
58    println!("{} netmask = {}", net4, net4.netmask());
59}
60```
61
62### Subdivide an existing IP network into smaller subnets
63
64```rust
65extern crate ipnet;
66use ipnet::Ipv4Net;
67
68fn main() {
69    let net: Ipv4Net = "192.168.0.0/23".parse().unwrap();
70
71    println!("\n/25 subnets in {}:", net);
72
73    // Note: `subnets()` returns a `Result`. If the given prefix length
74    // is less than the existing prefix length the `Result` will contain
75    // an error.
76
77    let subnets = net.subnets(25)
78        .expect("PrefixLenError: new prefix length cannot be shorter than existing");
79
80    // Output:
81    //  subnet 0 = 192.168.0.0/25
82    //  subnet 1 = 192.168.0.128/25
83    //  subnet 2 = 192.168.1.0/25
84    //  subnet 3 = 192.168.1.128/25
85
86    for (i, n) in subnets.enumerate() {
87        println!("\tsubnet {} = {}", i, n);
88    }
89}
90```
91
92### Iterate over the valid subnets between two IPv4 addresses
93
94```rust
95extern crate ipnet;
96use std::net::Ipv4Addr;
97use ipnet::Ipv4Subnets;
98
99fn main() {
100    let start = Ipv4Addr::new(10, 0, 0, 0);
101    let end = Ipv4Addr::new(10, 0, 0, 239);
102
103    println!("\n/0 or greater subnets between {} and {}:", start, end);
104
105    // Output all subnets starting with the largest that will fit. This
106    // will give us the smallest possible set of valid subnets.
107    //
108    // Output:
109    //  subnet 0 = 10.0.0.0/25
110    //  subnet 1 = 10.0.0.128/26
111    //  subnet 2 = 10.0.0.192/27
112    //  subnet 3 = 10.0.0.224/28
113
114    let subnets = Ipv4Subnets::new(start, end, 0);
115
116    for (i, n) in subnets.enumerate() {
117        println!("\tsubnet {} = {}", i, n);
118    }
119
120    println!("\n/26 or greater subnets between {} and {}:", start, end);
121
122    // Output all subnets with prefix lengths less than or equal to 26.
123    // This results in more subnets, but limits them to a maximum size.
124    //
125    // Output:
126    //  subnet 0 = 10.0.0.0/26
127    //  subnet 1 = 10.0.0.64/26
128    //  subnet 2 = 10.0.0.128/26
129    //  subnet 3 = 10.0.0.192/27
130    //  subnet 4 = 10.0.0.224/28
131
132    let subnets = Ipv4Subnets::new(start, end, 26);
133
134    for (i, n) in subnets.enumerate() {
135        println!("\tsubnet {} = {}", i, n);
136    }
137}
138```
139
140### Aggregate a list of IP prefixes
141
142```rust
143extern crate ipnet;
144use ipnet::IpNet;
145
146fn main() {}
147    // Example input list of overlapping and adjacent prefixes.
148
149    let strings = vec![
150        "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
151        "10.0.2.0/24",
152        "10.1.0.0/24", "10.1.1.0/24",
153        "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
154        "fd00::/32", "fd00:1::/32",
155    ];
156
157    let nets: Vec<IpNet> = strings.iter().filter_map(|p| p.parse().ok()).collect();
158
159    println!("\nAggregated IP prefixes:");
160
161    // Output:
162    //  10.0.0.0/23
163    //  10.0.2.0/24
164    //  10.1.0.0/23
165    //  192.168.0.0/22
166    //  fd00::/31
167
168    for n in IpNet::aggregate(&nets) {
169        println!("\t{}", n);
170    }
171}
172```
173
174## Future
175
176* Implementing `std::ops::{Add, Sub, BitAnd, BitOr}` for `Ipv4Addr` and `Ipv6Addr` would be useful as these are common operations on IP addresses. If done, the extension traits provided in this module would be removed and the major version incremented. Implementing these requires a change to the standard library. I've started a thread on this topic on the [Rust Internals](https://internals.rust-lang.org/t/pre-rfc-implementing-add-sub-bitand-bitor-for-ipaddr-ipv4addr-ipv6addr/) discussion board.
177* The results of `hosts()` and potentially `subnets()` should be represented as a `Range` rather than the custom `IpAddrRange` and `IpSubnets` types provided in this module. This requires the target types to have `Add` and `Step` implemented for them. Implementing `Add` for `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` requires a change to the standard library (see above). And `Step` is still unstable so exploring this will also wait until it has stablized.
178
179## License
180
181Copyright (c) 2017, Juniper Networks, Inc. All rights reserved.
182
183This code is licensed to you under either the MIT License or Apache License, Version 2.0 at your choice (the "License"). You may not use this code except in compliance with the License. This code is not an official Juniper product. You can obtain a copy of the License at: https://opensource.org/licenses/MIT or http://www.apache.org/licenses/LICENSE-2.0
184