README
¶
netaddr

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:
- https://github.com/golang/go/issues/18804 ("net: reconsider representation of IP")
- https://github.com/golang/go/issues/18757 ("net: ParseIP should return an error, like other Parse functions")
- https://github.com/golang/go/issues/37921 ("net: Unable to reliably distinguish IPv4-mapped-IPv6 addresses from regular IPv4 addresses")
- merges net.IPAddr and net.IP (which the Go net package is a little torn between for legacy reasons)
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.
Index ¶
- type IP
- func FromStdIP(std net.IP) (ip IP, ok bool)
- func FromStdIPRaw(std net.IP) (ip IP, ok bool)
- func IPFrom16(addr [16]byte) IP
- func IPv4(a, b, c, d uint8) IP
- func IPv6LinkLocalAllNodes() IP
- func IPv6Raw(addr [16]byte) IP
- func IPv6Unspecified() IP
- func MustParseIP(s string) IP
- func ParseIP(s string) (IP, error)
- func (ip IP) As16() [16]byte
- func (ip IP) As4() [4]byte
- func (ip IP) BitLen() uint8
- func (ip IP) Compare(ip2 IP) int
- func (ip IP) IPAddr() *net.IPAddr
- func (ip IP) Is4() bool
- func (ip IP) Is4in6() bool
- func (ip IP) Is6() bool
- func (ip IP) IsInterfaceLocalMulticast() bool
- func (ip IP) IsLinkLocalMulticast() bool
- func (ip IP) IsLinkLocalUnicast() bool
- func (ip IP) IsLoopback() bool
- func (ip IP) IsMulticast() bool
- func (ip IP) IsZero() bool
- func (ip IP) Less(ip2 IP) bool
- func (ip IP) MarshalText() ([]byte, error)
- func (ip *IP) Netmask(mask []byte) (IPPrefix, error)
- func (ip IP) Next() IP
- func (ip IP) Prefix(bits uint8) (IPPrefix, error)
- func (ip IP) Prior() IP
- func (ip IP) String() string
- func (ip IP) Unmap() IP
- func (ip *IP) UnmarshalText(text []byte) error
- func (ip IP) WithZone(zone string) IP
- func (ip IP) Zone() string
- type IPPort
- type IPPrefix
- func (p IPPrefix) Contains(ip IP) bool
- func (p IPPrefix) IPNet() *net.IPNet
- func (p IPPrefix) IsSingleIP() bool
- func (p IPPrefix) IsZero() bool
- func (p IPPrefix) MarshalText() ([]byte, error)
- func (p IPPrefix) Masked() IPPrefix
- func (p IPPrefix) Overlaps(o IPPrefix) bool
- func (p IPPrefix) Range() IPRange
- func (p IPPrefix) String() string
- func (p *IPPrefix) UnmarshalText(text []byte) error
- func (p IPPrefix) Valid() bool
- type IPRange
- type IPSet
- func (s *IPSet) Contains(ip IP) bool
- func (s *IPSet) ContainsPrefix(p IPPrefix) bool
- func (s *IPSet) ContainsRange(r IPRange) bool
- func (s *IPSet) Equal(o *IPSet) bool
- func (s *IPSet) Overlaps(b *IPSet) bool
- func (s *IPSet) OverlapsPrefix(p IPPrefix) bool
- func (s *IPSet) OverlapsRange(r IPRange) bool
- func (s *IPSet) Prefixes() []IPPrefix
- func (s *IPSet) Ranges() []IPRange
- func (s *IPSet) RemoveFreePrefix(bitLen uint8) (p IPPrefix, newSet *IPSet, ok bool)
- type IPSetBuilder
- func (s *IPSetBuilder) Add(ip IP)
- func (s *IPSetBuilder) AddPrefix(p IPPrefix)
- func (s *IPSetBuilder) AddRange(r IPRange)
- func (s *IPSetBuilder) AddSet(b *IPSet)
- func (s *IPSetBuilder) Clone() *IPSetBuilder
- func (s *IPSetBuilder) Complement()
- func (s *IPSetBuilder) IPSet() *IPSet
- func (s *IPSetBuilder) Intersect(b *IPSet)
- func (s *IPSetBuilder) Remove(ip IP)
- func (s *IPSetBuilder) RemovePrefix(p IPPrefix)
- func (s *IPSetBuilder) RemoveRange(r IPRange)
- func (s *IPSetBuilder) RemoveSet(b *IPSet)
Examples ¶
Constants ¶
Variables ¶
Functions ¶
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.
func FromStdIP ¶
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 ¶
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 ¶
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 IPv6LinkLocalAllNodes ¶
func IPv6LinkLocalAllNodes() IP
IPv6LinkLocalAllNodes returns the IPv6 link-local all nodes multicast address ff02::1.
func IPv6Raw ¶
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 ¶
MustParseIP calls ParseIP(s) and panics on error. It is intended for use in tests with hard-coded strings.
func ParseIP ¶
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) As16 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
Is4 reports whether ip is an IPv4 address.
It returns false for IP4-mapped IPv6 addresses. See IP.Unmap.
func (IP) IsInterfaceLocalMulticast ¶
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 ¶
IsLinkLocalMulticast reports whether ip is a link-local multicast address. If ip is the zero value, it will return false.
func (IP) IsLinkLocalUnicast ¶
IsLinkLocalUnicast reports whether ip is a link-local unicast address. If ip is the zero value, it will return false.
func (IP) IsLoopback ¶
IsLoopback reports whether ip is a loopback address. If ip is the zero value, it will return false.
func (IP) IsMulticast ¶
IsMulticast reports whether ip is a multicast address. If ip is the zero value, it will return false.
func (IP) IsZero ¶
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.
func (IP) Less ¶
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) MarshalText ¶
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 ¶
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) Prefix ¶
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) 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.
func (IP) Unmap ¶
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.
func (*IP) UnmarshalText ¶
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.
type IPPort ¶
IPPort is an IP & port number.
It's meant to be used as a value type.
func FromStdAddr ¶
FromStdAddr maps the components of a standard library TCPAddr or UDPAddr into an IPPort.
func MustParseIPPort ¶
MustParseIPPort calls ParseIPPort(s) and panics on error. It is intended for use in tests with hard-coded strings.
func ParseIPPort ¶
ParseIPPort parses s as an IPPort.
It doesn't do any name resolution, and ports must be numeric.
func (IPPort) MarshalText ¶
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) 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 ¶
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 ¶
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 ¶
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.
type IPPrefix ¶
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 ¶
FromStdIPNet returns an IPPrefix from the standard library's IPNet type. If std is invalid, ok is false.
func MustParseIPPrefix ¶
MustParseIPPrefix calls ParseIPPrefix(s) and panics on error. It is intended for use in tests with hard-coded strings.
func ParseIPPrefix ¶
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) Contains ¶
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.
func (IPPrefix) 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 ¶
IsSingleIP reports whether p contains exactly one IP.
func (IPPrefix) MarshalText ¶
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 ¶
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 ¶
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 ¶
Range returns the inclusive range of IPs that p covers.
If p is zero or otherwise invalid, Range returns the zero value.
func (*IPPrefix) UnmarshalText ¶
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.
type IPRange ¶
type IPRange struct { // From is the initial IP address in the range. From IP // To is the final IP address in the range. To IP }
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 be non-zero, have matching address families (IPv4 vs IPv6), be in the same IPv6 zone (if any), and From must be less than or equal to To. An invalid range may be ignored.
func ParseIPRange ¶
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 ¶
AppendPrefixes is an append version of IPRange.Prefixes. It appends the IPPrefix entries that cover r to dst.
func (IPRange) Contains ¶
Contains reports whether the range r includes addr.
An invalid range always reports false.
func (IPRange) Overlaps ¶
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 ¶
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 ¶
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.
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 ¶
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) ContainsPrefix ¶
ContainsPrefix reports whether all IPs in p are in s.
func (*IPSet) ContainsRange ¶
ContainsRange reports whether all IPs in r are in s.
func (*IPSet) OverlapsPrefix ¶
OverlapsPrefix reports whether any IP in p is also in s.
func (*IPSet) OverlapsRange ¶
OverlapsRange reports whether any IP in r is also in s.
func (*IPSet) RemoveFreePrefix ¶
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.
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
IPSet returns an immutable IPSet representing the current state of s. The builder remains usable after calling IPSet.
func (*IPSetBuilder) Intersect ¶
func (s *IPSetBuilder) Intersect(b *IPSet)
Intersect updates s to the set intersection of s and b.
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.