netaddr

package module
v0.0.0-...-b8eac61 Latest Latest
Warning

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

Go to latest
Published: May 25, 2023 License: BSD-3-Clause Imports: 11 Imported by: 203

README

netaddr Test Status Go Reference

Deprecated

Please see https://pkg.go.dev/go4.org/netipx and the standard library's net/netip.

What

This is a package containing a new IP address type for Go.

See its docs: https://pkg.go.dev/inet.af/netaddr

Status

This package is mature, optimized, and used heavily in production at Tailscale. However, API stability is not yet guaranteed.

netaddr is intended to be a core, low-level package. We take code review, testing, dependencies, and performance seriously, similar to Go's standard library or the golang.org/x repos.

Motivation

See https://tailscale.com/blog/netaddr-new-ip-type-for-go/ for a long blog post about why we made a new IP address package.

Other links:

Testing

In addition to regular Go tests, netaddr uses fuzzing. The corpus is stored separately, in a submodule, to minimize the impact on everyone else.

To use:

$ git submodule update --init
$ go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-build
$ go-fuzz-build && go-fuzz

Documentation

Overview

Package netaddr contains a IP address type that's in many ways better than the Go standard library's net.IP type. Building on that IP type, the package also contains IPPrefix, IPPort, IPRange, and IPSet types.

Notably, this package's IP type takes less memory, is immutable, comparable (supports == and being a map key), and more. See https://github.com/inetaf/netaddr for background.

IPv6 Zones

IP and IPPort are the only types in this package that support IPv6 zones. Other types silently drop any passed-in zones.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type IP

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

IP represents an IPv4 or IPv6 address (with or without a scoped addressing zone), similar to Go's net.IP or net.IPAddr.

Unlike net.IP or net.IPAddr, the netaddr.IP is a comparable value type (it supports == and can be a map key) and is immutable. Its memory representation is 24 bytes on 64-bit machines (the same size as a Go slice header) for both IPv4 and IPv6 address.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	ip, err := netaddr.ParseIP("192.0.2.3")
	if err != nil {
		panic(err)
	}

	// netaddr.IP supports comparison using ==
	fmt.Println(ip == netaddr.IPv4(192, 0, 2, 3))

	// netaddr.IP can be used as a map key
	hosts := map[netaddr.IP]string{ip: "example.net"}
	fmt.Println(hosts)
}
Output:

true
map[192.0.2.3:example.net]
Example (Properties)
package main

import (
	"fmt"
	"os"
	"text/tabwriter"

	"inet.af/netaddr"
)

func main() {
	var zeroIP netaddr.IP
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
	fmt.Fprintln(w, "String()\tZone()\tIsZero()\tIs4()\tIs6()\tIs4in6()")
	for _, ip := range []netaddr.IP{
		zeroIP,
		netaddr.MustParseIP("192.0.2.3"),
		netaddr.MustParseIP("2001:db8::68"),
		netaddr.MustParseIP("2001:db8::68%eth0"),
		netaddr.MustParseIP("::ffff:192.0.2.3"),
	} {
		fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\n", ip, ip.Zone(), ip.IsZero(), ip.Is4(), ip.Is6(), ip.Is4in6())
	}
	w.Flush()
}
Output:

String()           Zone()  IsZero()  Is4()  Is6()  Is4in6()
zero IP                    true      false  false  false
192.0.2.3                  false     true   false  false
2001:db8::68               false     false  true   false
2001:db8::68%eth0  eth0    false     false  true   false
::ffff:c000:203            false     false  true   true

func FromStdIP

func FromStdIP(std net.IP) (ip IP, ok bool)

FromStdIP returns an IP from the standard library's IP type.

If std is invalid, ok is false.

FromStdIP implicitly unmaps IPv6-mapped IPv4 addresses. That is, if len(std) == 16 and contains an IPv4 address, only the IPv4 part is returned, without the IPv6 wrapper. This is the common form returned by the standard library's ParseIP: https://play.golang.org/p/qdjylUkKWxl. To convert a standard library IP without the implicit unmapping, use FromStdIPRaw.

func FromStdIPRaw

func FromStdIPRaw(std net.IP) (ip IP, ok bool)

FromStdIPRaw returns an IP from the standard library's IP type. If std is invalid, ok is false. Unlike FromStdIP, FromStdIPRaw does not do an implicit Unmap if len(std) == 16 and contains an IPv6-mapped IPv4 address.

func IPFrom16

func IPFrom16(addr [16]byte) IP

IPFrom16 returns the IP address given by the bytes in addr, unmapping any v6-mapped IPv4 address.

It is equivalent to calling IPv6Raw(addr).Unmap().

func IPFrom4

func IPFrom4(addr [4]byte) IP

IPFrom4 returns the IPv4 address given by the bytes in addr. It is equivalent to calling IPv4(addr[0], addr[1], addr[2], addr[3]).

func IPv4

func IPv4(a, b, c, d uint8) IP

