isle/go/nebula/ip_net.go

54 lines
1.1 KiB
Go

package nebula
import (
"fmt"
"net"
"net/netip"
"testing"
)
// IPNet is the CIDR of a nebula network.
type IPNet net.IPNet
// MustParseIPNet is a test helper for parsing a string into an IPNet.
func MustParseIPNet(t *testing.T, str string) IPNet {
var ipNet IPNet
if err := ipNet.UnmarshalText([]byte(str)); err != nil {
t.Fatal(err)
}
return ipNet
}
// UnmarshalText parses and validates an IPNet from a text string.
func (n *IPNet) UnmarshalText(b []byte) error {
str := string(b)
_, subnet, err := net.ParseCIDR(str)
if err != nil {
return err
}
if cstr := subnet.String(); cstr != str {
return fmt.Errorf("IPNet is not given in its canonical form of %q", cstr)
}
if !subnet.IP.IsPrivate() {
return fmt.Errorf("IPNet is not in a private IP range")
}
*n = IPNet(*subnet)
return nil
}
func (n IPNet) String() string {
return (*net.IPNet)(&n).String()
}
func (n IPNet) MarshalText() ([]byte, error) {
return []byte(n.String()), nil
}
// FirstAddr returns the first IP address in the subnet.
func (n IPNet) FirstAddr() netip.Addr {
return netip.MustParseAddr(n.IP.String()).Next()
}