ipnet API reference
IP addresses and CIDR networks, IPv4 and IPv6. Parse an address or a address/prefix block, test membership, and compute netmask / broadcast - for allow-lists and subnet math. An Address holds its raw bytes (4 for IPv4, 16 for IPv6, network byte order); a Network pairs a base address with a prefix length. Pure Jennifer over strings + convert and the bitwise operators; both binaries. parseAddress folds an IPv4-mapped IPv6 literal (::ffff:a.b.c.d) down to a v4 Address so it can't slip past a v4 allow-list (see unmap).
Import with import "ipnet.j" as ipnet;. See the ipnet guide for prose and examples.
Functions
ipnet.aggregate(nets as list of Network)
Collapse a list of networks into the minimal equivalent set: contained blocks are dropped and adjacent sibling pairs are merged into their shorter parent (e.g. 192.168.0.0/25 + 192.168.0.128/25 -> 192.168.0.0/24). IPv4 and IPv6 entries are aggregated independently; the result is sorted ascending.
Parameters
nets{list of Network}- the networks to aggregate
Returns {list of Network} - the minimal covering set
ipnet.broadcast(net as Network)
The broadcast (last) address of a network - every host bit set. For IPv4 this is the broadcast address; for IPv6 it is the last address in the block.
Parameters
net{Network}- the network
Returns {Address} - the last address in the network
ipnet.compare(a as Address, b as Address)
Order two addresses: -1 if a < b, 0 if equal, 1 if a > b. Different versions order v4 before v6 (a stable, if arbitrary, total order for sorting).
Parameters
a{Address}- the first addressb{Address}- the second address
Returns {int} - -1, 0, or 1
ipnet.contains(net as Network, addr as Address)
Whether an address falls within a network (same version and matching prefix bits). A version mismatch is simply false.
Parameters
net{Network}- the networkaddr{Address}- the address to test
Returns {bool} - true if the address is in the network
ipnet.equal(a as Address, b as Address)
Whether two addresses are equal (same version and bytes).
Parameters
a{Address}- the first addressb{Address}- the second address
Returns {bool} - true if equal
ipnet.firstUsable(net as Network)
The first usable host address of a network. For IPv4 this is the address after the network base (the base is the network address), except a /31 (RFC 3021 point-to-point, both addresses usable) and a /32 (single host), where it is the base itself. For IPv6 it is the base + 1 (skipping the subnet-router anycast), except /127 and /128 where it is the base.
Parameters
net{Network}- the network
Returns {Address} - the first usable address
ipnet.hostCount(net as Network)
The total number of addresses in a network (2 ^ host-bits). Throws when the block is too large to hold in an int (an IPv4 prefix is always fine; an IPv6 prefix must be >= 66). For usable-host semantics see firstUsable / lastUsable.
Parameters
net{Network}- the network
Returns {int} - the count of addresses in the block
Throws
{Error}- kind "ipnet" when the block exceeds the int range
ipnet.hosts(net as Network)
Every usable host address of a network, in ascending order (from firstUsable to lastUsable inclusive). Capped at 65536 addresses - a larger block throws, so materializing a whole /8 cannot exhaust memory; walk those with next instead.
Parameters
net{Network}- the network
Returns {list of Address} - the usable host addresses
Throws
{Error}- kind "ipnet" when the block has more than 65536 addresses
ipnet.isGlobal(addr as Address)
Whether an address is a normal globally-routable unicast address - i.e. its scope is Global (not private, loopback, link-local, multicast, unspecified, or a reserved / documentation range). Best-effort, per the well-known special-purpose registries.
Parameters
addr{Address}- the address
Returns {bool} - true if globally routable
ipnet.isLinkLocal(addr as Address)
Whether an address is link-local (169.254.0.0/16 or fe80::/10).
Parameters
addr{Address}- the address
Returns {bool} - true if link-local
ipnet.isLoopback(addr as Address)
Whether an address is a loopback address (127.0.0.0/8 or ::1).
Parameters
addr{Address}- the address
Returns {bool} - true if loopback
ipnet.isMulticast(addr as Address)
Whether an address is multicast (224.0.0.0/4 or ff00::/8).
Parameters
addr{Address}- the address
Returns {bool} - true if multicast
ipnet.isPrivate(addr as Address)
Whether an address is in private (RFC 1918) or IPv6 unique-local (fc00::/7) space.
Parameters
addr{Address}- the address
Returns {bool} - true if private / ULA
ipnet.isUnspecified(addr as Address)
Whether an address is the unspecified address (0.0.0.0 or ::).
Parameters
addr{Address}- the address
Returns {bool} - true if unspecified
ipnet.lastUsable(net as Network)
The last usable host address of a network. For IPv4 this is the address before the broadcast address, except a /31 or /32 (where the last address is usable). IPv6 has no broadcast address, so the last address of the block is usable.
Parameters
net{Network}- the network
Returns {Address} - the last usable address
ipnet.netmask(net as Network)
The netmask of a network as an address (e.g. 255.255.255.0 for a /24).
Parameters
net{Network}- the network
Returns {Address} - the netmask address
ipnet.networkString(net as Network)
Render a network as address/prefix.
Parameters
net{Network}- the network
Returns {string} - the CIDR text
ipnet.next(addr as Address)
The next address after addr (numerically +1). Throws at the last address of the version (255.255.255.255 / all-ones IPv6) - there is no successor.
Parameters
addr{Address}- the address
Returns {Address} - the following address
Throws
{Error}- kind "ipnet" at the last address
ipnet.overlaps(a as Network, b as Network)
Whether two networks share any address. Different versions never overlap.
Parameters
a{Network}- the first networkb{Network}- the second network
Returns {bool} - true if the blocks intersect
ipnet.parse(cidr as string)
Parse a CIDR block address/prefix into a Network with host bits zeroed. The prefix range is taken from the literal, so an IPv6 v4-mapped block (::ffff:0:0/96) is accepted as a /96 and then folded to its v4 equivalent (0.0.0.0/0, i.e. the prefix is translated down by the 96-bit v4-mapped offset) - mirroring how parseAddress folds a v4-mapped address. A block with a prefix shorter than 96 stays a genuine v6 network (it spans beyond the v4-mapped range).
Parameters
cidr{string}- the CIDR text (e.g. "10.0.0.0/8" or "2001:db8::/32")
Returns {Network} - the network
Throws
{Error}- kind "ipnet" on malformed input or an out-of-range prefix
ipnet.parseAddress(s as string)
Parse a bare IP address (IPv4 dotted-quad or IPv6, with :: compression and embedded IPv4 supported).
Parameters
s{string}- the address text
Returns {Address} - the parsed address
Throws
{Error}- kind "ipnet" on malformed input
ipnet.prev(addr as Address)
The previous address before addr (numerically -1). Throws at the first address (0.0.0.0 / ::).
Parameters
addr{Address}- the address
Returns {Address} - the preceding address
Throws
{Error}- kind "ipnet" at the first address
ipnet.scope(addr as Address)
Classify an address into its Scope. A v4-mapped IPv6 address is folded to v4 first (via unmap), so ::ffff:10.0.0.1 classifies as Private.
Parameters
addr{Address}- the address
Returns {Scope} - the address's scope
ipnet.split(net as Network, newPrefix as int)
Divide a network into the equal subnets of a longer prefix (e.g. a /24 into four /26s). Returns them in ascending order. Capped at 65536 subnets (a newPrefix no more than 16 bits longer than the network prefix).
Parameters
net{Network}- the network to splitnewPrefix{int}- the subnet prefix length (>= net.prefix, <= version max)
Returns {list of Network} - the subnets
Throws
{Error}- kind "ipnet" on a bad prefix or more than 65536 subnets
ipnet.subnetOf(child as Network, parent as Network)
Whether child is wholly contained in parent (a subnet of it, or equal). Different versions are never a subnet.
Parameters
child{Network}- the candidate subnetparent{Network}- the enclosing network
Returns {bool} - true if child lies inside parent
ipnet.toString(addr as Address)
Render an address to its canonical string (IPv4 dotted-quad, or RFC 5952 canonical IPv6).
Parameters
addr{Address}- the address
Returns {string} - the canonical text
ipnet.unmap(addr as Address)
Fold an IPv4-mapped IPv6 address (::ffff:a.b.c.d, the ::ffff:0:0/96 range) down to the plain IPv4 Address it represents; any other address is returned unchanged. Without this, ::ffff:127.0.0.1 stays a version-6 Address and silently misses a version-4 network in a contains allow-list / deny-list check - a bypass of exactly the kind the leading-zero and embedded-IPv4 guards already close (OM-010). parseAddress applies it, so a v4-mapped literal parses straight to a v4 Address. The deprecated IPv4-compatible form (::a.b.c.d) is intentionally left alone: it is ambiguous with low addresses like ::1 and unmapping it would be wrong.
Parameters
addr{Address}- the address to normalize
Returns {Address} - a v4 Address if addr was v4-mapped, else addr unchanged
ipnet.version(addr as Address)
The IP version of an address (4 or 6).
Parameters
addr{Address}- the address
Returns {int} - 4 or 6
Structs
ipnet.Address
An IP address as raw bytes.
| Field | Type | Description |
|---|---|---|
version | int | the IP version: 4 or 6 |
octets | bytes | the address bytes (4 for IPv4, 16 for IPv6), network byte order |
ipnet.Network
A CIDR network: a base address (host bits zeroed) plus a prefix length.
| Field | Type | Description |
|---|---|---|
addr | Address | the network base address |
prefix | int | the prefix length (0..32 for IPv4, 0..128 for IPv6) |
Enums
ipnet.Scope
The address scope: which well-known category an address falls in. A total, disjoint classification - every address is exactly one Scope - so the is* predicates are thin wrappers over it and a caller can match on the whole set. Reserved covers the special-purpose ranges that are neither a normal global unicast address nor one of the named categories (documentation, benchmarking, shared CGNAT space, and other reserved blocks).