xnetip

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

xnetip

CI Go Reference License

IPv4 and IPv6 network types for Go: (address, mask) pairs with first-class non-contiguous masks and full set algebra.

// A mask net/netip cannot express — and every operation stays correct on it.
n := xnetip.MustParseNetwork4("10.0.0.0/255.0.255.0")

n.ContainsAddr(netip.MustParseAddr("10.7.0.9")) // true
n.ContainsAddr(netip.MustParseAddr("10.7.1.9")) // false
fmt.Println(n.LastAddr())                       // 10.255.0.255

Install

go get github.com/yanet-platform/xnetip

Requires Go 1.24. The runtime code depends only on the standard library — the test dependencies in go.mod (testify, rapid) are never pulled into your build.

Overview

  • Three network types. Network4 and Network6 are (address, mask) pairs where the mask is any bit pattern; Network holds either family. Values are small, immutable and always normalized (addr & mask == addr); the zero values are valid networks (0.0.0.0/0, ::/0).
  • Set algebra, correct on any mask. Contains, ContainsAddr, Intersection, Intersects, IsDisjoint, IsAdjacent, Merge, SupernetFor and Difference, which carves one network out of another into exact, pairwise-disjoint pieces.
  • Contiguous[T] — CIDR guaranteed by the type. A wrapper whose mask is a leading run of ones by construction: PrefixLen() int and Prefix() netip.Prefix become total, Intersection and Difference stay closed over the class, and its parsers reject non-contiguous input with ErrNonContiguousMask.
  • Collections. Aggregate4/Aggregate6 fold a slice in place using non-contiguous merges, AggregateContiguous computes a minimal CIDR cover, RangeToNetworks4/RangeToNetworks6 turn an arbitrary address range into the minimal list of CIDR blocks.
  • Iteration. Addrs and AddrsBackward as iter.Seq[netip.Addr], NumHostBits for the exact address count.
  • Text. String, AppendTo, MarshalText/UnmarshalText: a contiguous network prints as addr/prefix, a non-contiguous one as addr/mask, and both forms parse back. Compact renders host routes as a bare address. Parsing is strict: net/netip digit rules, no leading zeros in the prefix length, zones rejected.
  • net/netip interop. Plain zone-free netip.Addr is the address currency of the whole API, Contiguous converts to and from netip.Prefix, and wherever an operation has a net/netip analogue it keeps the analogue's name and semantics.

Why not net/netip

net/netip models a network as netip.Prefix — an address plus a prefix length — which can only express a mask that is a run of leading ones, and stops at membership tests. xnetip complements it where that is not enough:

net/netip xnetip
Network model address + prefix length, contiguous masks only (address, mask), any mask
Notation 10.0.0.0/8 10.0.0.0/8 and 10.0.0.0/255.0.255.0
Set algebra Contains, Overlaps containment, intersection, difference, merge, adjacency, supernet
Slice operations aggregation, range → CIDR list
Address iteration Addr.Next/Prev iter.Seq[netip.Addr], both directions

Examples

Address range → minimal CIDR list.

first := netip.MustParseAddr("10.0.0.1")
last := netip.MustParseAddr("10.0.0.30")
for block := range xnetip.RangeToNetworks4(first, last) {
	fmt.Println(block)
}
// 10.0.0.1/32  10.0.0.2/31  10.0.0.4/30  10.0.0.8/29
// 10.0.0.16/29 10.0.0.24/30 10.0.0.28/31 10.0.0.30/32

Aggregation beyond CIDR. Non-contiguous merges collapse networks that no CIDR aggregator can combine — here two /25s fold into a /24, which then merges with a non-adjacent /24 across the gap:

nets := []xnetip.Network4{
	xnetip.MustParseNetwork4("10.0.0.0/24"),
	xnetip.MustParseNetwork4("10.0.1.0/25"),
	xnetip.MustParseNetwork4("10.0.4.0/25"),
	xnetip.MustParseNetwork4("10.0.4.128/25"),
}
nets = xnetip.Aggregate4(nets) // in place, no allocation
// [10.0.1.0/25 10.0.0.0/255.255.251.0]

Carving a block out of another. Difference yields exact, pairwise-disjoint remainders — on CIDR blocks, the classic prefix ladder:

outer := xnetip.MustParseContiguous4("10.0.0.0/16")
inner := xnetip.MustParseContiguous4("10.0.4.0/22")
for block := range outer.Difference(inner) {
	fmt.Println(block)
}
// 10.0.128.0/17 10.0.64.0/18 10.0.32.0/19
// 10.0.16.0/20  10.0.8.0/21  10.0.0.0/22

The full API is documented on pkg.go.dev.

Guarantees

  • Operations do not allocate — the exceptions are String/MarshalText results and error construction — and hot paths are pinned by testing.AllocsPerRun tests.
  • No unsafe, no cgo, no reflection.
  • IPv4 and IPv6 take the same algorithm through every operation; behavior never diverges between families.
  • Tested with property-based checks (differential against net/netip where an oracle exists) and fuzzed parsers.

License

Apache 2.0, see LICENSE.

Documentation

Overview

Package xnetip provides IPv4 and IPv6 network types with first-class support for non-contiguous subnet masks.

A network is an (address, mask) pair where the mask may be any bit pattern, not only a run of leading ones. All operations — containment, intersection, difference, merge, adjacency, aggregation, iteration — are defined on those pairs and stay correct for non-contiguous masks. Addresses at the API boundary are plain zone-free netip.Addr values, while all mask algebra runs on host-order integers internally. The package depends only on the standard library.

Index

Constants

This section is empty.

Variables

View Source
var ErrAddrFamilyMismatch = errors.New("address family mismatch")

ErrAddrFamilyMismatch reports an address of the other IP family where one family was required.

Examples are IPv6 text given to ParseNetwork4 or an IPv6 mask given to an IPv4 network.

View Source
var ErrCIDROverflow = errors.New("prefix length out of range")

ErrCIDROverflow reports a prefix length outside its address family's range, 0 through 32 for IPv4 and 0 through 128 for IPv6.

The CIDR constructors return it wrapped with the address and length echoed, so errors.Is recognizes the rejection whatever the entry point.

View Source
var ErrEmptyInput = errors.New("empty input")

ErrEmptyInput reports empty text where a network was required.

Only the UnmarshalText implementations return it: their zero values are valid networks, so empty text must not silently produce one the way it produces the invalid zero netip.Prefix. The parsers reject empty text through ErrParse and the net/netip cause instead.

View Source
var ErrInvalidMask = errors.New("invalid network mask")

ErrInvalidMask reports network text whose part after "/" is neither a prefix length nor a mask address of the network's family.

The network parsers return it, together with the underlying cause when one exists: the net/netip error for a suffix that is no address at all, ErrAddrFamilyMismatch for a mask of the other family, ErrZone for a mask carrying a zone suffix.

View Source
var ErrNonBiContiguousMask = errors.New("mask not bi-contiguous")

ErrNonBiContiguousMask reports a valid IPv6 mask with an interior hole in either 64-bit half, where a bi-contiguous mask was required.

The checked address-pair constructor returns it when the plain IPv6 network is valid but does not carry the stronger per-half shape.

View Source
var ErrNonContiguousMask = errors.New("mask not contiguous")

ErrNonContiguousMask reports network text whose mask is valid but not a leading run of one bits, where a CIDR block was required.

Only the Contiguous parsers return it: the text is a well-formed network that the plain network parsers accept.

View Source
var ErrParse = errors.New("invalid address or network text")

ErrParse reports text that is not an address or network in any accepted form.

Every parser of this package wraps it, together with the net/netip error that carries the detail, so errors.Is recognizes a rejection whatever its cause.

View Source
var ErrZone = errors.New("zone not allowed")

ErrZone reports IPv6 text carrying a zone suffix ("fe80::1%eth0"), which the zone-free address types of this package cannot represent.

Only the IPv6 parsers return it: net/netip accepts the zone, so the rejection is this package's own and wraps the sentinel alone.

Functions

func Compact

func Compact[T compactable](n T) compact[T]

Compact renders a network-like value in its shortest unambiguous form.

A host route is written as its bare address, everything else exactly as the network's own String writes it: address and prefix length for a contiguous mask, address and explicit mask otherwise. A Network is written in its own family, so the host-route rule fires at 32 bits for IPv4 and at 128 for IPv6, an IPv4-mapped IPv6 network counting as IPv6. Guarantee-bearing wrappers keep the same rule and reparse through their own parsers. The opaque result carries String, AppendTo and fmt.Stringer.

func RangeToNetworks4

func RangeToNetworks4(first, last netip.Addr) iter.Seq[Contiguous[Network4]]

RangeToNetworks4 returns the minimum set of CIDR blocks covering the closed address interval [first, last].

Blocks are yielded in ascending order and are pairwise disjoint, each one a typed CIDR block aligned to its own size, and no CIDR decomposition of the interval uses fewer blocks (at most 62). The function is total: the sequence is empty when first > last, and when either end — an IPv6 end (IPv4-mapped included) or the invalid zero Addr — is not an Is4 netip.Addr, because such an interval holds no IPv4 addresses. The sequence is allocation-free and re-iterable.

func RangeToNetworks6

func RangeToNetworks6(first, last netip.Addr) iter.Seq[Contiguous[Network6]]

RangeToNetworks6 returns the minimum set of CIDR blocks covering the closed address interval [first, last].

