network

package
v0.0.9-alpha Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2024 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Network ranges and IP address sets.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Adjacent

func Adjacent[A ip.Address[A]](r0, r1 AddressRange[A]) bool

Ranges are one element from overlap

func Contiguous

func Contiguous[A ip.Address[A]](r0, r1 AddressRange[A]) bool

Ranges either Intersect or are Adjacent

func Intersect

func Intersect[A ip.Address[A]](r0, r1 AddressRange[A]) bool

Ranges overlap in any way

Types

type AddressRange

type AddressRange[A ip.Address[A]] interface {
	AddressSet[A]
	// Least address
	First() A
	// Greatest address
	Last() A
}

Immutable contiguous range of one or more IP addresses.

func Join

func Join[A ip.Address[A]](r0, r1 AddressRange[A]) AddressRange[A]

Joins ranges using least and greatest elements. Ranges do not have to be contiguous.

func NewRange

func NewRange[A ip.Address[A]](first, last A) AddressRange[A]

Creates new AddressRange. Return value conforms to Block if possible.

type AddressSet

type AddressSet[A ip.Address[A]] interface {
	// Tests if address in set
	Contains(address A) bool
	// Number of unique addresses
	Size() *big.Int
	// Unique addresses from least to greatest
	Addresses() Iterator[A]
	// Non-contiguous ranges from least to greatest
	Ranges() Iterator[AddressRange[A]]
	// Informational only
	String() string
}

IP address set.

func NewSet

func NewSet[A ip.Address[A]](ranges ...AddressRange[A]) AddressSet[A]

Creates AddressSet from given IP address ranges. Ranges may overlap. If set reduces to contiguous range returns type that conforms to AddressRange.

Example
package main

import (
	"github.com/ipfreely-uk/go/ip"
	"github.com/ipfreely-uk/go/ip/network"
)

func main() {
	family := ip.V4()
	r0 := exampleRange(family, "192.0.2.0", "192.0.2.100")
	r1 := exampleRange(family, "192.0.2.101", "192.0.2.111")
	r2 := exampleRange(family, "192.0.2.200", "192.0.2.255")
	r3 := exampleRange(family, "203.0.113.0", "203.0.113.255")
	r4 := exampleRange(family, "192.0.2.0", "192.0.2.100")

	addresses := network.NewSet(r0, r1, r2, r3, r4)

	println("Rationalized ranges:")
	next := addresses.Ranges()
	for aRange, exists := next(); exists; aRange, exists = next() {
		println(aRange.String())
	}
}

func exampleRange[A ip.Address[A]](family ip.Family[A], first, last string) network.AddressRange[A] {
	a0 := ip.MustParse(family, first)
	a1 := ip.MustParse(family, last)
	return network.NewRange(a0, a1)
}
Output:

type Block

type Block[A ip.Address[A]] interface {
	AddressRange[A]
	// Mask size in bits
	MaskSize() int
	// Mask as [ip.Address]
	Mask() A
}

Immutable RFC-4632 CIDR block.

Example
package main

import (
	"crypto/rand"

	"github.com/ipfreely-uk/go/ip"
	"github.com/ipfreely-uk/go/ip/network"
)

func main() {
	netAddress := ip.MustParse(ip.V6(), "2001:db8:cafe::")
	block := network.NewBlock(netAddress, 56)

	randomAddr := randomAddressFrom(block)

	println("Random address from", block.String(), "=", randomAddr.String())
}

func randomAddressFrom[A ip.Address[A]](netBlock network.Block[A]) A {
	netAddr := netBlock.First()
	family := netAddr.Family()
	r := randomAddress(family)

	iMask := netBlock.Mask().Not()

	return r.Or(iMask).Or(netAddr)
}

func randomAddress[A ip.Address[A]](f ip.Family[A]) A {
	slice := make([]byte, f.Width()/8)
	_, _ = rand.Read(slice)
	return f.MustFromBytes(slice...)
}
Output:

func NewBlock

func NewBlock[A ip.Address[A]](network A, mask int) Block[A]

Creates Block. Panics if mask does not cover network address or is out of range for address family.

Example
package main

import (
	humanize "github.com/dustin/go-humanize"
	"github.com/ipfreely-uk/go/ip"
	"github.com/ipfreely-uk/go/ip/network"
)

func main() {
	netAddress := ip.MustParse(ip.V6(), "2001:db8::")

	block := network.NewBlock(netAddress, 32)

	println("Block", block.String())
	println("First", block.First().String())
	println("Last", block.Last().String())
	println("Size", humanize.BigComma(block.Size()))
}
Output:

type Iterator

type Iterator[E any] func() (E, bool)

Iterator function that returns whether element returned and element

Example
package main

import (
	"github.com/ipfreely-uk/go/ip"
	"github.com/ipfreely-uk/go/ip/network"
)

func main() {
	first := ip.V4().MustFromBytes(192, 168, 0, 1)
	last := ip.V4().MustFromBytes(192, 168, 0, 254)
	assignable := network.NewRange(first, last)

	// iterator of addresses
	next := assignable.Addresses()
	for address, exists := next(); exists; address, exists = next() {
		println(address.String())
	}
}
Output:

func Blocks

func Blocks[A ip.Address[A]](r AddressRange[A]) Iterator[Block[A]]

Subdivides [Range] into valid CIDR blocks

Example
package main

import (
	"github.com/ipfreely-uk/go/ip"
	"github.com/ipfreely-uk/go/ip/network"
)

func main() {
	first := ip.V4().MustFromBytes(192, 0, 2, 101)
	last := ip.V4().MustFromBytes(192, 0, 2, 240)
	freeAddresses := network.NewRange(first, last)

	printCidrBlocksIn(freeAddresses)
}

func printCidrBlocksIn[A ip.Address[A]](addressRange network.AddressRange[A]) {
	next := network.Blocks(addressRange)
	for block, exists := next(); exists; block, exists = next() {
		println(block.String())
	}
}
Output:

Directories

Path Synopsis
RFC-4632 Classless Inter-domain Routing notation handling https://www.rfc-editor.org/rfc/rfc4632
RFC-4632 Classless Inter-domain Routing notation handling https://www.rfc-editor.org/rfc/rfc4632

Jump to

Keyboard shortcuts

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