IPv4 returns the IP of the IPv4 address a.b.c.d.

func IPv6LinkLocalAllNodes

func IPv6LinkLocalAllNodes() IP

IPv6LinkLocalAllNodes returns the IPv6 link-local all nodes multicast address ff02::1.

func IPv6Raw

func IPv6Raw(addr [16]byte) IP

IPv6Raw returns the IPv6 address given by the bytes in addr, without an implicit Unmap call to unmap any v6-mapped IPv4 address.

func IPv6Unspecified

func IPv6Unspecified() IP

IPv6Unspecified returns the IPv6 unspecified address ::.

func MustParseIP

func MustParseIP(s string) IP

MustParseIP calls ParseIP(s) and panics on error. It is intended for use in tests with hard-coded strings.

func ParseIP

func ParseIP(s string) (IP, error)

ParseIP parses s as an IP address, returning the result. The string s can be in dotted decimal ("192.0.2.1"), IPv6 ("2001:db8::68"), or IPv6 with a scoped addressing zone ("fe80::1cc0:3e8c:119f:c2e1%ens18").

func (IP) AppendTo

func (ip IP) AppendTo(b []byte) []byte

AppendTo appends a text encoding of ip, as generated by MarshalText, to b and returns the extended buffer.

func (IP) As16

func (ip IP) As16() [16]byte

As16 returns the IP address in its 16 byte representation. IPv4 addresses are returned in their v6-mapped form. IPv6 addresses with zones are returned without their zone (use the Zone method to get it). The ip zero value returns all zeroes.

func (IP) As4

func (ip IP) As4() [4]byte

As4 returns an IPv4 or IPv4-in-IPv6 address in its 4 byte representation. If ip is the IP zero value or an IPv6 address, As4 panics. Note that 0.0.0.0 is not the zero value.

func (IP) BitLen

func (ip IP) BitLen() uint8

BitLen returns the number of bits in the IP address: 32 for IPv4 or 128 for IPv6. For the zero value (see IP.IsZero), it returns 0. For IP4-mapped IPv6 addresses, it returns 128.

func (IP) Compare

func (ip IP) Compare(ip2 IP) int

Compare returns an integer comparing two IPs. The result will be 0 if ip==ip2, -1 if ip < ip2, and +1 if ip > ip2. The definition of "less than" is the same as the IP.Less method.

func (IP) IPAddr

func (ip IP) IPAddr() *net.IPAddr

IPAddr returns the net.IPAddr representation of an IP. The returned value is always non-nil, but the IPAddr.IP will be nil if ip is the zero value. If ip contains a zone identifier, IPAddr.Zone is populated.

func (IP) Is4

func (ip IP) Is4() bool

Is4 reports whether ip is an IPv4 address.

It returns false for IP4-mapped IPv6 addresses. See IP.Unmap.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var zeroIP netaddr.IP
	ipv4 := netaddr.MustParseIP("192.0.2.3")
	ipv6 := netaddr.MustParseIP("2001:db8::68")
	ip4in6 := netaddr.MustParseIP("::ffff:192.0.2.3")

	fmt.Printf("IP{}.Is4() -> %v\n", zeroIP.Is4())
	fmt.Printf("(%v).Is4() -> %v\n", ipv4, ipv4.Is4())
	fmt.Printf("(%v).Is4() -> %v\n", ipv6, ipv6.Is4())
	fmt.Printf("(%v).Is4() -> %v\n", ip4in6, ip4in6.Is4())
}
Output:

IP{}.Is4() -> false
(192.0.2.3).Is4() -> true
(2001:db8::68).Is4() -> false
(::ffff:c000:203).Is4() -> false

func (IP) Is4in6

func (ip IP) Is4in6() bool

Is4in6 reports whether ip is an IPv4-mapped IPv6 address.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var zeroIP netaddr.IP
	ipv4 := netaddr.MustParseIP("192.0.2.3")
	ipv6 := netaddr.MustParseIP("2001:db8::68")
	ip4in6 := netaddr.MustParseIP("::ffff:192.0.2.3")

	fmt.Printf("IP{}.Is4in6() -> %v\n", zeroIP.Is4in6())
	fmt.Printf("(%v).Is4in6() -> %v\n", ipv4, ipv4.Is4in6())
	fmt.Printf("(%v).Is4in6() -> %v\n", ipv6, ipv6.Is4in6())
	fmt.Printf("(%v).Is4in6() -> %v\n", ip4in6, ip4in6.Is4in6())
}
Output:

IP{}.Is4in6() -> false
(192.0.2.3).Is4in6() -> false
(2001:db8::68).Is4in6() -> false
(::ffff:c000:203).Is4in6() -> true

func (IP) Is6

func (ip IP) Is6() bool