Blocks are yielded in ascending order and are pairwise disjoint, each one a typed CIDR block aligned to its own size, and no CIDR decomposition of the interval uses fewer blocks (at most 254). The function is total: the sequence is empty when first > last, and when either end — an Is4 end or the invalid zero Addr — is not an Is6 netip.Addr, because such an interval holds no IPv6 addresses. An IPv4-mapped end is IPv6 and accepted, a zone is dropped silently. The sequence is allocation-free and re-iterable.

Types

type BiContiguous added in v0.1.1

type BiContiguous struct {
	// contains filtered or unexported fields
}

BiContiguous is an IPv6 network whose two 64-bit mask halves are independently contiguous.

Each half is a leading run of one bits followed by zero bits. The zero value wraps ::/0 and is valid. Values are immutable, comparable with == exactly when their wrapped networks are, and safe to copy. The unexported field prevents construction without validating or otherwise proving the mask shape.

func AggregateBiContiguous6 added in v0.1.1

func AggregateBiContiguous6(nets []BiContiguous) []BiContiguous

AggregateBiContiguous6 aggregates bi-contiguous IPv6 networks in place into a class-closed cover of the same address union.

Duplicates and containment are removed; low-half buddies and high-half buddies with equal canonical low sets merge. Every survivor stays in the class, no class-preserving pair remains, and a second call is a set no-op. The input is reordered; only the returned prefix is meaningful. Results sort by numeric (mask, address), not BiContiguous.Compare. The cover is not minimum: three rectangles can tile a parent with no accepted pair. For N inputs and S present shapes, it is O(N*S*log N) amortized plus bounded 65-level work, uses fixed stack state and allocates no heap memory.

func BiContiguousFrom added in v0.1.1

func BiContiguousFrom(addr, mask netip.Addr) (BiContiguous, error)

BiContiguousFrom returns the normalized bi-contiguous network with the given IPv6 address and mask.

Both arguments must be Is6 addresses. IPv4-mapped IPv6 is accepted and zones are dropped silently. An Is4 or invalid zero address wraps ErrAddrFamilyMismatch. A valid mask whose 64-bit halves are not each leading runs of ones wraps ErrNonBiContiguousMask. The zero wrapper is returned on every error.

func BiContiguousFrom6 added in v0.1.1

func BiContiguousFrom6(network Network6) (BiContiguous, bool)

BiContiguousFrom6 returns network with its bi-contiguity guarantee carried by the result type.

ok is false when either 64-bit mask half is not a leading run of ones, and the zero wrapper is returned. The network is otherwise carried unchanged.

func BiContiguousFromContiguous added in v0.1.1

func BiContiguousFromContiguous(block Contiguous[Network6]) BiContiguous

BiContiguousFromContiguous upgrades an IPv6 CIDR block to the broader bi-contiguous class without validation.

Every global leading run is independently a leading run in both 64-bit halves, so the conversion is total and carries the wrapped network unchanged.

func MustParseBiContiguous added in v0.1.1

func MustParseBiContiguous(s string) BiContiguous

MustParseBiContiguous calls ParseBiContiguous and panics on error.

It is intended for tests and package-level constants built from literals.

func ParseBiContiguous added in v0.1.1

func ParseBiContiguous(s string) (BiContiguous, error)

ParseBiContiguous parses an IPv6 network whose two mask halves are independently contiguous.

The grammar and ordinary parse errors are exactly ParseNetwork6's. A valid network whose mask has an interior hole in either 64-bit half instead wraps ErrNonBiContiguousMask under this function's name.

func (BiContiguous) Addrs added in v0.1.1

func (m BiContiguous) Addrs() iter.Seq[netip.Addr]

Addrs returns every address in row-major host-index order.

The low half's host counter cycles fastest and carries into the high half after its trailing host run is exhausted. The order, membership and count are exactly those of the wrapped network's Addrs sequence. Every yielded address is an Is6 netip.Addr, zone-free. The sequence is re-iterable, allocation-free and stops early when the consumer breaks.

func (BiContiguous) AddrsBackward added in v0.1.1

func (m BiContiguous) AddrsBackward() iter.Seq[netip.Addr]

AddrsBackward returns every address in reverse row-major host-index order.

The low half's host counter decrements fastest and borrows from the high half after reaching zero. The order, membership and count are exactly those of the wrapped network's AddrsBackward sequence. Every yielded address is an Is6 netip.Addr, zone-free. The sequence is re-iterable, allocation-free and stops early when the consumer breaks.

func (BiContiguous) AppendTo added in v0.1.1

func (m BiContiguous) AppendTo(b []byte) []byte

AppendTo appends the canonical text form to b.

The format is exactly the wrapped IPv6 network's, including its choice between a decimal prefix length and an explicit compressed mask.

func (BiContiguous) Compare added in v0.1.1

func (m BiContiguous) Compare(other BiContiguous) int

Compare returns -1, 0 or +1 as m sorts before, equal to or after other in the wrapped network order.

func (BiContiguous) Contains added in v0.1.1

func (m BiContiguous) Contains(other BiContiguous) bool

Contains reports whether every address of other is also an address of m.

Each mask half is a leading run of ones, so a receiver half constrains a subset of the other's bits exactly when its unsigned mask word is no greater. Checking both halves replaces the general whole-mask subset AND; normalized addresses still must agree on every receiver-constrained bit.

func (BiContiguous) Difference added in v0.1.1

func (m BiContiguous) Difference(other BiContiguous) iter.Seq[BiContiguous]

Difference returns the bi-contiguous networks whose union is m without other.

A disjoint other yields m once, while a containing other yields nothing. On overlap, pairwise-disjoint parts are yielded from the most significant pending mask bit: the high-half prefix extension first, then the low-half extension. The part count is the sum of those extension lengths. Each step lengthens one leading run, so every part stays bi-contiguous. The sequence is allocation-free and re-iterable.

func (BiContiguous) HighPrefixLen added in v0.1.1

func (m BiContiguous) HighPrefixLen() int

HighPrefixLen returns the leading-one length of the high 64-bit mask half.

The result is total and ranges from zero through 64. The zero wrapper reports zero.

func (BiContiguous) Intersection added in v0.1.1

func (m BiContiguous) Intersection(other BiContiguous) (BiContiguous, bool)

Intersection returns the bi-contiguous network common to m and other, or false when they are disjoint.

The mask union takes the longer leading run independently in each 64-bit half, so the result stays bi-contiguous and needs no revalidation. On false the first result is the zero wrapper.

func (BiContiguous) LowPrefixLen added in v0.1.1

func (m BiContiguous) LowPrefixLen() int

LowPrefixLen returns the leading-one length of the low 64-bit mask half.

The result is total and ranges from zero through 64. The zero wrapper reports zero.

func (BiContiguous) MarshalText added in v0.1.1

func (m BiContiguous) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

The text is the String form of the bi-contiguous network. It never fails and allocates only the returned slice.

func (BiContiguous) MergeByLowestMaskBit added in v0.1.1

func (m BiContiguous) MergeByLowestMaskBit(other BiContiguous) (BiContiguous, bool)

MergeByLowestMaskBit merges containment or lowest-mask-bit siblings while preserving bi-contiguity.

Containment returns an input unchanged. A sibling merge clears the low run's boundary bit when that run is nonempty, or the high run's boundary bit otherwise, so every successful result remains in the class. On false the first result is the zero wrapper.

func (BiContiguous) Network added in v0.1.1

func (m BiContiguous) Network() Network6

Network returns the wrapped IPv6 network.

It is total: the wrapper adds only the per-half mask guarantee, and operations without a guarantee-bearing result are reached through this view.

func (BiContiguous) String added in v0.1.1

func (m BiContiguous) String() string

String returns the canonical text form of the bi-contiguous network.

The format is exactly the wrapped IPv6 network's: a globally contiguous mask uses a prefix length, while a genuine two-run mask is written as a compressed IPv6 address. The output parses back with ParseBiContiguous.

func (*BiContiguous) UnmarshalText added in v0.1.1

func (m *BiContiguous) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

The text must be accepted by ParseBiContiguous. Empty text wraps ErrEmptyInput because the zero wrapper is a valid block. The receiver is untouched on every error.

type Contiguous

type Contiguous[T network[T]] struct {
	// contains filtered or unexported fields
}

Contiguous is a CIDR block: a network whose mask is a leading run of one bits, carried as a type-level guarantee.

The zero value wraps the zero network (0.0.0.0/0 for Network4, ::/0 otherwise), which is contiguous, so it is valid. Values are immutable, comparable with == exactly when the wrapped networks are, and safe to copy. The wrapper is generic over the family: Contiguous[Network4] is the IPv4 CIDR block, Contiguous[Network6] the IPv6 one, Contiguous[Network] the family-agnostic one.

func AggregateContiguous

func AggregateContiguous[T network[T]](nets []Contiguous[T]) []Contiguous[T]

AggregateContiguous aggregates CIDR blocks in place into their minimal cover and returns the kept prefix of nets.

Duplicates are removed, contained blocks eliminated and CIDR buddies merged, cascading, down to the unique smallest set of blocks whose address union equals the input's. The result is sorted by Compare and every block stays contiguous. Unlike Aggregate4 and Aggregate6, the cover is minimal and the pass runs in O(N log N): sorted contiguous blocks form a laminar family, so each candidate can only interact with the running top. The input slice is reordered; only the returned prefix is meaningful.

func ContiguousFrom

func ContiguousFrom[T network[T]](network T) (Contiguous[T], bool)

ContiguousFrom returns the network as a typed CIDR block.

ok is false when the mask is not contiguous, and the zero block is returned. The type argument is inferred from the argument. The exact counterpart of the widening ToContiguous conversions.

func ContiguousFrom4

