ipnetwork

A Rust library for parsing and working with IPv4 and IPv6 CIDR network ranges.

Library
Cargo
v0.21.1
144stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
50/100Fair
Development Activity20
Maintenance24
Community76
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture85
Code Quality88
Innovation84
Learning Curve82

ipnetwork is a lightweight, dependency-free Rust crate for representing and manipulating IP network ranges expressed in CIDR notation. It provides distinct Ipv4Network and Ipv6Network types plus a unified IpNetwork enum that mirror the standard library’s IpAddr family, so you can parse strings like 192.168.1.0/24 or 2001:db8::/32, inspect their address and prefix, and reason about the addresses they contain.

Beyond parsing, the crate offers iteration over every address in a network, containment and membership checks, netmask-to-prefix conversion, network size calculation, and optional serde and schemars integration. It is widely used across the Rust ecosystem as a foundational building block for firewalls, routers, IP-allocation tooling, and any application that needs to work with subnets.

What You Get

  • Ipv4Network, Ipv6Network, and a unifying IpNetwork enum that parallel the standard library’s IP address types
  • CIDR string parsing via FromStr, plus constructors from an address and prefix or an address and netmask
  • Address iteration, containment checks, network/broadcast/mask accessors, and network size calculation
  • Optional serde serialization/deserialization and schemars JSON Schema generation behind feature flags
  • A typed IpNetworkError enum for precise, non-panicking error handling

Common Use Cases

  • Parsing and validating subnet definitions from configuration files or user input
  • Checking whether a given IP address falls within an allowed or blocked network range
  • Enumerating all addresses in a subnet for allocation, scanning, or provisioning tasks
  • Serializing and deserializing network ranges in JSON APIs and config formats via serde

Under The Hood

Architecture - The crate is organized around a small set of value types split across focused modules: ipv4.rs and ipv6.rs define Ipv4Network/Ipv6Network (each an address plus a u8 prefix), lib.rs wraps them in the IpNetwork enum and dispatches shared operations, parse.rs centralizes CIDR string splitting and prefix parsing, size.rs provides the NetworkSize abstraction, and error.rs defines the IpNetworkError and NetworkSizeError types. Parsing flows from FromStr through parse::cidr_parts/parse_prefix into the concrete constructors, and mask math is done with const helpers like ipv4_mask_bits that shift u32::MAX.

Tech Stack - Pure Rust on the 2021 edition with a minimum supported Rust version of 1.80. It has zero required dependencies, building only on std::net primitives; serde (1.0) and schemars (1.0) are optional and feature-gated so they stay out of the default build. Dev dependencies are serde_json and criterion for the benchmark in benches/parse_bench.rs.

Code Quality - The code is disciplined: lib.rs opens with #![deny(missing_debug_implementations, unsafe_code, unused_extern_crates, unused_import_braces)], so the crate forbids unsafe code outright. Error handling is exhaustive and non-panicking through the #[non_exhaustive] IpNetworkError enum, and many accessors are const fn. Test coverage is strong for a crate this size — roughly 80 unit tests inlined across ipv4.rs, ipv6.rs, and size.rs, plus serde round-trip integration tests in tests/test_json.rs.

API Design - The public surface deliberately mirrors the standard library’s IpAddr/Ipv4Addr/Ipv6Addr shape, so the types feel native and require almost no boilerplate: parse with "a.b.c.d/n".parse(), then call .ip(), .prefix(), .contains(), or iterate. Checked and unchecked netmask-conversion variants give callers a choice between ergonomics and explicit error handling, and derived Ord/Hash/Copy implementations make the types drop-in for collections. Documentation lives in rustdoc with runnable doctests rather than a long README, which is idiomatic for the ecosystem.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search