Is6 reports whether ip is an IPv6 address, including IPv4-mapped IPv6 addresses.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var zeroIP netaddr.IP
	ipv4 := netaddr.MustParseIP("192.0.2.3")
	ipv6 := netaddr.MustParseIP("2001:db8::68")
	ip4in6 := netaddr.MustParseIP("::ffff:192.0.2.3")

	fmt.Printf("IP{}.Is6() -> %v\n", zeroIP.Is4in6())
	fmt.Printf("(%v).Is6() -> %v\n", ipv4, ipv4.Is6())
	fmt.Printf("(%v).Is6() -> %v\n", ipv6, ipv6.Is6())
	fmt.Printf("(%v).Is6() -> %v\n", ip4in6, ip4in6.Is6())
}
Output:

IP{}.Is6() -> false
(192.0.2.3).Is6() -> false
(2001:db8::68).Is6() -> true
(::ffff:c000:203).Is6() -> true

func (IP) IsGlobalUnicast

func (ip IP) IsGlobalUnicast() bool

IsGlobalUnicast reports whether ip is a global unicast address.

It returns true for IPv6 addresses which fall outside of the current IANA-allocated 2000::/3 global unicast space, with the exception of the link-local address space. It also returns true even if ip is in the IPv4 private address space or IPv6 unique local address space. If ip is the zero value, it will return false.

For reference, see RFC 1122, RFC 4291, and RFC 4632.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var (
		zeroIP netaddr.IP

		ipv4AllZeroes = netaddr.MustParseIP("0.0.0.0")
		ipv4          = netaddr.MustParseIP("192.0.2.3")

		ipv6AllZeroes  = netaddr.MustParseIP("::")
		ipv6LinkLocal  = netaddr.MustParseIP("fe80::1")
		ipv6           = netaddr.MustParseIP("2001:db8::68")
		ipv6Unassigned = netaddr.MustParseIP("4000::1")
		ip4in6         = netaddr.MustParseIP("::ffff:192.0.2.3")
	)

	fmt.Printf("IP{}.IsGlobalUnicast() -> %v\n", zeroIP.IsGlobalUnicast())

	ips := []netaddr.IP{
		ipv4AllZeroes,
		ipv4,
		ipv6AllZeroes,
		ipv6LinkLocal,
		ipv6,
		ipv6Unassigned,
		ip4in6,
	}

	for _, ip := range ips {
		fmt.Printf("(%v).IsGlobalUnicast() -> %v\n", ip, ip.IsGlobalUnicast())
	}
}
Output:

IP{}.IsGlobalUnicast() -> false
(0.0.0.0).IsGlobalUnicast() -> false
(192.0.2.3).IsGlobalUnicast() -> true
(::).IsGlobalUnicast() -> false
(fe80::1).IsGlobalUnicast() -> false
(2001:db8::68).IsGlobalUnicast() -> true
(4000::1).IsGlobalUnicast() -> true
(::ffff:c000:203).IsGlobalUnicast() -> true

func (IP) IsInterfaceLocalMulticast

func (ip IP) IsInterfaceLocalMulticast() bool

IsInterfaceLocalMulticast reports whether ip is an IPv6 interface-local multicast address. If ip is the zero value or an IPv4 address, it will return false.

func (IP) IsLinkLocalMulticast

func (ip IP) IsLinkLocalMulticast() bool

IsLinkLocalMulticast reports whether ip is a link-local multicast address. If ip is the zero value, it will return false.

func (IP) IsLinkLocalUnicast

func (ip IP) IsLinkLocalUnicast() bool

IsLinkLocalUnicast reports whether ip is a link-local unicast address. If ip is the zero value, it will return false.

func (IP) IsLoopback

func (ip IP) IsLoopback() bool

IsLoopback reports whether ip is a loopback address. If ip is the zero value, it will return false.

func (IP) IsMulticast

func (ip IP) IsMulticast() bool

IsMulticast reports whether ip is a multicast address. If ip is the zero value, it will return false.

func (IP) IsPrivate

func (ip IP) IsPrivate() bool

IsPrivate reports whether ip is a private address, according to RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses). That is, it reports whether ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the same as the standard library's net.IP.IsPrivate.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var (
		zeroIP netaddr.IP

		ipv4        = netaddr.MustParseIP("192.0.2.3")
		ipv4Private = netaddr.MustParseIP("192.168.1.1")

		ipv6        = netaddr.MustParseIP("2001:db8::68")
		ipv6Private = netaddr.MustParseIP("fd00::1")
	)

	fmt.Printf("IP{}.IsPrivate() -> %v\n", zeroIP.IsPrivate())

	ips := []netaddr.IP{
		ipv4,
		ipv4Private,
		ipv6,
		ipv6Private,
	}

	for _, ip := range ips {
		fmt.Printf("(%v).IsPrivate() -> %v\n", ip, ip.IsPrivate())
	}
}
Output:

IP{}.IsPrivate() -> false
(192.0.2.3).IsPrivate() -> false
(192.168.1.1).IsPrivate() -> true
(2001:db8::68).IsPrivate() -> false
(fd00::1).IsPrivate() -> true

func (IP) IsUnspecified

func (ip IP) IsUnspecified() bool