func ContiguousFrom4(block Contiguous[Network4]) Contiguous[Network]

ContiguousFrom4 returns the Network instantiation holding an IPv4 block, mirroring NetworkFrom4.

The lift is total and preserves the address set. The lifted mask gains the 96 leading one bits that pin the IPv4-mapped storage form on top of its own run, which is a leading run again, so the result wraps without revalidation. The inverse of ContiguousIPv4.

func ContiguousFrom6

func ContiguousFrom6(block Contiguous[Network6]) Contiguous[Network]

ContiguousFrom6 returns the Network instantiation holding an IPv6 block, mirroring NetworkFrom6.

The lift is total: the network is carried verbatim with its mask unchanged, an IPv4-mapped block stays IPv6, so the result wraps without revalidation. The inverse of ContiguousIPv6.

func ContiguousFromCIDR

func ContiguousFromCIDR(addr netip.Addr, bits int) (Contiguous[Network], error)

ContiguousFromCIDR returns the block of addr with the top bits bits masked, in addr's own family, host bits cleared.

The mask built from a length is a leading run of ones, so the result is a CIDR block by construction. The length is bounded by the family, 0 through 32 for IPv4 and 0 through 128 for IPv6, otherwise ErrCIDROverflow is returned. An IPv4-mapped address is IPv6 and stays IPv6, as in netip. The invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch.

func ContiguousFromCIDR4

func ContiguousFromCIDR4(addr netip.Addr, bits int) (Contiguous[Network4], error)

ContiguousFromCIDR4 returns the block of addr with the top bits bits masked, host bits cleared.

The mask built from a length is a leading run of ones, so the result is a CIDR block by construction. The address must be Is4 — an IPv6 address, IPv4-mapped included, or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch — and bits must be in the range 0 through 32, otherwise ErrCIDROverflow is returned.

func ContiguousFromCIDR6

func ContiguousFromCIDR6(addr netip.Addr, bits int) (Contiguous[Network6], error)

ContiguousFromCIDR6 returns the block of addr with the top bits bits masked, host bits cleared.

The mask built from a length is a leading run of ones, so the result is a CIDR block by construction. The address must be Is6 (an IPv4-mapped address is IPv6, a zone is dropped silently) — an Is4 address or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch — and bits must be in the range 0 through 128, otherwise ErrCIDROverflow is returned.

func ContiguousFromPrefix

func ContiguousFromPrefix(p netip.Prefix) (Contiguous[Network], bool)

ContiguousFromPrefix converts a netip.Prefix into a CIDR block in the prefix address's own family, host bits cleared.

An Is4 prefix becomes an IPv4 block, anything else — an IPv4-mapped IPv6 prefix included — an IPv6 one, as in netip. ok is false only for the invalid zero prefix: a valid prefix always carries a contiguous mask, so the conversion is the exact inverse of Prefix and the round trip through either direction is the identity on masked prefixes.

func ContiguousFromPrefix4

func ContiguousFromPrefix4(p netip.Prefix) (Contiguous[Network4], bool)

ContiguousFromPrefix4 converts a netip.Prefix into an IPv4 CIDR block, host bits cleared.

ok is false when the prefix is invalid or its address is not Is4 — an IPv4-mapped prefix is IPv6, convert it through ContiguousFromPrefix6 instead. A valid prefix always carries a contiguous mask, so the conversion accepts every valid Is4 prefix and is the exact inverse of Prefix: the round trip through either direction is the identity on masked prefixes.

func ContiguousFromPrefix6

func ContiguousFromPrefix6(p netip.Prefix) (Contiguous[Network6], bool)

ContiguousFromPrefix6 converts a netip.Prefix into an IPv6 CIDR block, host bits cleared.

ok is false when the prefix is invalid or its address is Is4 — an IPv4-mapped IPv6 prefix is IPv6 and is accepted. A valid prefix always carries a contiguous mask, so the conversion accepts every valid Is6 prefix and is the exact inverse of Prefix: the round trip through either direction is the identity on masked prefixes.

func ContiguousIPv4

func ContiguousIPv4(block Contiguous[Network]) (Contiguous[Network4], bool)

ContiguousIPv4 returns the IPv4 block, ok is false for an IPv6 one — the free-function twin of Network.IPv4.

On ok the unwrap drops exactly the 96 leading one bits that pin the IPv4-mapped storage form, leaving the mask's own leading run, so the result wraps without revalidation. The inverse of ContiguousFrom4.

func ContiguousIPv6

func ContiguousIPv6(block Contiguous[Network]) (Contiguous[Network6], bool)

ContiguousIPv6 returns the IPv6 block, ok is false for an IPv4 one — the free-function twin of Network.IPv6.

On ok the network is carried verbatim with its mask unchanged, so the result wraps without revalidation. The inverse of ContiguousFrom6.

func MustParseContiguous

func MustParseContiguous(s string) Contiguous[Network]

MustParseContiguous calls ParseContiguous and panics on error.

It is intended for tests and package-level constants built from literals.

func MustParseContiguous4

func MustParseContiguous4(s string) Contiguous[Network4]

MustParseContiguous4 calls ParseContiguous4 and panics on error.

It is intended for tests and package-level constants built from literals.

func MustParseContiguous6

func MustParseContiguous6(s string) Contiguous[Network6]

MustParseContiguous6 calls ParseContiguous6 and panics on error.

It is intended for tests and package-level constants built from literals.

func ParseContiguous

func ParseContiguous(s string) (Contiguous[Network], error)

ParseContiguous parses an IPv4 or IPv6 CIDR block, the address part selecting the family (an IPv4-mapped address is IPv6).

The grammar is exactly ParseNetwork's, so both families' prefix, explicit-mask and bare address forms are accepted, with the mask required to be contiguous. Text whose mask is valid but not a leading run of one bits wraps ErrNonContiguousMask; every other rejection is ParseNetwork's, under this function's name.

func ParseContiguous4

func ParseContiguous4(s string) (Contiguous[Network4], error)

ParseContiguous4 parses an IPv4 CIDR block in prefix, explicit-mask or bare address notation.

The grammar is exactly ParseNetwork4's: "10.0.0.0/8", "10.0.0.0/255.0.0.0" (the mask must be contiguous) and "10.0.0.1" (a host route) are accepted. Text whose mask is valid but not a leading run of one bits wraps ErrNonContiguousMask; every other rejection is ParseNetwork4's, under this function's name.

func ParseContiguous6

func ParseContiguous6(s string) (Contiguous[Network6], error)

ParseContiguous6 parses an IPv6 CIDR block in prefix, explicit-mask or bare address notation.

The grammar is exactly ParseNetwork6's: "2001:db8::/32", "2001:db8::/ffff:ffff::" (the mask must be contiguous) and "2001:db8::1" (a host route) are accepted, an IPv4-mapped address is IPv6 and a zone suffix is an error. Text whose mask is valid but not a leading run of one bits wraps ErrNonContiguousMask; every other rejection is ParseNetwork6's, under this function's name.

func (Contiguous[T]) AppendTo

func (m Contiguous[T]) AppendTo(b []byte) []byte

AppendTo appends the text form of the block to b and returns the extended buffer.

The format is exactly the wrapped network's, and by the contiguity invariant the suffix is always a prefix length, never an explicit mask. The output parses back with the matching ParseContiguous function.

func (Contiguous[T]) Compare

func (m Contiguous[T]) Compare(other Contiguous[T]) int

Compare returns -1, 0 or +1 as m sorts before, equal to or after other, in the wrapped type's own order.

func (Contiguous[T]) Contains

func (m Contiguous[T]) Contains(other Contiguous[T]) bool

Contains reports whether every address of other is also an address of m.

Both blocks are CIDR by the type invariant, so the mask-subset check is a single unsigned compare of the masks — the typed argument is what makes that formula sound. The answer equals the wrapped networks' Contains; blocks of different families (Network instantiation) never contain each other.

func (Contiguous[T]) ContainsAddr

func (m Contiguous[T]) ContainsAddr(addr netip.Addr) bool

ContainsAddr reports whether addr is an address of this block.

The answer is exactly the wrapped network's ContainsAddr: total, the netip.Prefix.Contains rule, cross-family, zoned and invalid addresses not contained. For a Network instantiation the address must be of the block's own family.

func (Contiguous[T]) Difference

func (m Contiguous[T]) Difference(other Contiguous[T]) iter.Seq[Contiguous[T]]

Difference returns the blocks whose union is the set difference m \ other: every address of m that is not in other.

For CIDR operands every part is itself a CIDR block, so the sequence carries the type: when other is nested inside m the parts are the prefix ladder from m's length plus one down to other's length, most significant peeled bit first; a disjoint other yields m once; a containing other yields nothing. Order, count and disjointness are those of the wrapped networks' Difference. The sequence is allocation-free and re-iterable.

func (Contiguous[T]) Intersection

func (m Contiguous[T]) Intersection(other Contiguous[T]) (Contiguous[T], bool)

Intersection returns the block of addresses common to m and other.

Two CIDR blocks intersect exactly when one contains the other, so the result is the nested block, still contiguous — the class is closed under intersection and the result needs no revalidation. ok is false when the blocks are disjoint, and for blocks of different families in the Network instantiation; the first result is then the zero block.

func (Contiguous[T]) MarshalText

func (m Contiguous[T]) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

The text is the String form of the block: an address, "/" and a prefix length. It never fails and allocates only the returned slice.

func (Contiguous[T]) MergeByLowestMaskBit

func (m Contiguous[T]) MergeByLowestMaskBit(other Contiguous[T]) (Contiguous[T], bool)

