ipnetwork: a Rust library for parsing and working with IP CIDRs
A small, dependency-light crate that parses IPv4/IPv6 CIDR strings into typed networks you can test membership against.
The ipnetwork crate solves a narrow problem: turning CIDR notation into something Rust programs can reason about safely. Given a string like "10.9.0.32/16", it produces an Ipv4Network value with the address, prefix, and derived properties — network address, broadcast address, mask, size, and membership tests — all without hand-rolling bit math in every caller.
It is a library, not a tool: there are no binaries. Its source lives under src/, with integration tests in tests/ and Criterion benchmarks in benches/. The crate's own description is one line: "A library to work with IP CIDRs in Rust."
What it gives you
The public surface centers on three types. Ipv4Network and Ipv6Network hold a concrete address plus a prefix length, and IpNetwork is an enum wrapping either:
pub enum IpNetwork {
V4(Ipv4Network),
V6(Ipv6Network),
}
Ipv4Network derives Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, and Ord.
Construction happens through parsing. Both network types implement FromStr, so a CIDR string parses directly:
let net: Ipv4Network = "10.9.0.32/16".parse().unwrap();
The parser (src/parse.rs) splits on the single slash, rejects strings with more than one, and validates that the prefix does not exceed 32 bits for IPv4 or 128 for IPv6. A bare address without a slash parses as a full-prefix network — "10.9.0.1" becomes /32. There is also with_netmask, which accepts an explicit netmask and converts it to a prefix, and the const constructor new_checked, which returns Option<Ipv4Network> so it can be used in constant contexts.
The operations
Once you have a network value, the useful methods are mostly const fn:
ip()andprefix()return the stored address and length.network()gives the lowest address in range;broadcast()the highest. For IPv6 it returns the top of the range.mask()builds the netmask from the prefix.contains(ip)tests membership with a single mask-and-compare — cheap enough that it appears as a benchmark target inbenches/parse_bench.rs.size()counts addresses, returningu32::MAXfor/0. IPv6 sizes live behind the separateNetworkSizetype because they can exceed 32 bits.nth(n)returns the n-th address by index, orNoneout of range.
Subnet relations are covered too: is_subnet_of, is_supernet_of, and overlaps.
Iteration is supported. Both network types expose iter(), returning a dedicated iterator type (Ipv4NetworkIterator, Ipv6NetworkIterator). The iterators implement DoubleEndedIterator, so you can call .rev() to walk descending, and the tests in tests/reverse_iterators.rs are unusually thorough about it — they exercise every front/back consumption pattern across a four-address network and assert that singleton networks like 0.0.0.0/32 do not underflow or repeat.
Optional features
The crate keeps its default feature set empty on purpose, as the comment in Cargo.toml explains: most people add a dependency without disabling defaults, so optional dependencies should stay out of that path to avoid pulling them in involuntarily. Two opt-in features exist:
serde, which serializes networks as their CIDR string and deserializes by parsing back.schemars, which generates JSON Schema for the network types. The IPv4 schema is a regex pattern over dotted-quad plus prefix; theIpNetworkschema is aoneOfacross v4 and v6.
The tests in tests/test_json.rs round-trip both families through serde when that feature is enabled, and validate that schemars output carries the expected structure. Both features are gated with #[cfg(feature = ...)], so a default build compiles neither dependency.
Getting started
Setup follows any Rust crate:
git clone https://github.com/achanda/ipnetwork
cd ipnetwork
cargo test
Or add it as a dependency and enable the features you need:
[dependencies]
ipnetwork = { version = "0.21", features = ["serde"] }
The crate requires Rust 1.80 or newer (rust-version in Cargo.toml) and uses edition 2021.
Maintenance posture
This is a small, mature, low-churn project — about 20 files and roughly 100 KB. The Cargo manifest marks it "passively-maintained," which fits the evidence: releases are infrequent but real (the changelog records v0.21.1 fixing an edge case for 0::/0 networks), dependency updates arrive through Renovate, and the README documents running Clippy with cargo clippy. It is dual-licensed Apache-2.0 OR MIT.
The main authors are Abhishek Chanda and Linus Färnstrand (faern). The changelog records recent changes such as new_checked, opt-in serde, and u128-based IPv6 core methods; the code and tests show double-ended iteration via .rev().
For a developer deciding whether to reach for it: if you need CIDR parsing, membership tests, subnet math, or address enumeration in Rust and want those as plain typed values rather than hand-rolled bit operations, this crate covers the ground with no default dependencies. If your needs are exotic — say, arbitrary netmask forms beyond dotted-quad, or streaming over a /0 IPv6 range (up to 2^128 addresses, which the docs warn will take "a _long_ time") — budget for doing some of that yourself.
achanda/ipnetwork: 100 KB in 20 files, indexed Nov 9, 2026 after 0.00 hours of indexing. License: Apache-2.0 OR MIT. Source: https://github.com/achanda/ipnetwork.
Ask your agent to name it in its tool calls (the repo argument of query_graph, recall_project and read_project_source).
Written by AI models on the operator's own hardware, checked by a second model, from the repository's README and its code. Back to the shelf