IsUnspecified reports whether ip is an unspecified address, either the IPv4 address "0.0.0.0" or the IPv6 address "::".

Note that the IP zero value is not an unspecified address. Use IsZero to check for the zero value instead.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var zeroIP netaddr.IP
	ipv4AllZeroes := netaddr.MustParseIP("0.0.0.0")
	ipv6AllZeroes := netaddr.MustParseIP("::")

	fmt.Printf("IP{}.IsUnspecified() -> %v\n", zeroIP.IsUnspecified())
	fmt.Printf("(%v).IsUnspecified() -> %v\n", ipv4AllZeroes, ipv4AllZeroes.IsUnspecified())
	fmt.Printf("(%v).IsUnspecified() -> %v\n", ipv6AllZeroes, ipv6AllZeroes.IsUnspecified())
}
Output:

IP{}.IsUnspecified() -> false
(0.0.0.0).IsUnspecified() -> true
(::).IsUnspecified() -> true

func (IP) IsValid

func (ip IP) IsValid() bool

IsValid whether the IP is an initialized value and not the IP type's zero value.

Note that both "0.0.0.0" and "::" are valid, non-zero values.

func (IP) IsZero

func (ip IP) IsZero() bool

IsZero reports whether ip is the zero value of the IP type. The zero value is not a valid IP address of any type.

Note that "0.0.0.0" and "::" are not the zero value. Use IsUnspecified to check for these values instead.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var zeroIP netaddr.IP
	ipv4AllZeroes := netaddr.MustParseIP("0.0.0.0")
	ipv6AllZeroes := netaddr.MustParseIP("::")

	fmt.Printf("IP{}.IsZero() -> %v\n", zeroIP.IsZero())
	fmt.Printf("(%v).IsZero() -> %v\n", ipv4AllZeroes, ipv4AllZeroes.IsZero())
	fmt.Printf("(%v).IsZero() -> %v\n", ipv6AllZeroes, ipv6AllZeroes.IsZero())
}
Output:

IP{}.IsZero() -> true
(0.0.0.0).IsZero() -> false
(::).IsZero() -> false

func (IP) Less

func (ip IP) Less(ip2 IP) bool

Less reports whether ip sorts before ip2. IP addresses sort first by length, then their address. IPv6 addresses with zones sort just after the same address without a zone.

func (IP) MarshalBinary

func (ip IP) MarshalBinary() ([]byte, error)

MarshalBinary implements the encoding.BinaryMarshaler interface.

func (IP) MarshalText

func (ip IP) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface, The encoding is the same as returned by String, with one exception: If ip is the zero value, the encoding is the empty string.

func (IP) Netmask

func (ip IP) Netmask(mask []byte) (IPPrefix, error)

Netmask applies a bit mask to IP, producing an IPPrefix. If IP is the zero value, a zero-value IPPrefix and a nil error are returned. If the netmask length is not 4 for IPv4 or 16 for IPv6, an error is returned. If the netmask is non-contiguous, an error is returned.

func (IP) Next

func (ip IP) Next() IP

Next returns the IP following ip. If there is none, it returns the IP zero value.

func (IP) Prefix

func (ip IP) Prefix(bits uint8) (IPPrefix, error)

Prefix applies a CIDR mask of leading bits to IP, producing an IPPrefix of the specified length. If IP is the zero value, a zero-value IPPrefix and a nil error are returned. If bits is larger than 32 for an IPv4 address or 128 for an IPv6 address, an error is returned.

func (IP) Prior

func (ip IP) Prior() IP

Prior returns the IP before ip. If there is none, it returns the IP zero value.

func (IP) String

func (ip IP) String() string

String returns the string form of the IP address ip. It returns one of 4 forms:

  • "invalid IP", if ip is the zero value
  • IPv4 dotted decimal ("192.0.2.1")
  • IPv6 ("2001:db8::1")
  • IPv6 with zone ("fe80:db8::1%eth0")

Note that unlike the Go standard library's IP.String method, IP4-mapped IPv6 addresses do not format as dotted decimals.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	ipv4 := netaddr.MustParseIP("192.0.2.3")
	ipv6 := netaddr.MustParseIP("2001:db8::68")
	ip4in6 := netaddr.MustParseIP("::ffff:192.0.2.3")

	fmt.Printf("(%v).String() -> %v\n", ipv4, ipv4.String())
	fmt.Printf("(%v).String() -> %v\n", ipv6, ipv6.String())
	fmt.Printf("(%v).String() -> %v\n", ip4in6, ip4in6.String())
}
Output:

(192.0.2.3).String() -> 192.0.2.3
(2001:db8::68).String() -> 2001:db8::68
(::ffff:c000:203).String() -> ::ffff:c000:203

func (IP) StringExpanded

func (ip IP) StringExpanded() string

StringExpanded is like String but IPv6 addresses are expanded with leading zeroes and no "::" compression. For example, "2001:db8::1" becomes "2001:0db8:0000:0000:0000:0000:0000:0001".