MergeByLowestMaskBit merges two blocks when one contains the other or when they are CIDR buddies at the prefix boundary bit.

Containment returns the larger block; buddies merge into their parent, whose mask drops the run's lowest bit and therefore stays contiguous — the class is closed and the result needs no revalidation. Whenever ok is true the result equals the wrapped networks' MergeByLowestMaskBit; on ok=false the first result is the zero block.

func (Contiguous[T]) Network

func (m Contiguous[T]) Network() T

Network returns the wrapped network.

It is total and free: the wrapper adds only the contiguity guarantee, every operation the wrapper does not carry is reached through this view.

func (Contiguous[T]) Prefix

func (m Contiguous[T]) Prefix() netip.Prefix

Prefix returns the block as a netip.Prefix, total by the contiguity invariant.

The prefix is always valid, already masked and in the block's own family: an IPv4 block of the Network instantiation yields an Is4 prefix, never the mapped storage form.

func (Contiguous[T]) PrefixLen

func (m Contiguous[T]) PrefixLen() int

PrefixLen returns the prefix length of the block, total by the contiguity invariant.

The length is 0 through 32 for an IPv4 block, 0 through 128 for an IPv6 one, family-native for a Network instantiation.

func (Contiguous[T]) String

func (m Contiguous[T]) String() string

String returns the text form of the block, always an address and a prefix length ("10.0.0.0/8", "2001:db8::/32").

An explicit mask never appears: a contiguous mask always has a prefix length, so the prefix branch of the network format is the only reachable one. A Network instantiation prints in its own family. The output parses back with the matching ParseContiguous function.

func (*Contiguous[T]) UnmarshalText

func (m *Contiguous[T]) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

The text must be accepted by the family's ParseContiguous function, so a valid network with a non-contiguous mask wraps ErrNonContiguousMask. Empty text wraps ErrEmptyInput (the zero wrapper is a valid block). The receiver is untouched on any error.

type Network

type Network struct {
	// contains filtered or unexported fields
}

Network is an IPv4 or IPv6 network with a mask of arbitrary shape.

It is the family-agnostic counterpart of Network4 and Network6: every operation of the concrete types exists here and delegates to them, operations across families are false, ok=false or empty as documented on each method, and Compare orders every IPv4 network before every IPv6 network. An IPv4 network is stored as its image under Network4.ToIPv6Mapped, which preserves every set relation, while the accessors keep returning unmapped Is4 views. The zero value is ::/0. Values are immutable and safe to copy.

func MustParseNetwork

func MustParseNetwork(s string) Network

MustParseNetwork calls ParseNetwork and panics on error.

It is intended for tests and package-level constants built from literals.

func NetworkFrom

func NetworkFrom(addr, mask netip.Addr) (Network, error)

NetworkFrom returns the network with the given address and mask, normalizing the address by the mask.

Both arguments must belong to the same address family (Is4 with Is4, Is6 with Is6 — an IPv4-mapped address is Is6), otherwise ErrAddrFamilyMismatch is returned; the invalid zero netip.Addr is rejected the same way. Any mask bit pattern of the family is accepted, non-contiguous ones included. An IPv4 pair produces an IPv4 network, an IPv6 pair (IPv4-mapped addresses included) an IPv6 network. A zone is dropped silently.

func NetworkFrom4

func NetworkFrom4(network Network4) Network

NetworkFrom4 returns the Network holding an IPv4 network.

func NetworkFrom6

func NetworkFrom6(network Network6) Network

NetworkFrom6 returns the Network holding an IPv6 network.

An IPv6 network that happens to be IPv4-mapped stays IPv6, as in netip, where an IPv4-mapped address reports Is6 and not Is4.

func NetworkFromAddr

func NetworkFromAddr(addr netip.Addr) (Network, error)

NetworkFromAddr returns the host route that contains exactly addr, in the address family of addr.

An Is4 address yields an IPv4 network (/32) and an Is6 address an IPv6 network (/128). An IPv4-mapped IPv6 address is Is6 and yields an IPv6 network, a zone is dropped silently, and the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch.

func NetworkFromCIDR

func NetworkFromCIDR(addr netip.Addr, bits int) (Network, error)

NetworkFromCIDR returns the network of addr with the top bits bits masked, in addr's own family.

The length is bounded by the family, 0 through 32 for IPv4 and 0 through 128 for IPv6, otherwise ErrCIDROverflow is returned. An IPv4-mapped address is IPv6 and stays IPv6, as in netip. The invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch. Host bits of addr are cleared.

func NetworkFromPrefix

func NetworkFromPrefix(p netip.Prefix) (Network, bool)

NetworkFromPrefix converts a netip.Prefix into a Network.

The family follows the prefix address: an IPv4 prefix becomes an IPv4 network, anything else — an IPv4-mapped IPv6 prefix included — an IPv6 network, as in netip. The result is normalized: host bits of the prefix address are cleared, the same network netip.Prefix.Masked would report. ok is false only for the invalid zero prefix. The inverse of Prefix.

func ParseNetwork

func ParseNetwork(s string) (Network, error)

ParseNetwork parses an IPv4 or IPv6 network in CIDR, explicit-mask or bare address notation.

The address part selects the family and the mask must be of the same family: "10.0.0.0/8", "10.0.0.0/255.0.255.0", "2001:db8::/32", "2001:db8::/ffff:ffff::ffff:ffff:0:0", "10.0.0.1" and "2001:db8::1" are all accepted. An IPv4-mapped address such as "::ffff:192.0.2.0" is IPv6, so the network stays IPv6. Text whose address part is no address of either family wraps ErrParse with the net/netip cause; past that point the per-family grammar and errors are those of ParseNetwork4 and ParseNetwork6.

func (Network) Addr

func (m Network) Addr() netip.Addr

Addr returns the network address as a netip.Addr of the network's own family: Is4 for an IPv4 network, Is6 otherwise.

An IPv4 network answers with the unmapped view of the low 32 stored address bits, which the mapped-storage invariant makes exact.

func (Network) Addrs

func (m Network) Addrs() iter.Seq[netip.Addr]

Addrs returns every address of the network in host-index order, each carrying the network's address family.

An IPv4 network yields Is4 addresses, an IPv6 network Is6 ones, zone-free, in exactly the order of Network4.Addrs and Network6.Addrs. The number of addresses is 1 << NumHostBits().

func (Network) AddrsBackward

func (m Network) AddrsBackward() iter.Seq[netip.Addr]

AddrsBackward returns every address of the network in reverse host-index order, each carrying the network's address family.

It yields exactly the addresses of Addrs in the opposite order: Is4 netip.Addr values for an IPv4 network, Is6 for an IPv6 one, zone-free either way. The walk starts at LastAddr(), and for a contiguous mask it is descending numeric order down to Addr(). The sequence is re-iterable, allocation-free and stops early when the consumer breaks. The number of addresses is exactly 1 << NumHostBits().

func (Network) AppendTo

func (m Network) AppendTo(b []byte) []byte

AppendTo appends the text form of the network to b and returns the extended buffer.

An IPv4 network is written in the IPv4 form ("10.0.0.0/8"), never in its IPv4-mapped storage form. See Network4.AppendTo and Network6.AppendTo for the per-family format. The output parses back with ParseNetwork.

func (Network) Compare

func (m Network) Compare(other Network) int

Compare returns -1, 0 or +1 as m sorts before, equal to or after other.

Every IPv4 network sorts before every IPv6 network, the order netip.Addr.Compare gives across families. Within a family the order is that of Network4.Compare or Network6.Compare: lexicographic on (address, mask). An IPv4-mapped IPv6 network is an IPv6 network and sorts among IPv6 networks, not next to its IPv4 counterpart.

func (Network) Contains

func (m Network) Contains(other Network) bool

Contains reports whether every address of other is also an address of m.

Networks of different address families never contain each other. Within a family the result is the family's Contains, so masks may be non-contiguous and the usual rules apply: identical networks contain each other, the family universe contains every network of its family, a host route contains only itself.

func (Network) ContainsAddr

func (m Network) ContainsAddr(addr netip.Addr) bool

ContainsAddr reports whether addr is an address of this network.

The test is total, the netip.Prefix.Contains rule: an address of the other family — an IPv4-mapped IPv6 address against an IPv4 network included — the invalid zero netip.Addr, or a zoned address is simply not contained. Within the network's family the answer is that of Network4.ContainsAddr or Network6.ContainsAddr, so the mask may be non-contiguous.

func (Network) Difference

func (m Network) Difference(other Network) iter.Seq[Network]

Difference returns the networks whose union is the set difference m \ other, each part carrying m's address family.

Same-family operands delegate to the concrete peel: exactly popcount(d) pairwise-disjoint parts with d the mask bits fixed by the intersection but free in m, most significant bit of d first, as documented on Network4.Difference and Network6.Difference. Operands of different families share no address, so the difference is m itself, yielded once. Masks may be non-contiguous. The sequence is allocation-free and re-iterable.

func (Network) IPv4

func (m Network) IPv4() (Network4, bool)

IPv4 returns the IPv4 network, ok is false for an IPv6 network.

func (Network) IPv6

func (m Network) IPv6() (Network6, bool)

IPv6 returns the IPv6 network, ok is false for an IPv4 network.

func (Network) Intersection

func (m Network) Intersection(other Network) (Network, bool)

Intersection returns the network of addresses common to m and other.

Networks of different address families are disjoint and yield ok=false. Within a family the result is the family's Intersection: always a single network, ok=false only when the two disagree on a bit position both masks constrain. Masks may be non-contiguous. The result keeps the family of the inputs, and on ok=false the returned value is the zero Network.