func (IP) Unmap

func (ip IP) Unmap() IP

Unmap returns ip with any IPv4-mapped IPv6 address prefix removed.

That is, if ip is an IPv6 address wrapping an IPv4 adddress, it returns the wrapped IPv4 address. Otherwise it returns ip, regardless of its type.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	ipv4 := netaddr.MustParseIP("192.0.2.3")
	ipv6 := netaddr.MustParseIP("2001:db8::68")
	ip4in6 := netaddr.MustParseIP("::ffff:192.0.2.3")

	fmt.Printf("(%v).Unmap() -> %v\n", ipv4, ipv4.Unmap())
	fmt.Printf("(%v).Unmap() -> %v\n", ipv6, ipv6.Unmap())
	fmt.Printf("(%v).Unmap() -> %v\n", ip4in6, ip4in6.Unmap())
}
Output:

(192.0.2.3).Unmap() -> 192.0.2.3
(2001:db8::68).Unmap() -> 2001:db8::68
(::ffff:c000:203).Unmap() -> 192.0.2.3

func (*IP) UnmarshalBinary

func (ip *IP) UnmarshalBinary(b []byte) error

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.

func (*IP) UnmarshalText

func (ip *IP) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface. The IP address is expected in a form accepted by ParseIP. It returns an error if *ip is not the IP zero value.

func (IP) WithZone

func (ip IP) WithZone(zone string) IP

WithZone returns an IP that's the same as ip but with the provided zone. If zone is empty, the zone is removed. If ip is an IPv4 address it's returned unchanged.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	ipv4 := netaddr.MustParseIP("192.0.2.3")
	ipv6 := netaddr.MustParseIP("2001:db8::68")
	ipv6Zoned := netaddr.MustParseIP("2001:db8::68%eth0")

	fmt.Printf("(%v).WithZone(\"newzone\") -> %v\n", ipv4, ipv4.WithZone("newzone"))
	fmt.Printf("(%v).WithZone(\"newzone\") -> %v\n", ipv6, ipv6.WithZone("newzone"))
	fmt.Printf("(%v).WithZone(\"newzone\") -> %v\n", ipv6Zoned, ipv6Zoned.WithZone("newzone"))
	fmt.Printf("(%v).WithZone(\"\") -> %v\n", ipv6Zoned, ipv6Zoned.WithZone(""))
}
Output:

(192.0.2.3).WithZone("newzone") -> 192.0.2.3
(2001:db8::68).WithZone("newzone") -> 2001:db8::68%newzone
(2001:db8::68%eth0).WithZone("newzone") -> 2001:db8::68%newzone
(2001:db8::68%eth0).WithZone("") -> 2001:db8::68

func (IP) Zone

func (ip IP) Zone() string

Zone returns ip's IPv6 scoped addressing zone, if any.

type IPPort

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

IPPort is an IP and a port number.

func FromStdAddr

func FromStdAddr(stdIP net.IP, port int, zone string) (_ IPPort, ok bool)

FromStdAddr maps the components of a standard library TCPAddr or UDPAddr into an IPPort.

func IPPortFrom

func IPPortFrom(ip IP, port uint16) IPPort

IPPortFrom returns an IPPort with IP ip and port port. It does not allocate.

func MustParseIPPort

func MustParseIPPort(s string) IPPort

MustParseIPPort calls ParseIPPort(s) and panics on error. It is intended for use in tests with hard-coded strings.

func ParseIPPort

func ParseIPPort(s string) (IPPort, error)

ParseIPPort parses s as an IPPort.

It doesn't do any name resolution, and ports must be numeric.

func (IPPort) AppendTo

func (p IPPort) AppendTo(b []byte) []byte

AppendTo appends a text encoding of p, as generated by MarshalText, to b and returns the extended buffer.

func (IPPort) IP

func (p IPPort) IP() IP

IP returns p's IP.

func (IPPort) IsValid

func (p IPPort) IsValid() bool

IsValid reports whether p.IP() is valid. All ports are valid, including zero.

func (IPPort) IsZero

func (p IPPort) IsZero() bool

IsZero reports whether p is its zero value.

func (IPPort) MarshalText

func (p IPPort) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface. The encoding is the same as returned by String, with one exception: if p.IP() is the zero value, the encoding is the empty string.

func (IPPort) Port

func (p IPPort) Port() uint16

Port returns p's port.

func (IPPort) String

func (p IPPort) String() string

func (IPPort) TCPAddr

func (p IPPort) TCPAddr() *net.TCPAddr

TCPAddr returns a standard library net.TCPAddr from p. The returned value is always non-nil. If p.IP() is the zero value, then TCPAddr.IP is nil.

func (IPPort) UDPAddr

func (p IPPort) UDPAddr() *net.UDPAddr

UDPAddr returns a standard library net.UDPAddr from p. The returned value is always non-nil. If p.IP() is the zero value, then UDPAddr.IP is nil.