func (Network) Intersects

func (m Network) Intersects(other Network) bool

Intersects reports whether the two networks share at least one address.

Networks of different families never intersect. Within a family the result equals the corresponding Network4 or Network6 method, for contiguous and non-contiguous masks alike.

func (Network) Is4

func (m Network) Is4() bool

Is4 reports whether the network is IPv4.

func (Network) Is6

func (m Network) Is6() bool

Is6 reports whether the network is IPv6 (including IPv4-mapped ones).

func (Network) IsAdjacent

func (m Network) IsAdjacent(other Network) bool

IsAdjacent reports whether the two networks share a mask and differ in exactly one masked bit.

Networks of different families are never adjacent. Within a family the result equals the corresponding Network4 or Network6 method.

func (Network) IsAdjacentByLowestMaskBit

func (m Network) IsAdjacentByLowestMaskBit(other Network) bool

IsAdjacentByLowestMaskBit reports whether the two networks share a mask and differ in exactly the lowest set bit of that mask.

Networks of different families are never adjacent. Within a family the result equals the corresponding Network4 or Network6 method.

func (Network) IsContiguous

func (m Network) IsContiguous() bool

IsContiguous reports whether the mask, in the network's own family, is a CIDR prefix mask: leading one bits followed only by zero bits.

For an IPv4 network the answer is that of Network4.IsContiguous, for an IPv6 network that of Network6.IsContiguous. The stored mask of an IPv4 network carries 96 leading ones above the 32 IPv4 mask bits, extending the leading run, so the 128-bit predicate of the stored form answers for both families without a branch. When the IPv4 mask is zero, the wrapped predecessor borrows one bit out of the pinned region and the or restores it, so the all-zero IPv4 mask still counts as contiguous.

func (Network) IsDisjoint

func (m Network) IsDisjoint(other Network) bool

IsDisjoint reports whether the two networks share no address.

Networks of different families are always disjoint. Within a family it is the logical complement of Intersects.

func (Network) LastAddr

func (m Network) LastAddr() netip.Addr

LastAddr returns the greatest address in this network, in the network's address family.

For an IPv4 network the result is an Is4 netip.Addr, for an IPv6 network an Is6 one, zone-free either way. The value is the family's greatest member: the broadcast address of a CIDR block, or the network address with every host bit set for a non-contiguous mask. It is computed once on the stored 128-bit form — the mapped mask of an IPv4 network pins the top 96 bits, so setting its host bits only touches the low 32 — and an IPv4 network merely unmaps the view.

func (Network) MarshalText

func (m Network) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

The text is the String form of the network in its own address family: an IPv4 network prints in dotted form even though it is stored IPv4-mapped, an IPv6 network prints compressed. It never fails and allocates only the returned slice.

func (Network) Mask

func (m Network) Mask() netip.Addr

Mask returns the network mask as a netip.Addr of the network's own family: Is4 for an IPv4 network, Is6 otherwise.

An IPv4 network answers with the unmapped view of the low 32 stored mask bits, the upper 96 being all ones by the mapped-storage invariant. A non-contiguous mask comes back verbatim.

func (Network) Merge

func (m Network) Merge(other Network) (Network, bool)

Merge returns the single network whose address set is the union of the two inputs, and false when no such network exists.

Networks of different families never merge. Within a family the result equals the corresponding Network4 or Network6 method and keeps the family of the inputs. On ok=false the returned value is the zero Network.

func (Network) MergeByLowestMaskBit

func (m Network) MergeByLowestMaskBit(other Network) (Network, bool)

MergeByLowestMaskBit merges two networks of the same family when one contains the other or when they are lowest-mask-bit siblings.

Networks of different families never merge and report false. Within a family the result and the flag are exactly those of the Network4 or Network6 method, and the result keeps the operands' family. On ok=false the returned value is the zero Network.

func (Network) NumHostBits

func (m Network) NumHostBits() int

NumHostBits returns the number of host bits, the zero bits of the mask, in the network's address family.

An IPv4 network reports a value in 0 through 32, an IPv6 network in 0 through 128. The network holds exactly 2 to the power of this value addresses. Both families are answered by the stored 128-bit mask without a branch: the mapped mask of an IPv4 network pins its top 96 bits as ones, so they contribute no host bits and the whole-word count is the family count.

func (Network) Prefix

func (m Network) Prefix() (netip.Prefix, bool)

Prefix returns the network as a netip.Prefix in its own family.

An IPv4 network yields an Is4 prefix with its 0 through 32 length, never the IPv4-mapped storage form, while an IPv4-mapped IPv6 network stays IPv6. ok is false when the mask is not contiguous, and the first result is then the invalid zero netip.Prefix. The returned prefix is already masked. The inverse of NetworkFromPrefix.

func (Network) PrefixLen

func (m Network) PrefixLen() (int, bool)

PrefixLen returns the family-native prefix length when the mask is contiguous.

For an IPv4 network the prefix is 0 through 32, for an IPv6 network 0 through 128, in both cases the number of leading one bits of the mask in that family. The second result is false for a non-contiguous mask, in which case the first result is 0. The stored mask of an IPv4 network carries the 96 mapped-range bits as leading ones above its 32 family bits, so the family length is the 128-bit length of the stored form minus that width.

func (Network) String

func (m Network) String() string

String returns the text form of the network, see AppendTo.

func (Network) SupernetFor

func (m Network) SupernetFor(nets []Network) (Network, bool)

SupernetFor returns the smallest network containing this network and every network in nets.

Any element of the other address family makes ok false: no network spans both families, so a mixed slice has no supernet and yields false rather than a silently narrowed answer. Within one family the result is exactly the Network4 or Network6 fold and keeps that family. An empty slice returns the network itself. On ok=false the returned value is the zero Network.

func (Network) ToCanonical

func (m Network) ToCanonical() Network

ToCanonical returns the network in its canonical address family.

An IPv4 network is returned unchanged. An IPv6 network that is IPv4-mapped (address ::ffff:a.b.c.d and a mask whose top 96 bits are all ones, see Network6.IsIPv4MappedIPv6) collapses to the equivalent IPv4 network, non-contiguous masks included. Any other IPv6 network, including IPv4-compatible ::a.b.c.d addresses and mapped addresses whose mask does not pin the top 96 bits, is returned unchanged. The inverse of ToIPv6Mapped on mapped values.

func (Network) ToContiguous

func (m Network) ToContiguous() Contiguous[Network]

ToContiguous returns the CIDR block whose mask is the leading run of one bits of this mask, keeping the address family.

See Network4.ToContiguous and Network6.ToContiguous for the per-family contract. An IPv4 network stays an IPv4 network. The exact, non-widening conversion is ContiguousFrom.

func (Network) ToIPv6Mapped

func (m Network) ToIPv6Mapped() Network6

ToIPv6Mapped embeds the network into IPv6 address space.

An IPv4 network is returned as its IPv4-mapped IPv6 network (address ::ffff:a.b.c.d, mask ffff:ffff:ffff:ffff:ffff:ffff:M). An IPv6 network is returned unchanged, so the result is not necessarily IPv4-mapped: any IPv6 network passes through as is. Lifting both operands of a dual-stack comparison this way makes containment and intersection, which are false across families, meaningful. Both arms return the stored network, which for the IPv4 arm already is the mapped image by the storage invariant.

func (*Network) UnmarshalText

func (m *Network) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

The text must be accepted by ParseNetwork, which detects the family from the address part, so a zone suffix is rejected and IPv4-mapped text stays IPv6. Empty text wraps ErrEmptyInput rather than yielding the zero value the way it yields the invalid zero netip.Prefix: the zero Network is the valid network ::/0, so empty text would silently hide a missing field. The receiver is untouched on any error.

type Network4

type Network4 struct {
	// contains filtered or unexported fields
}

Network4 is an IPv4 network: an address and a mask of arbitrary shape.

The mask need not be contiguous (255.0.255.0 is a valid mask). The address is always normalized, every bit outside the mask is zero, so two values describing the same address set compare equal with ==. The zero value is 0.0.0.0/0, the network of every IPv4 address. Values are immutable and safe to copy.

func Aggregate4

func Aggregate4(nets []Network4) []Network4

Aggregate4 collapses nets in place and returns the surviving prefix.

Duplicates are dropped, contained networks are absorbed and mergeable pairs are replaced by their merge until no pair merges: the address union of the result equals that of the input. The input order is destroyed (the slice is sorted first) and the tail beyond the returned prefix holds unspecified values, like slices.Compact. The output order is a deterministic function of the input but not guaranteed sorted, and for non-contiguous input the result is not guaranteed minimal. Works with non-contiguous masks.

func MustParseNetwork4

func MustParseNetwork4(s string) Network4

MustParseNetwork4 calls ParseNetwork4 and panics on error.

It is intended for tests and package-level constants built from literals.

func Network4From

func Network4From(addr, mask netip.Addr) (Network4, error)

Network4From returns the network with the given address and mask.

The address is normalized by the mask: 192.168.1.1/255.255.255.0 becomes 192.168.1.0/255.255.255.0 and 192.168.1.1/255.255.0.255 becomes 192.168.0.1/255.255.0.255. Any mask bit pattern is accepted. Both arguments must be Is4 addresses: an IPv6 address (IPv4-mapped included) or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch.

func Network4FromAddr

func Network4FromAddr(addr netip.Addr) (Network4, error)

Network4FromAddr returns the host route that contains exactly addr.

The mask is all ones (/32), so the result is normalized by construction and no address bit is cleared. addr must be Is4: an IPv6 address (IPv4-mapped included) or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch.

func Network4FromCIDR

func Network4FromCIDR(addr netip.Addr, bits int) (Network4, error)

Network4FromCIDR returns the network of addr with the top bits bits masked.

Host bits of addr are cleared: 192.168.1.5 with 24 gives 192.168.1.0/24, the same network netip.Prefix.Masked would report. The address must be Is4 — an IPv6 address, IPv4-mapped included, or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch — and bits must be in the range 0 through 32, otherwise ErrCIDROverflow is returned.

func Network4FromPrefix

func Network4FromPrefix(p netip.Prefix) (Network4, bool)

Network4FromPrefix converts a netip.Prefix into a Network4.

The result is normalized: host bits of the prefix address are cleared, the same network netip.Prefix.Masked would report. ok is false when the prefix is invalid or its address is not Is4 — an IPv4-mapped IPv6 prefix is IPv6, convert it through Network6FromPrefix instead. The inverse of Prefix.

func ParseNetwork4

func ParseNetwork4(s string) (Network4, error)

ParseNetwork4 parses an IPv4 network in CIDR, explicit-mask or bare address notation.

Accepted forms are "10.0.0.0/8", "10.0.0.0/255.0.0.0" (the mask may be non-contiguous, "10.0.0.0/255.0.255.0") and "10.0.0.1" (a host route, "/32"). The address is normalized under the mask, so "10.0.0.1/8" is the network "10.0.0.0/8". The prefix length after "/" is one or more decimal digits with no sign and no leading zero, at most 32. Errors wrap ErrAddrFamilyMismatch (an IPv6 literal), ErrCIDROverflow, ErrInvalidMask or, for text that is not an address in any form, ErrParse together with the net/netip cause.

func (Network4) Addr

func (m Network4) Addr() netip.Addr

Addr returns the network address (already normalized by the mask) as an Is4 netip.Addr.

func (Network4) Addrs

func (m Network4) Addrs() iter.Seq[netip.Addr]

Addrs returns every address of the network in host-index order.

The k host positions (mask bits that are zero) are filled with the successive values 0 through 2^k-1, least-significant host bit first. For a contiguous mask this is ascending numeric order from Addr() to LastAddr(). For a non-contiguous mask the numeric order of the yielded addresses differs from the iteration order. Every yielded address is an Is4 netip.Addr, zone-free. The sequence is re-iterable, allocation-free and stops early when the consumer breaks. The number of addresses is exactly 1 << NumHostBits().

func (Network4) AddrsBackward

func (m Network4) AddrsBackward() iter.Seq[netip.Addr]

AddrsBackward returns every address of the network in reverse host-index order, starting at LastAddr().

It yields exactly the addresses of Addrs in the opposite order, so for a contiguous mask this is descending numeric order from LastAddr() to Addr(). Every yielded address is an Is4 netip.Addr, zone-free. The sequence is re-iterable, allocation-free and stops early when the consumer breaks. The number of addresses is exactly 1 << NumHostBits().

func (Network4) AppendTo

func (m Network4) AppendTo(b []byte) []byte

AppendTo appends the text form of the network to b and returns the extended buffer.

A contiguous network is written as "addr/prefix", a non-contiguous one as "addr/mask" with the mask in dotted-decimal form. The suffix is always present, so a host route is written with "/32". The output parses back with ParseNetwork4.

func (Network4) Compare

func (m Network4) Compare(other Network4) int

Compare returns -1, 0 or +1 as m sorts before, equal to or after other.

The order is lexicographic on (address, mask), both compared as unsigned 32-bit integers: the address decides first and the mask breaks ties, so a container sorts before the networks nested under the same address. This order is a documented contract: it is the sort Aggregate4 applies before its greedy pass and the order BinarySplit4 expects of its input.

func (Network4) Contains

func (m Network4) Contains(other Network4) bool

Contains reports whether every address of other is also an address of m.

Two networks are compared as address sets: m contains other when other agrees with m on every bit position m constrains, and other constrains at least those positions. Identical networks contain each other, the universe 0.0.0.0/0 contains everything, a host route contains only itself. Masks may be non-contiguous.

func (Network4) ContainsAddr

func (m Network4) ContainsAddr(addr netip.Addr) bool

ContainsAddr reports whether addr is an address of this network.

The test is total, the netip.Prefix.Contains rule: an address that is not Is4 — an IPv6 address, IPv4-mapped included, or the invalid zero netip.Addr — is simply not contained. The mask may be non-contiguous: membership is agreement with the network address on every mask bit. Equivalent to Contains of the host route of addr, without the construction.

func (Network4) Difference

func (m Network4) Difference(other Network4) iter.Seq[Network4]

Difference returns the networks whose union is the set difference m \ other: every address of m that is not in other.

The parts are pairwise disjoint and masks may be non-contiguous. With d the mask bits fixed by the intersection but free in m, there are exactly popcount(d) parts when the two overlap, none when m is a subset of other, and m itself when they are disjoint — the minimum number of networks that can represent the difference. Parts are yielded from the most significant bit of d downwards, each mask adding one more bit of d. The sequence is allocation-free and re-iterable.

func (Network4) Intersection

func (m Network4) Intersection(other Network4) (Network4, bool)

Intersection returns the network of addresses common to m and other.

The intersection of two networks is always a single network: its mask is the union of both masks and its address the union of both addresses. ok is false when the networks are disjoint, which happens exactly when they disagree on a bit position both masks constrain. Masks may be non-contiguous. When one network contains the other the result is the contained one, and a network intersected with itself is itself.

func (Network4) Intersects

func (m Network4) Intersects(other Network4) bool

Intersects reports whether the two networks share at least one address.

Two networks intersect when their addresses agree on every bit that both masks constrain. The check is equivalent to Intersection returning ok, and holds for non-contiguous masks. A network always intersects itself and the unspecified network 0.0.0.0/0 intersects everything.

func (Network4) IsAdjacent

func (m Network4) IsAdjacent(other Network4) bool

IsAdjacent reports whether the two networks share a mask and differ in exactly one masked bit.

Adjacent networks merge into a single network by dropping the differing bit from the mask. Identical networks are not adjacent, and networks with different masks are never adjacent. The differing bit may sit anywhere in the mask, so merging two contiguous networks that are adjacent at a non-boundary bit yields a non-contiguous mask. Works with non-contiguous masks.

func (Network4) IsAdjacentByLowestMaskBit

func (m Network4) IsAdjacentByLowestMaskBit(other Network4) bool

IsAdjacentByLowestMaskBit reports whether the two networks share a mask and differ in exactly the lowest set bit of that mask.

It is the restriction of IsAdjacent to the boundary bit between a block and its parent: every pair accepted here is adjacent, but adjacency at any higher masked bit is rejected. Merging such a pair never leaves the mask's structural class, so two contiguous networks give a contiguous parent. Identical networks are not adjacent, and the unspecified network /0 is never adjacent to anything. For a two-run non-contiguous mask only the lower run's boundary bit counts. Works with non-contiguous masks.

func (Network4) IsContiguous

func (m Network4) IsContiguous() bool

IsContiguous reports whether the mask is a CIDR prefix mask: a run of leading one bits followed only by zero bits.

The all-zero mask (/0) and the all-ones mask (/32) are both contiguous. Any mask with a one bit after a zero bit, such as 255.0.255.0, is not.

func (Network4) IsDisjoint

func (m Network4) IsDisjoint(other Network4) bool

IsDisjoint reports whether the two networks share no address.

It is the logical complement of Intersects and holds the same guarantees for non-contiguous masks.

func (Network4) LastAddr

func (m Network4) LastAddr() netip.Addr

LastAddr returns the greatest address in this network.

For a contiguous network this is the broadcast address. For a non-contiguous mask it is the network address with every host bit set: masking that back yields the network address, so it is a member, and no member can set a bit the mask clears beyond all of them, so none is greater. Host bits need not form a trailing run for either fact to hold. The result is an Is4 netip.Addr.

func (Network4) MarshalText

func (m Network4) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

The text is the String form of the network: an address, "/" and either a prefix length (contiguous mask) or a dotted mask (non-contiguous mask). It never fails and allocates only the returned slice.

func (Network4) Mask

func (m Network4) Mask() netip.Addr

Mask returns the network mask as an Is4 netip.Addr.

func (Network4) Merge

func (m Network4) Merge(other Network4) (Network4, bool)

Merge returns the single network whose address set is the union of the two inputs, and false when no such network exists.

The union is a single network in exactly two cases: the masks are equal and the addresses differ in at most one bit (the result drops that bit from the mask, a duplicate merges to itself), or one network contains the other (the result is the larger one). The differing bit may be any masked bit, so merging two contiguous networks adjacent at a non-boundary bit yields a non-contiguous mask. Works with non-contiguous masks.

func (Network4) MergeByLowestMaskBit

func (m Network4) MergeByLowestMaskBit(other Network4) (Network4, bool)

MergeByLowestMaskBit merges two networks when one contains the other or when they are lowest-mask-bit siblings.

Exactly two disjoint cases merge and everything else reports false: containment returns the larger network, and a sibling pair sharing a mask and differing in precisely its lowest set bit returns the common address under that mask with the bit removed. Adjacency at any higher masked bit is refused even though Merge accepts it, so the result stays in the inputs' class — for a non-contiguous mask only the lowest run's boundary bit is a merge point. Whenever ok is true the result equals Merge's.

func (Network4) Network

func (m Network4) Network() Network

Network returns this IPv4 network as a Network.