UDPAddr necessarily does two allocations. If you have an existing UDPAddr already allocated, see UDPAddrAt.

func (IPPort) UDPAddrAt

func (p IPPort) UDPAddrAt(at *net.UDPAddr) *net.UDPAddr

UDPAddrAt is like UDPAddr, but reuses the provided UDPAddr, which must be non-nil. If at.IP has a capacity of 16, UDPAddrAt is allocation-free. It returns at to facilitate using this method as a wrapper.

func (*IPPort) UnmarshalText

func (p *IPPort) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface. The IPPort is expected in a form accepted by ParseIPPort. It returns an error if *p is not the IPPort zero value.

func (IPPort) Valid deprecated

func (p IPPort) Valid() bool

Valid reports whether p.IP() is valid. All ports are valid, including zero.

Deprecated: use the correctly named and identical IsValid method instead.

func (IPPort) WithIP

func (p IPPort) WithIP(ip IP) IPPort

WithIP returns an IPPort with IP ip and port p.Port().

func (IPPort) WithPort

func (p IPPort) WithPort(port uint16) IPPort

WithIP returns an IPPort with IP p.IP() and port port.

type IPPrefix

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

IPPrefix is an IP address prefix (CIDR) representing an IP network.

The first Bits() of IP() are specified. The remaining bits match any address. The range of Bits() is [0,32] for IPv4 or [0,128] for IPv6.

func FromStdIPNet

func FromStdIPNet(std *net.IPNet) (prefix IPPrefix, ok bool)

FromStdIPNet returns an IPPrefix from the standard library's IPNet type. If std is invalid, ok is false.

func IPPrefixFrom

func IPPrefixFrom(ip IP, bits uint8) IPPrefix

IPPrefixFrom returns an IPPrefix with IP ip and provided bits prefix length. It does not allocate.

func MustParseIPPrefix

func MustParseIPPrefix(s string) IPPrefix

MustParseIPPrefix calls ParseIPPrefix(s) and panics on error. It is intended for use in tests with hard-coded strings.

func ParseIPPrefix

func ParseIPPrefix(s string) (IPPrefix, error)

ParseIPPrefix parses s as an IP address prefix. The string can be in the form "192.168.1.0/24" or "2001::db8::/32", the CIDR notation defined in RFC 4632 and RFC 4291.

Note that masked address bits are not zeroed. Use Masked for that.

func (IPPrefix) AppendTo

func (p IPPrefix) AppendTo(b []byte) []byte

AppendTo appends a text encoding of p, as generated by MarshalText, to b and returns the extended buffer.

func (IPPrefix) Bits

func (p IPPrefix) Bits() uint8

Bits returns p's prefix length.

func (IPPrefix) Contains

func (p IPPrefix) Contains(ip IP) bool

Contains reports whether the network p includes ip.

An IPv4 address will not match an IPv6 prefix. A v6-mapped IPv6 address will not match an IPv4 prefix. A zero-value IP will not match any prefix. If ip has an IPv6 zone, Contains returns false, because IPPrefixes strip zones.

func (IPPrefix) IP

func (p IPPrefix) IP() IP

IP returns p's IP.

func (IPPrefix) IPNet

func (p IPPrefix) IPNet() *net.IPNet

IPNet returns the net.IPNet representation of an IPPrefix. The returned value is always non-nil. Any zone identifier is dropped in the conversion.

func (IPPrefix) IsSingleIP

func (p IPPrefix) IsSingleIP() bool

IsSingleIP reports whether p contains exactly one IP.

func (IPPrefix) IsValid

func (p IPPrefix) IsValid() bool

IsValid reports whether whether p.Bits() has a valid range for p.IP(). If p.IP() is zero, Valid returns false.

func (IPPrefix) IsZero

func (p IPPrefix) IsZero() bool

IsZero reports whether p is its zero value.

func (IPPrefix) MarshalText

func (p IPPrefix) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface, The encoding is the same as returned by String, with one exception: If p is the zero value, the encoding is the empty string.

func (IPPrefix) Masked

func (p IPPrefix) Masked() IPPrefix

Masked returns p in its canonical form, with bits of p.IP() not in p.Bits() masked off. If p is zero or otherwise invalid, Masked returns the zero value.

func (IPPrefix) Overlaps

func (p IPPrefix) Overlaps(o IPPrefix) bool

Overlaps reports whether p and o overlap at all.

If p and o are of different address families or either have a zero IP, it reports false. Like the Contains method, a prefix with a v6-mapped IPv4 IP is still treated as an IPv6 mask.

If either has a Bits of zero, it returns true.

func (IPPrefix) Range

func (p IPPrefix) Range() IPRange

Range returns the inclusive range of IPs that p covers.

If p is zero or otherwise invalid, Range returns the zero value.

func (IPPrefix) String

func (p IPPrefix) String() string

String returns the CIDR notation of p: "<ip>/<bits>".

func (*IPPrefix) UnmarshalText