func (Network4) NumHostBits

func (m Network4) NumHostBits() int

NumHostBits returns the number of host bits, the zero bits of the mask.

The network holds exactly 2 to the power of this value addresses, in any position the mask leaves free, so the count is carried exactly for every network including the default route. There is no separate address count: 2 to the 32 does not fit a uint32 and 2 to the 128 fits no integer, the exponent is the lossless form.

func (Network4) Prefix

func (m Network4) Prefix() (netip.Prefix, bool)

Prefix returns the network as a netip.Prefix.

ok is false when the mask is not contiguous, because netip.Prefix can only express prefix lengths, and the first result is then the invalid zero netip.Prefix. The returned prefix is already masked. The inverse of Network4FromPrefix.

func (Network4) PrefixLen

func (m Network4) PrefixLen() (int, bool)

PrefixLen returns the prefix length of the mask when the mask is contiguous.

The prefix is the number of leading one bits, 0 through 32. The second result is false for a non-contiguous mask, in which case no prefix length describes the network and the first result is 0.

func (Network4) String

func (m Network4) String() string

String returns the text form of the network, see AppendTo.

func (Network4) SupernetFor

func (m Network4) SupernetFor(nets []Network4) Network4

SupernetFor returns the smallest network containing this network and every network in nets.

The mask keeps exactly the bits that every input masks and on which every input's address agrees with this network's address, so the result is the greatest mask in the bitwise-subset order that still covers all inputs. An empty slice returns the network itself. The result may be non-contiguous even when every input is a CIDR block: addresses differing at a bit off their mask boundary leave a hole. Works with non-contiguous masks.

func (Network4) ToContiguous

func (m Network4) ToContiguous() Contiguous[Network4]

ToContiguous returns the CIDR block whose mask is the leading run of one bits of this mask, with the address normalized under it.

A contiguous network comes back wrapped unchanged. For a non-contiguous mask every one bit after the first zero bit is cleared, so the block is spanned by the leading run and contains every address of this network. The exact, non-widening conversion is ContiguousFrom.

func (Network4) ToIPv6Mapped

func (m Network4) ToIPv6Mapped() Network6

ToIPv6Mapped returns this network as an IPv4-mapped IPv6 network.

The address becomes ::ffff:a.b.c.d and the mask keeps the upper 96 bits set, so the result pins the mapped prefix and carries the IPv4 mask, contiguous or not, in its low 32 bits. Set relations are preserved: two IPv4 networks contain or intersect each other exactly when their mapped forms do. Network6.ToIPv4Mapped inverts it.

func (*Network4) UnmarshalText

func (m *Network4) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

The text must be accepted by ParseNetwork4. Empty text wraps ErrEmptyInput rather than yielding the zero value the way it yields the invalid zero netip.Prefix: the zero Network4 is the valid network 0.0.0.0/0, so empty text would silently hide a missing field. The receiver is untouched on any error.

type Network6

type Network6 struct {
	// contains filtered or unexported fields
}

Network6 is an IPv6 network: an address and a mask of arbitrary shape.

The mask need not be contiguous (ffff:0:ffff:: is a valid mask). The address is always normalized, every bit outside the mask is zero, so two values describing the same address set compare equal with ==. The zero value is ::/0, the network of every IPv6 address. Values are immutable and safe to copy.

func Aggregate6

func Aggregate6(nets []Network6) []Network6

Aggregate6 collapses nets in place and returns the surviving prefix.

Duplicates are dropped, contained networks are absorbed and mergeable pairs are replaced by their merge until no pair merges: the address union of the result equals that of the input. The input order is destroyed (the slice is sorted first) and the tail beyond the returned prefix holds unspecified values, like slices.Compact. The output order is a deterministic function of the input but not guaranteed sorted, and for non-contiguous input the result is not guaranteed minimal. Works with non-contiguous masks.

func MustParseNetwork6

func MustParseNetwork6(s string) Network6

MustParseNetwork6 calls ParseNetwork6 and panics on error.

It is intended for tests and package-level constants built from literals.

func Network6From

func Network6From(addr, mask netip.Addr) (Network6, error)

Network6From returns the network with the given address and mask.

The address is normalized by the mask: 2a02:6b8:c00:1:2:3:4:5/ffff:ffff:ff00:: becomes 2a02:6b8:c00::/ffff:ffff:ff00::. Any mask bit pattern is accepted. Both arguments must be Is6 addresses (an IPv4-mapped address is IPv6 and converts as its 16-byte form, a zone is dropped silently): an Is4 address or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch.

func Network6FromAddr

func Network6FromAddr(addr netip.Addr) (Network6, error)

Network6FromAddr returns the host route that contains exactly addr.

The mask is all ones (/128), so the result is normalized by construction and no address bit is cleared. addr must be Is6 (an IPv4-mapped address is IPv6, a zone is dropped silently): an Is4 address or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch.

func Network6FromCIDR

func Network6FromCIDR(addr netip.Addr, bits int) (Network6, error)

Network6FromCIDR returns the network of addr with the top bits bits masked.

Host bits of addr are cleared: 2001:db8::1 with 64 gives 2001:db8::/64, the same network netip.Prefix.Masked would report. The address must be Is6 (an IPv4-mapped address is IPv6 and converts as its 16-byte form, a zone is dropped silently) — an Is4 address or the invalid zero netip.Addr is rejected with ErrAddrFamilyMismatch — and bits must be in the range 0 through 128, otherwise ErrCIDROverflow is returned.

func Network6FromPrefix

func Network6FromPrefix(p netip.Prefix) (Network6, bool)

Network6FromPrefix converts a netip.Prefix into a Network6.

The result is normalized: host bits of the prefix address are cleared, the same network netip.Prefix.Masked would report. An IPv4-mapped IPv6 prefix (::ffff:a.b.c.d/n) is IPv6 and is accepted, and a zone never appears because netip.Prefix carries none. ok is false when the prefix is invalid or its address is Is4 — convert that one through Network4FromPrefix instead. The inverse of Prefix.

func ParseNetwork6

func ParseNetwork6(s string) (Network6, error)

ParseNetwork6 parses an IPv6 network in CIDR, explicit-mask or bare address notation.

Accepted forms are "2001:db8::/32", "2001:db8::/ffff:ffff::" (the mask may be non-contiguous) and "2001:db8::1" (a host route, "/128"). IPv4-mapped addresses such as "::ffff:192.0.2.1" are IPv6 here. The address is normalized under the mask. The prefix length after "/" is decimal digits with no sign and no leading zero, at most 128. A zone suffix ("%eth0") anywhere is an error. Errors wrap ErrZone, ErrAddrFamilyMismatch (an IPv4 literal), ErrCIDROverflow, ErrInvalidMask or ErrParse together with the net/netip cause.

func (Network6) Addr

func (m Network6) Addr() netip.Addr

Addr returns the network address (already normalized by the mask) as an Is6 netip.Addr.

func (Network6) Addrs

func (m Network6) Addrs() iter.Seq[netip.Addr]

Addrs returns every address of the network in host-index order.

The k host positions (mask bits that are zero) are filled with the successive values 0 through 2^k-1, least-significant host bit first. For a contiguous mask this is ascending numeric order from Addr() to LastAddr(), for a non-contiguous mask the numeric order differs from the iteration order. Every yielded address is an Is6 netip.Addr, zone-free. The sequence is re-iterable, allocation-free and stops early when the consumer breaks. The count is exactly 1 << NumHostBits(), which may exceed any integer type.

func (Network6) AddrsBackward

func (m Network6) AddrsBackward() iter.Seq[netip.Addr]

AddrsBackward returns every address of the network in reverse host-index order, starting at LastAddr().

It yields exactly the addresses of Addrs in the opposite order, so for a contiguous mask this is descending numeric order from LastAddr() to Addr(). Every yielded address is an Is6 netip.Addr, zone-free. The sequence is re-iterable, allocation-free and stops early when the consumer breaks. The number of addresses is exactly 1 << NumHostBits().

func (Network6) AppendTo

func (m Network6) AppendTo(b []byte) []byte

AppendTo appends the text form of the network to b and returns the extended buffer.

A contiguous network is written as "addr/prefix", a non-contiguous one as "addr/mask" with the mask in the same compressed form as an address. The suffix is always present, so a host route is written with "/128". The output parses back with ParseNetwork6.

func (Network6) Compare

func (m Network6) Compare(other Network6) int

Compare returns -1, 0 or +1 as m sorts before, equal to or after other.

The order is lexicographic on (address, mask), both compared as unsigned 128-bit integers: the address decides first and the mask breaks ties, so a container sorts before the networks nested under the same address. This order is a documented contract: it is the sort Aggregate6 applies before its greedy pass and the order BinarySplit6 expects of its input.

func (Network6) Contains

func (m Network6) Contains(other Network6) bool

Contains reports whether every address of other is also an address of m.

Two networks are compared as address sets: m contains other when other agrees with m on every bit position m constrains, and other constrains at least those positions. Identical networks contain each other, ::/0 contains everything, a host route contains only itself. Masks may be non-contiguous.

func (Network6) ContainsAddr

func (m Network6) ContainsAddr(addr netip.Addr) bool

ContainsAddr reports whether addr is an address of this network.

The test is total, the netip.Prefix.Contains rule: an address that is not Is6 — an Is4 address or the invalid zero netip.Addr — is simply not contained, and an address carrying a zone is not contained either. An IPv4-mapped address is IPv6 and is tested by its 16-byte form. The mask may be non-contiguous: membership is agreement with the network address on every mask bit. Equivalent to Contains of the host route of addr, without the construction.