func (p *IPPrefix) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface. The IP address is expected in a form accepted by ParseIPPrefix. It returns an error if *p is not the IPPrefix zero value.

func (IPPrefix) Valid deprecated

func (p IPPrefix) Valid() bool

Valid reports whether whether p.Bits() has a valid range for p.IP(). If p.IP() is zero, Valid returns false.

Deprecated: use the correctly named and identical IsValid method instead.

type IPRange

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

IPRange represents an inclusive range of IP addresses from the same address family.

The From() and To() IPs are inclusive bounds, both included in the range.

To be valid, the From() and To() values must be non-zero, have matching address families (IPv4 vs IPv6), and From() must be less than or equal to To(). IPv6 zones are stripped out and ignored. An invalid range may be ignored.

func IPRangeFrom

func IPRangeFrom(from, to IP) IPRange

IPRangeFrom returns an IPRange from from to to. It does not allocate.

func MustParseIPRange

func MustParseIPRange(s string) IPRange

MustParseIPRange calls ParseIPRange(s) and panics on error. It is intended for use in tests with hard-coded strings.

func ParseIPRange

func ParseIPRange(s string) (IPRange, error)

ParseIPRange parses a range out of two IPs separated by a hyphen.

It returns an error if the range is not valid.

func (IPRange) AppendPrefixes

func (r IPRange) AppendPrefixes(dst []IPPrefix) []IPPrefix

AppendPrefixes is an append version of IPRange.Prefixes. It appends the IPPrefix entries that cover r to dst.

func (IPRange) AppendTo

func (r IPRange) AppendTo(b []byte) []byte

AppendTo appends a text encoding of r, as generated by MarshalText, to b and returns the extended buffer.

func (IPRange) Contains

func (r IPRange) Contains(addr IP) bool

Contains reports whether the range r includes addr.

An invalid range always reports false.

If ip has an IPv6 zone, Contains returns false, because IPPrefixes strip zones.

func (IPRange) From

func (r IPRange) From() IP

From returns the lower bound of r.

func (IPRange) IsValid

func (r IPRange) IsValid() bool

IsValid reports whether r.From() and r.To() are both non-zero and obey the documented requirements: address families match, and From is less than or equal to To.

func (IPRange) IsZero

func (r IPRange) IsZero() bool

IsZero reports whether r is the zero value of the IPRange type.

func (IPRange) MarshalText

func (r IPRange) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface, The encoding is the same as returned by String, with one exception: If ip is the zero value, the encoding is the empty string.

func (IPRange) Overlaps

func (r IPRange) Overlaps(o IPRange) bool

Overlaps reports whether p and o overlap at all.

If p and o are of different address families or either are invalid, it reports false.

func (IPRange) Prefix

func (r IPRange) Prefix() (p IPPrefix, ok bool)

Prefix returns r as an IPPrefix, if it can be presented exactly as such. If r is not valid or is not exactly equal to one prefix, ok is false.

func (IPRange) Prefixes

func (r IPRange) Prefixes() []IPPrefix

Prefixes returns the set of IPPrefix entries that covers r.

If either of r's bounds are invalid, in the wrong order, or if they're of different address families, then Prefixes returns nil.

Prefixes necessarily allocates. See AppendPrefixes for a version that uses memory you provide.

func (IPRange) String

func (r IPRange) String() string

String returns a string representation of the range.

For a valid range, the form is "From-To" with a single hyphen separating the IPs, the same format recognized by ParseIPRange.

func (IPRange) To

func (r IPRange) To() IP

To returns the upper bound of r.

func (*IPRange) UnmarshalText

func (r *IPRange) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface. The IP range is expected in a form accepted by ParseIPRange. It returns an error if *r is not the IPRange zero value.

func (IPRange) Valid deprecated

func (r IPRange) Valid() bool

Valid reports whether r.From() and r.To() are both non-zero and obey the documented requirements: address families match, and From is less than or equal to To.

Deprecated: use the correctly named and identical IsValid method instead.

type IPSet

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

IPSet represents a set of IP addresses.

IPSet is safe for concurrent use. The zero value is a valid value representing a set of no IPs. Use IPSetBuilder to construct IPSets.

Example
package main

import (
	"fmt"

	"inet.af/netaddr"
)

func main() {
	var b netaddr.IPSetBuilder

	b.AddPrefix(netaddr.MustParseIPPrefix("10.0.0.0/8"))
	b.RemovePrefix(netaddr.MustParseIPPrefix("10.0.0.0/16"))

	b.AddRange(netaddr.IPRangeFrom(
		netaddr.MustParseIP("fed0::0400"),
		netaddr.MustParseIP("fed0::04ff"),
	))

	s, _ := b.IPSet()

	fmt.Println("Ranges:")
	for _, r := range s.Ranges() {
		fmt.Printf("  %s - %s\n", r.From(), r.To())
	}

	fmt.Println("Prefixes:")
	for _, p := range s.Prefixes() {
		fmt.Printf("  %s\n", p)
	}
}
Output:

Ranges:
  10.1.0.0 - 10.255.255.255
  fed0::400 - fed0::4ff
Prefixes:
  10.1.0.0/16
  10.2.0.0/15
  10.4.0.0/14
  10.8.0.0/13
  10.16.0.0/12
  10.32.0.0/11
  10.64.0.0/10
  10.128.0.0/9
  fed0::400/120

func (*IPSet) Contains

func (s *IPSet) Contains(ip IP) bool

Contains reports whether ip is in s. If ip has an IPv6 zone, Contains returns false, because IPSets do not track zones.

func (*IPSet) ContainsPrefix

func (s *IPSet) ContainsPrefix(p IPPrefix) bool

ContainsPrefix reports whether all IPs in p are in s.

func (*IPSet) ContainsRange

func (s *IPSet) ContainsRange(r IPRange) bool

ContainsRange reports whether all IPs in r are in s.

func (*IPSet) Equal

func (s *IPSet) Equal(o *IPSet) bool

Equal reports whether s and o represent the same set of IP addresses.

func (*IPSet) Overlaps

func (s *IPSet) Overlaps(b *IPSet) bool

Overlaps reports whether any IP in b is also in s.

func (*IPSet) OverlapsPrefix

func (s *IPSet) OverlapsPrefix(p IPPrefix) bool

OverlapsPrefix reports whether any IP in p is also in s.

func (*IPSet) OverlapsRange

func (s *IPSet) OverlapsRange(r IPRange) bool

OverlapsRange reports whether any IP in r is also in s.

func (*IPSet) Prefixes

func (s *IPSet) Prefixes() []IPPrefix

Prefixes returns the minimum and sorted set of IP prefixes that covers s.

func (*IPSet) Ranges

func (s *IPSet) Ranges() []IPRange

Ranges returns the minimum and sorted set of IP ranges that covers s.

func (*IPSet) RemoveFreePrefix

func (s *IPSet) RemoveFreePrefix(bitLen uint8) (p IPPrefix, newSet *IPSet, ok bool)

RemoveFreePrefix splits s into a Prefix of length bitLen and a new IPSet with that prefix removed.

If no contiguous prefix of length bitLen exists in s, RemoveFreePrefix returns ok=false.

type IPSetBuilder

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

IPSetBuilder builds an immutable IPSet.

The zero value is a valid value representing a set of no IPs.

The Add and Remove methods add or remove IPs to/from the set. Removals only affect the current membership of the set, so in general Adds should be called first. Input ranges may overlap in any way.

Most IPSetBuilder methods do not return errors. Instead, errors are accumulated and reported by IPSetBuilder.IPSet.

func (*IPSetBuilder) Add

func (s *IPSetBuilder) Add(ip IP)

Add adds ip to s.

func (*IPSetBuilder) AddPrefix

func (s *IPSetBuilder) AddPrefix(p IPPrefix)

AddPrefix adds all IPs in p to s.

func (*IPSetBuilder) AddRange

func (s *IPSetBuilder) AddRange(r IPRange)

AddRange adds r to s. If r is not Valid, AddRange does nothing.

func (*IPSetBuilder) AddSet

func (s *IPSetBuilder) AddSet(b *IPSet)

AddSet adds all IPs in b to s.

func (*IPSetBuilder) Clone

func (s *IPSetBuilder) Clone() *IPSetBuilder

Clone returns a copy of s that shares no memory with s.

func (*IPSetBuilder) Complement

func (s *IPSetBuilder) Complement()

Complement updates s to contain the complement of its current contents.

func (*IPSetBuilder) IPSet

func (s *IPSetBuilder) IPSet() (*IPSet, error)

IPSet returns an immutable IPSet representing the current state of s.

Most IPSetBuilder methods do not return errors. Rather, the builder ignores any invalid inputs (such as an invalid IPPrefix), and accumulates a list of any such errors that it encountered.

IPSet also reports any such accumulated errors. Even if the returned error is non-nil, the returned IPSet is usable and contains all modifications made with valid inputs.

The builder remains usable after calling IPSet. Calling IPSet clears any accumulated errors.

func (*IPSetBuilder) Intersect

func (s *IPSetBuilder) Intersect(b *IPSet)

Intersect updates s to the set intersection of s and b.

func (*IPSetBuilder) Remove

func (s *IPSetBuilder) Remove(ip IP)

Remove removes ip from s.

func (*IPSetBuilder) RemovePrefix

func (s *IPSetBuilder) RemovePrefix(p IPPrefix)

RemovePrefix removes all IPs in p from s.

func (*IPSetBuilder) RemoveRange

func (s *IPSetBuilder) RemoveRange(r IPRange)

RemoveRange removes all IPs in r from s.

func (*IPSetBuilder) RemoveSet

func (s *IPSetBuilder) RemoveSet(b *IPSet)

RemoveSet removes all IPs in o from s.

Jump to

Keyboard shortcuts

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