func (Network6) Difference

func (m Network6) Difference(other Network6) iter.Seq[Network6]

Difference returns the networks whose union is the set difference m \ other: every address of m that is not in other.

The parts are pairwise disjoint and masks may be non-contiguous. With d the mask bits fixed by the intersection but free in m, there are exactly popcount(d) parts when the two overlap, none when m is a subset of other, and m itself when they are disjoint — the minimum number of networks that can represent the difference. Parts are yielded from the most significant bit of d downwards, each mask adding one more bit of d. The sequence is allocation-free and re-iterable.

func (Network6) Intersection

func (m Network6) Intersection(other Network6) (Network6, bool)

Intersection returns the network of addresses common to m and other.

The intersection of two networks is always a single network: its mask is the union of both masks and its address the union of both addresses. ok is false when the networks are disjoint, which happens exactly when they disagree on a bit position both masks constrain. Masks may be non-contiguous. When one network contains the other the result is the contained one, and a network intersected with itself is itself.

func (Network6) Intersects

func (m Network6) Intersects(other Network6) bool

Intersects reports whether the two networks share at least one address.

Two networks intersect when their addresses agree on every bit that both masks constrain. The check is equivalent to Intersection returning ok, and holds for non-contiguous masks. A network always intersects itself and the unspecified network ::/0 intersects everything.

func (Network6) IsAdjacent

func (m Network6) IsAdjacent(other Network6) bool

IsAdjacent reports whether the two networks share a mask and differ in exactly one masked bit.

Adjacent networks merge into a single network by dropping the differing bit from the mask. Identical networks are not adjacent, and networks with different masks are never adjacent. The differing bit may sit anywhere in the mask, so merging two contiguous networks that are adjacent at a non-boundary bit yields a non-contiguous mask. Works with non-contiguous masks.

func (Network6) IsAdjacentByLowestMaskBit

func (m Network6) IsAdjacentByLowestMaskBit(other Network6) bool

IsAdjacentByLowestMaskBit reports whether the two networks share a mask and differ in exactly the lowest set bit of that mask.

It is the restriction of IsAdjacent to the boundary bit between a block and its parent: every pair accepted here is adjacent, but adjacency at any higher masked bit is rejected. Merging such a pair never leaves the mask's structural class, so two contiguous networks give a contiguous parent. Identical networks are not adjacent, and the unspecified network /0 is never adjacent to anything. For a two-run non-contiguous mask only the lower run's boundary bit counts. Works with non-contiguous masks.

func (Network6) IsBicontiguous

func (m Network6) IsBicontiguous() bool

IsBicontiguous reports whether each 64-bit half of the mask is a run of leading ones on its own.

Such a mask describes a product of a high-half prefix and a low-half prefix, the shape of site-by-subnet classifiers. Every contiguous mask is bi-contiguous — its low half is all ones or all zeros — but the converse is false. The check uses the run-top property: a set bit whose upper neighbour is clear ends a maximal run of ones, and the mask is bi-contiguous exactly when every run ends at bit 127 or at bit 63, so clearing those two positions from the run tops must leave nothing.

func (Network6) IsContiguous

func (m Network6) IsContiguous() bool

IsContiguous reports whether the mask is a CIDR prefix mask: a run of leading one bits followed only by zero bits.

The all-zero mask (/0) and the all-ones mask (/128) are both contiguous. Any mask with a one bit after a zero bit, such as ffff:0:ffff::, is not. The formula is the 128-bit twin of the IPv4 one: or with the wrapped predecessor against all ones, with the subtraction borrowing across the 64-bit halves.

func (Network6) IsDisjoint

func (m Network6) IsDisjoint(other Network6) bool

IsDisjoint reports whether the two networks share no address.

It is the logical complement of Intersects and holds the same guarantees for non-contiguous masks.

func (Network6) IsIPv4MappedIPv6

func (m Network6) IsIPv4MappedIPv6() bool

IsIPv4MappedIPv6 reports whether this network is an IPv4-mapped IPv6 network.

True when the address lies in ::ffff:0:0/96 and the mask keeps all of those upper 96 bits, so the network is exactly the image of an IPv4 network under Network4.ToIPv6Mapped. An address with the ::ffff pattern under a mask that does not pin the upper bits is not mapped: collapsing it to IPv4 would lose addresses.

func (Network6) LastAddr

func (m Network6) LastAddr() netip.Addr

LastAddr returns the greatest address in this network.

For a contiguous network this is the last address of the CIDR block. For a non-contiguous mask it is the network address with every host bit set: masking that back yields the network address, so it is a member, and no member can set a bit the mask clears beyond all of them, so none is greater. Host bits need not form a trailing run for either fact to hold. The result is an Is6 netip.Addr, zone-free.

func (Network6) MarshalText

func (m Network6) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

The text is the String form of the network: a compressed address, "/" and either a prefix length (contiguous mask) or a colon-form mask (non-contiguous mask). It never fails and allocates only the returned slice.

func (Network6) Mask

func (m Network6) Mask() netip.Addr

Mask returns the network mask as an Is6 netip.Addr.

func (Network6) Merge

func (m Network6) Merge(other Network6) (Network6, bool)

Merge returns the single network whose address set is the union of the two inputs, and false when no such network exists.

The union is a single network in exactly two cases: the masks are equal and the addresses differ in at most one bit (the result drops that bit from the mask, a duplicate merges to itself), or one network contains the other (the result is the larger one). The differing bit may be any masked bit, so merging two contiguous networks adjacent at a non-boundary bit yields a non-contiguous mask. Works with non-contiguous masks.

func (Network6) MergeByLowestMaskBit

func (m Network6) MergeByLowestMaskBit(other Network6) (Network6, bool)

MergeByLowestMaskBit merges two networks when one contains the other or when they are lowest-mask-bit siblings.

Exactly two disjoint cases merge and everything else reports false: containment returns the larger network, and a sibling pair sharing a mask and differing in precisely its lowest set bit returns the common address under that mask with the bit removed. Adjacency at any higher masked bit is refused even though Merge accepts it, so the result stays in the inputs' class — for a non-contiguous mask only the lowest run's boundary bit is a merge point. Whenever ok is true the result equals Merge's.

func (Network6) Network

func (m Network6) Network() Network

Network returns this IPv6 network as a Network.

func (Network6) NumHostBits

func (m Network6) NumHostBits() int

NumHostBits returns the number of host bits, the zero bits of the mask.

The network holds exactly 2 to the power of this value addresses, in any position the mask leaves free, so the count is carried exactly for every network including the default route, whose 2 to the 128 members fit no integer type. The exponent is the lossless form and the only count the type offers.

func (Network6) Prefix

func (m Network6) Prefix() (netip.Prefix, bool)

Prefix returns the network as a netip.Prefix.

ok is false when the mask is not contiguous, because netip.Prefix can only express prefix lengths, and the first result is then the invalid zero netip.Prefix. The returned prefix is already masked and carries no zone. The inverse of Network6FromPrefix.

func (Network6) PrefixLen

func (m Network6) PrefixLen() (int, bool)

PrefixLen returns the prefix length of the mask when the mask is contiguous.

The prefix is the number of leading one bits, 0 through 128. The second result is false for a non-contiguous mask, in which case no prefix length describes the network and the first result is 0. An IPv4-mapped network reports its 128-bit length: the image of an IPv4 /24 is a /120 here.

func (Network6) String

func (m Network6) String() string

String returns the text form of the network, see AppendTo.

func (Network6) SupernetFor

func (m Network6) SupernetFor(nets []Network6) Network6

SupernetFor returns the smallest network containing this network and every network in nets.

The mask keeps exactly the bits that every input masks and on which every input's address agrees with this network's address, so the result is the greatest mask in the bitwise-subset order that still covers all inputs. An empty slice returns the network itself. The result may be non-contiguous even when every input is a CIDR block: addresses differing at a bit off their mask boundary leave a hole. Works with non-contiguous masks.

func (Network6) ToBiContiguous added in v0.1.1

func (m Network6) ToBiContiguous() BiContiguous

ToBiContiguous returns the smallest bi-contiguous network that contains this network.

Each mask half keeps its longest leading run of one bits and clears every later constrained bit. The address is normalized under the widened mask. A bi-contiguous network is returned wrapped unchanged; the exact, non-widening conversion is BiContiguousFrom6.

func (Network6) ToContiguous

func (m Network6) ToContiguous() Contiguous[Network6]

ToContiguous returns the CIDR block whose mask is the leading run of one bits of this mask, with the address normalized under it.

A contiguous network comes back wrapped unchanged. For a non-contiguous mask every one bit after the first zero bit is cleared, so the block is spanned by the leading run and contains every address of this network. The exact, non-widening conversion is ContiguousFrom.

func (Network6) ToIPv4Mapped

func (m Network6) ToIPv4Mapped() (Network4, bool)

ToIPv4Mapped returns the IPv4 network this IPv4-mapped IPv6 network encodes.

The result is the low 32 bits of the address and the mask, valid only when IsIPv4MappedIPv6 holds, otherwise ok is false. Truncation preserves normalization, because the upper 96 bits of a mapped network are fully masked. The inverse of Network4.ToIPv6Mapped.

func (*Network6) UnmarshalText

func (m *Network6) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

The text must be accepted by ParseNetwork6, so a zone suffix is rejected. Empty text wraps ErrEmptyInput rather than yielding the zero value the way it yields the invalid zero netip.Prefix: the zero Network6 is the valid network ::/0, so empty text would silently hide a missing field. The receiver is untouched on any error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL