Documentation ¶
Overview ¶
Package netutil contains common utilities for IP, MAC, and other kinds of network addresses.
Index ¶
- Constants
- func CloneIPNet(n *net.IPNet) (clone *net.IPNet)
- func CloneIPs(ips []net.IP) (clone []net.IP)
- func CloneURL(u *url.URL) (clone *url.URL)
- func IPAndPortFromAddr(addr net.Addr) (ip net.IP, port uint16)
- func IPFromReversedAddr(arpa string) (ip net.IP, err error)
- func IPNetToPrefix(subnet *net.IPNet, fam AddrFamily) (p netip.Prefix, err error)
- func IPNetToPrefixNoMapped(subnet *net.IPNet) (p netip.Prefix, err error)
- func IPToAddr(ip net.IP, fam AddrFamily) (addr netip.Addr, err error)
- func IPToAddrNoMapped(ip net.IP) (addr netip.Addr, err error)
- func IPToReversedAddr(ip net.IP) (arpa string, err error)
- func IPv4Localhost() (ip netip.Addr)
- func IPv4Zero() (ip net.IP)
- func IPv4allrouter() (ip net.IP)
- func IPv4allsys() (ip net.IP)
- func IPv4bcast() (ip net.IP)
- func IPv6Localhost() (ip netip.Addr)
- func IPv6Zero() (ip net.IP)
- func IsImmediateSubdomain(domain, top string) (ok bool)
- func IsLocallyServed(ip net.IP) (ok bool)
- func IsLocallyServedAddr(ip netip.Addr) (ok bool)
- func IsSpecialPurpose(ip net.IP) (ok bool)
- func IsSpecialPurposeAddr(ip netip.Addr) (ok bool)
- func IsSubdomain(domain, top string) (ok bool)
- func IsValidHostInnerRune(r rune) (ok bool)
- func IsValidHostOuterRune(r rune) (ok bool)
- func JoinHostPort(host string, port uint16) (hostport string)
- func NetAddrToAddrPort(addr net.Addr) (addrPort netip.AddrPort)
- func ParseIP(s string) (ip net.IP, err error)
- func ParseIPv4(s string) (ip net.IP, err error)
- func ParseSubnet(s string) (n *net.IPNet, err error)
- func ParseSubnets(ss ...string) (ns []*net.IPNet, err error)
- func SingleIPSubnet(ip net.IP) (n *net.IPNet)
- func SplitHost(hostport string) (host string, err error)
- func SplitHostPort(hostport string) (host string, port uint16, err error)
- func Subdomains(domain string) (sub []string)
- func SubnetFromReversedAddr(arpa string) (subnet *net.IPNet, err error)
- func ValidateDomainName(name string) (err error)
- func ValidateDomainNameLabel(label string) (err error)
- func ValidateHostname(name string) (err error)
- func ValidateHostnameLabel(label string) (err error)
- func ValidateIP(ip net.IP) (err error)
- func ValidateMAC(mac net.HardwareAddr) (err error)
- func ValidateSRVDomainName(name string) (err error)
- func ValidateServiceNameLabel(label string) (err error)
- func ValidateTLDLabel(tld string) (err error)
- func ZeroPrefix(fam AddrFamily) (n netip.Prefix)
- type AddrError
- type AddrFamily
- type AddrKind
- type HostPort
- type IPMapdeprecated
- func (m *IPMap) Clear()
- func (m *IPMap) Del(ip net.IP)
- func (m *IPMap) Get(ip net.IP) (v any, ok bool)
- func (m *IPMap) Len() (n int)
- func (m *IPMap) Range(f func(ip net.IP, v any) (cont bool))
- func (m *IPMap) Set(ip net.IP, v any)
- func (m *IPMap) ShallowClone() (sclone *IPMap)
- func (m *IPMap) String() (s string)
- type LabelError
- type LabelKind
- type LengthError
- type RuneError
- type SliceSubnetSet
- type SubnetSet
- type SubnetSetFunc
Examples ¶
- AddrFamily.String
- AddrFamilyFromRRType
- HostPort.MarshalText
- HostPort.String
- HostPort.UnmarshalText
- IPFromReversedAddr
- IPNetToPrefix
- IPNetToPrefixNoMapped
- IPToAddr
- IPToAddrNoMapped
- IPToReversedAddr
- IPv4Localhost
- IPv4Zero
- IPv6Localhost
- IPv6Zero
- IsImmediateSubdomain
- IsSubdomain
- JoinHostPort
- NetAddrToAddrPort
- ParseIP
- ParseIPv4
- ParseSubnet
- ParseSubnets
- SingleIPSubnet
- SplitHost
- SplitHostPort
- Subdomains
- SubnetFromReversedAddr
- SubnetFromReversedAddr (DomainOnly)
- SubnetSet (Func)
- SubnetSet (Single)
- SubnetSet (Slice)
- ZeroPrefix
Constants ¶
const ( // ErrNotAReversedIP is the underlying error returned from validation // functions when a domain name is not a full reversed IP address. ErrNotAReversedIP errors.Error = "not a full reversed ip address" // ErrNotAReversedSubnet is the underlying error returned from validation // functions when a domain name is not a valid reversed IP network. ErrNotAReversedSubnet errors.Error = "not a reversed ip network" )
const ( IPv4BitLen = net.IPv4len * 8 IPv6BitLen = net.IPv6len * 8 )
Bit lengths of IP addresses.
const MaxDomainLabelLen = 63
MaxDomainLabelLen is the maximum allowed length of a domain name label according to RFC 1035.
const MaxDomainNameLen = 253
MaxDomainNameLen is the maximum allowed length of a full domain name according to RFC 1035.
See also: https://stackoverflow.com/a/32294443/1892060.
const MaxServiceLabelLen = 16
MaxServiceLabelLen is the maximum allowed length of a service name label according to RFC 6335.
Variables ¶
This section is empty.
Functions ¶
func CloneIPNet ¶
CloneIPNet returns a deep clone of n.
func CloneURL ¶
CloneURL returns a deep clone of u. The User pointer of clone is the same, since a *url.Userinfo is effectively an immutable value.
func IPAndPortFromAddr ¶
IPAndPortFromAddr returns the IP address and the port from addr. If addr is neither a *net.TCPAddr nor a *net.UDPAddr, it returns nil and 0.
func IPFromReversedAddr ¶
IPFromReversedAddr tries to convert a full reversed ARPA address to a normal IP address. arpa can be domain name or an FQDN.
Any error returned will have the underlying type of *AddrError.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ip, err := netutil.IPFromReversedAddr("4.3.2.1.in-addr.arpa") if err != nil { panic(err) } fmt.Println(ip) a := `4.3.2.1.d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa` ip, err = netutil.IPFromReversedAddr(a) if err != nil { panic(err) } fmt.Println(ip) }
Output: 1.2.3.4 ::abcd:1234
func IPNetToPrefix ¶
IPNetToPrefix is a helper that converts a *net.IPNet into a netip.Prefix. subnet should not be nil. fam must be either AddrFamilyIPv4 or AddrFamilyIPv6.
See also IPNetToPrefixNoMapped.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { _, n, _ := net.ParseCIDR("1.2.3.0/24") pref, err := netutil.IPNetToPrefix(n, netutil.AddrFamilyIPv4) fmt.Printf("%q, error: %v\n", pref, err) pref, err = netutil.IPNetToPrefix(n, netutil.AddrFamilyIPv6) fmt.Printf("%q, error: %v\n", pref, err) _, n, _ = net.ParseCIDR("1234::/72") pref, err = netutil.IPNetToPrefix(n, netutil.AddrFamilyIPv4) fmt.Printf("%q, error: %v\n", pref, err) pref, err = netutil.IPNetToPrefix(n, netutil.AddrFamilyIPv6) fmt.Printf("%q, error: %v\n", pref, err) }
Output: "1.2.3.0/24", error: <nil> "::ffff:1.2.3.0/24", error: <nil> "invalid Prefix", error: bad ip for subnet 1234::/72: bad ipv4 net.IP 1234:: "1234::/72", error: <nil>
func IPNetToPrefixNoMapped ¶
IPNetToPrefixNoMapped is like IPNetToPrefix but it detects the address family automatically by assuming that every IPv6-mapped IPv4 address is actually an IPv4 address. Do not use IPNetToPrefixNoMapped where this assumption isn't safe.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { _, n, _ := net.ParseCIDR("1.2.3.0/24") pref, err := netutil.IPNetToPrefixNoMapped(n) fmt.Printf("%q, error: %v\n", pref, err) n = &net.IPNet{ IP: net.IP{1, 2, 3, 0}, Mask: net.CIDRMask(24, 32), } pref, err = netutil.IPNetToPrefixNoMapped(n) fmt.Printf("%q, error: %v\n", pref, err) _, n, _ = net.ParseCIDR("1234::/72") pref, err = netutil.IPNetToPrefixNoMapped(n) fmt.Printf("%q, error: %v\n", pref, err) }
Output: "1.2.3.0/24", error: <nil> "1.2.3.0/24", error: <nil> "1234::/72", error: <nil>
func IPToAddr ¶
IPToAddr converts a net.IP into a netip.Addr of the given family and returns a meaningful error. ip should not be nil. fam must be either AddrFamilyIPv4 or AddrFamilyIPv6.
See also IPToAddrNoMapped.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ip := net.ParseIP("1.2.3.4") addr, err := netutil.IPToAddr(ip, netutil.AddrFamilyIPv4) fmt.Printf("%q, error: %v\n", addr, err) addr, err = netutil.IPToAddr(ip, netutil.AddrFamilyIPv6) fmt.Printf("%q, error: %v\n", addr, err) ip = net.ParseIP("1234::5678") addr, err = netutil.IPToAddr(ip, netutil.AddrFamilyIPv4) fmt.Printf("%q, error: %v\n", addr, err) addr, err = netutil.IPToAddr(ip, netutil.AddrFamilyIPv6) fmt.Printf("%q, error: %v\n", addr, err) }
Output: "1.2.3.4", error: <nil> "::ffff:1.2.3.4", error: <nil> "invalid IP", error: bad ipv4 net.IP 1234::5678 "1234::5678", error: <nil>
func IPToAddrNoMapped ¶
IPToAddrNoMapped is like IPToAddr but it detects the address family automatically by assuming that every IPv6-mapped IPv4 address is actually an IPv4 address. Do not use IPToAddrNoMapped where this assumption isn't safe.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ip := net.ParseIP("1.2.3.4") addr, err := netutil.IPToAddrNoMapped(ip) fmt.Printf("%q, error: %v\n", addr, err) ip = net.IP{1, 2, 3, 4} addr, err = netutil.IPToAddrNoMapped(ip) fmt.Printf("%q, error: %v\n", addr, err) ip = net.ParseIP("1234::5678") addr, err = netutil.IPToAddrNoMapped(ip) fmt.Printf("%q, error: %v\n", addr, err) }
Output: "1.2.3.4", error: <nil> "1.2.3.4", error: <nil> "1234::5678", error: <nil>
func IPToReversedAddr ¶
IPToReversedAddr returns the reversed ARPA address of ip suitable for reverse DNS (PTR) record lookups. This is a modified version of function ReverseAddr from package github.com/miekg/dns package that accepts an IP.
Any error returned will have the underlying type of *AddrError.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { arpa, err := netutil.IPToReversedAddr(net.IP{1, 2, 3, 4}) if err != nil { panic(err) } fmt.Println(arpa) ip := net.ParseIP("::abcd:1234") arpa, err = netutil.IPToReversedAddr(ip) if err != nil { panic(err) } fmt.Println(arpa) }
Output: 4.3.2.1.in-addr.arpa 4.3.2.1.d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa
func IPv4Localhost ¶
IPv4Localhost returns the IPv4 localhost address "127.0.0.1".
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Println(netutil.IPv4Localhost()) }
Output: 127.0.0.1
func IPv4Zero ¶
IPv4Zero returns a new unspecified (aka empty or null) IPv4 address, 0.0.0.0. It has the same name as the variable in package net, but the result always has four bytes.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Println(netutil.IPv4Zero()) }
Output: 0.0.0.0
func IPv4allrouter ¶
IPv4allrouter returns a new all routers IPv4 address, 224.0.0.2. It has the same name as the variable in package net, but the result always has four bytes.
func IPv4allsys ¶
IPv4allsys returns a new all systems (aka all hosts) IPv4 address, 224.0.0.1. It has the same name as the variable in package net, but the result always has four bytes.
func IPv4bcast ¶
IPv4bcast returns a new limited broadcast IPv4 address, 255.255.255.255. It has the same name as the variable in package net, but the result always has four bytes.
func IPv6Localhost ¶
IPv6Localhost returns the IPv6 localhost address "::1".
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Println(netutil.IPv6Localhost()) }
Output: ::1
func IPv6Zero ¶
IPv6Zero returns a new unspecified (aka empty or null) IPv6 address, [::]. It has the same name as the variable in package net.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Println(netutil.IPv6Zero()) }
Output: ::
func IsImmediateSubdomain ¶
IsImmediateSubdomain returns true if domain is an immediate subdomain of top. domain and top should be valid domain names, qualified in the same manner, and have the same letter case.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { printResult := func(name string, isImmSub bool) { fmt.Printf("%-14s: %5t\n", name, isImmSub) } printResult("same domain", netutil.IsImmediateSubdomain("sub.example.com", "example.com")) printResult("empty", netutil.IsImmediateSubdomain("", "")) printResult("same", netutil.IsImmediateSubdomain("example.com", "example.com")) printResult("dot only", netutil.IsImmediateSubdomain(".example.com", "example.com")) printResult("backwards", netutil.IsImmediateSubdomain("example.com", "sub.example.com")) printResult("other domain", netutil.IsImmediateSubdomain("sub.example.com", "example.org")) printResult("not immediate", netutil.IsImmediateSubdomain("sub.sub.example.com", "example.com")) printResult("similar 1", netutil.IsImmediateSubdomain("sub.myexample.com", "example.org")) printResult("similar 2", netutil.IsImmediateSubdomain("sub.example.com", "myexample.org")) }
Output: same domain : true empty : false same : false dot only : false backwards : false other domain : false not immediate : false similar 1 : false similar 2 : false
func IsLocallyServed ¶
IsLocallyServed checks if ip belongs to any network defined by RFC 6303:
10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.0.2.0/24 192.168.0.0/16 198.51.100.0/24 203.0.113.0/24 255.255.255.255/32 ::/128 ::1/128 2001:db8::/32 fd00::/8 fe80::/10
It may also be used as a SubnetSetFunc.
func IsLocallyServedAddr ¶
IsLocallyServedAddr is like IsLocallyServed but for netip.Addr.
func IsSpecialPurpose ¶
IsSpecialPurpose checks if ip belongs to any network defined by IANA Special-Purpose Address Registry:
0.0.0.0/8 "This host on this network". 10.0.0.0/8 Private-Use. 100.64.0.0/10 Shared Address Space. 127.0.0.0/8 Loopback. 169.254.0.0/16 Link Local. 172.16.0.0/12 Private-Use. 192.0.0.0/24 IETF Protocol Assignments. 192.0.0.0/29 DS-Lite. 192.0.2.0/24 Documentation (TEST-NET-1) 192.88.99.0/24 6to4 Relay Anycast. 192.168.0.0/16 Private-Use. 198.18.0.0/15 Benchmarking. 198.51.100.0/24 Documentation (TEST-NET-2). 203.0.113.0/24 Documentation (TEST-NET-3). 240.0.0.0/4 Reserved. 255.255.255.255/32 Limited Broadcast. ::/128 Unspecified Address. ::1/128 Loopback Address. 64:ff9b::/96 IPv4-IPv6 Translation Address. 64:ff9b:1::/48 IPv4-IPv6 Translation Address. 100::/64 Discard-Only Address Block. 2001::/23 IETF Protocol Assignments. 2001::/32 TEREDO. 2001:1::1/128 Port Control Protocol Anycast. 2001:1::2/128 Traversal Using Relays around NAT Anycast. 2001:2::/48 Benchmarking. 2001:3::/32 AMT. 2001:4:112::/48 AS112-v6. 2001:10::/28 ORCHID. 2001:20::/28 ORCHIDv2. 2001:db8::/32 Documentation. 2002::/16 6to4. 2620:4f:8000::/48 Direct Delegation AS112 Service. fc00::/7 Unique-Local. fe80::/10 Linked-Scoped Unicast.
See https://www.iana.org/assignments/iana-ipv4-special-registry and https://www.iana.org/assignments/iana-ipv6-special-registry.
It may also be used as a SubnetSetFunc.
func IsSpecialPurposeAddr ¶
IsSpecialPurposeAddr is like IsSpecialPurpose but for netip.Addr. Since the argument's type is different, it cannot be used as a SubnetSetFunc.
func IsSubdomain ¶
IsSubdomain returns true if domain is a subdomain of top. domain and top should be valid domain names, qualified in the same manner, and have the same letter case.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { printResult := func(name string, isImmSub bool) { fmt.Printf("%-14s: %5t\n", name, isImmSub) } printResult("same domain", netutil.IsSubdomain("sub.example.com", "example.com")) printResult("not immediate", netutil.IsSubdomain("sub.sub.example.com", "example.com")) printResult("empty", netutil.IsSubdomain("", "")) printResult("same", netutil.IsSubdomain("example.com", "example.com")) printResult("dot only", netutil.IsSubdomain(".example.com", "example.com")) printResult("backwards", netutil.IsSubdomain("example.com", "sub.example.com")) printResult("other domain", netutil.IsSubdomain("sub.example.com", "example.org")) printResult("similar 1", netutil.IsSubdomain("sub.myexample.com", "example.org")) printResult("similar 2", netutil.IsSubdomain("sub.example.com", "myexample.org")) }
Output: same domain : true not immediate : true empty : false same : false dot only : false backwards : false other domain : false similar 1 : false similar 2 : false
func IsValidHostInnerRune ¶
IsValidHostInnerRune returns true if r is a valid inner—that is, neither initial nor final—rune for a hostname label.
func IsValidHostOuterRune ¶
IsValidHostOuterRune returns true if r is a valid initial or final rune for a hostname label.
func JoinHostPort ¶
JoinHostPort is a convenient wrapper for net.JoinHostPort with port of type uint16. As opposed to net.JoinHostPort it also trims the host from square brackets if any. This may be useful when passing url.URL.Host field containing an IPv6 address.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Println(netutil.JoinHostPort("example.com", 12345)) }
Output: example.com:12345
func NetAddrToAddrPort ¶
NetAddrToAddrPort converts a net.Addr into a netip.AddrPort if it can. Otherwise, it returns an empty netip.AddrPort. addr must not be nil.
Since net.TCPAddr.AddrPort and net.UDPAddr.AddrPort perform a naïve conversion of their net.IP values into netip.Addr ones, that does not take mapped addresses into account, IPv4-mapped IPv6 addresses are assumed to actually be IPv4 addresses and are normalized into them.
Those who want a conversion without this normalization may use:
if ap, ok := addr.(interface{ AddrPort() (a netip.AddrPort) }); ok { return ap.AddrPort() }
See https://github.com/golang/go/issues/53607.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { tcpAddr := &net.TCPAddr{ // NOTE: This produces a 16-byte form of the IPv4 address. IP: net.IPv4(1, 2, 3, 4), Port: 56789, } addrPort := netutil.NetAddrToAddrPort(tcpAddr) fmt.Println(addrPort) fmt.Println(addrPort.Addr().Is4()) fmt.Println(addrPort.Addr().Is4In6()) }
Output: 1.2.3.4:56789 true false
func ParseIP ¶
ParseIP is a wrapper around net.ParseIP that returns a useful error.
Any error returned will have the underlying type of *AddrError.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ip, err := netutil.ParseIP("1.2.3.4") fmt.Println(ip, err) ip, err = netutil.ParseIP("1234::cdef") fmt.Println(ip, err) ip, err = netutil.ParseIP("!!!") fmt.Println(ip, err) }
Output: 1.2.3.4 <nil> 1234::cdef <nil> <nil> bad ip address "!!!"
func ParseIPv4 ¶
ParseIPv4 is a wrapper around net.ParseIP that makes sure that the parsed IP is an IPv4 address and returns a useful error.
Any error returned will have the underlying type of either *AddrError.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ip, err := netutil.ParseIPv4("1.2.3.4") fmt.Println(ip, err) ip, err = netutil.ParseIPv4("1234::cdef") fmt.Println(ip, err) ip, err = netutil.ParseIPv4("!!!") fmt.Println(ip, err) }
Output: 1.2.3.4 <nil> <nil> bad ipv4 address "1234::cdef" <nil> bad ipv4 address "!!!"
func ParseSubnet ¶
ParseSubnet parses a subnet which can be either a CIDR or a single IP. In the latter case, n is a single-IP subnet. It also keeps the original parsed IP address inside n.
If s contains a CIDR with an IP address that is an IPv4-mapped IPv6 address, the behavior is undefined.
Any error returned will have the underlying type of either *AddrError.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ip := net.IP{1, 2, 3, 4} otherIP := net.IP{1, 2, 3, 5} n, err := netutil.ParseSubnet("1.2.3.4") fmt.Println(n, err) fmt.Printf("%s is in %s: %t\n", ip, n, n.Contains(ip)) fmt.Printf("%s is in %s: %t\n", otherIP, n, n.Contains(otherIP)) n, err = netutil.ParseSubnet("1.2.3.4/16") fmt.Println(n, err) fmt.Printf("%s is in %s: %t\n", ip, n, n.Contains(ip)) fmt.Printf("%s is in %s: %t\n", otherIP, n, n.Contains(otherIP)) }
Output: 1.2.3.4/32 <nil> 1.2.3.4 is in 1.2.3.4/32: true 1.2.3.5 is in 1.2.3.4/32: false 1.2.3.4/16 <nil> 1.2.3.4 is in 1.2.3.4/16: true 1.2.3.5 is in 1.2.3.4/16: true
func ParseSubnets ¶
ParseSubnets returns the slice of *net.IPNet parsed from ss.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ns, err := netutil.ParseSubnets("1.2.3.4", "1.2.3.4/16") fmt.Println("error: ", err) fmt.Println("networks:", ns) fmt.Println() ns, err = netutil.ParseSubnets() fmt.Println("error: ", err) fmt.Println("networks:", ns) fmt.Println() ns, err = netutil.ParseSubnets("4.3.2.1/32", "5.5.5.5/33") fmt.Println("error: ", err) fmt.Println("networks:", ns) }
Output: error: <nil> networks: [1.2.3.4/32 1.2.3.4/16] error: <nil> networks: [] error: parsing network at index 1: bad cidr address "5.5.5.5/33" networks: []
func SingleIPSubnet ¶
SingleIPSubnet returns an IP network that only contains ip. If ip is not a valid IPv4 or IPv6 address, n is nil.
Example ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { ip4 := net.IP{1, 2, 3, 4} otherIP4 := net.IP{1, 2, 3, 5} n := netutil.SingleIPSubnet(ip4) fmt.Printf("%s is in %s: %t\n", ip4, n, n.Contains(ip4)) fmt.Printf("%s is in %s: %t\n", otherIP4, n, n.Contains(otherIP4)) ip6 := net.ParseIP("1234::cdef") otherIP6 := net.ParseIP("1234::cdff") n = netutil.SingleIPSubnet(ip6) fmt.Printf("%s is in %s: %t\n", ip6, n, n.Contains(ip6)) fmt.Printf("%s is in %s: %t\n", otherIP6, n, n.Contains(otherIP6)) }
Output: 1.2.3.4 is in 1.2.3.4/32: true 1.2.3.5 is in 1.2.3.4/32: false 1234::cdef is in 1234::cdef/128: true 1234::cdff is in 1234::cdef/128: false
func SplitHost ¶
SplitHost is a wrapper for net.SplitHostPort for cases when the hostport may or may not contain a port.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { host, err := netutil.SplitHost("example.com:12345") if err != nil { panic(err) } fmt.Println(host) host, err = netutil.SplitHost("example.org") if err != nil { panic(err) } fmt.Println(host) _, err = netutil.SplitHost("[BAD:!") fmt.Println(err) }
Output: example.com example.org address [BAD:!: missing ']' in address
func SplitHostPort ¶
SplitHostPort is a convenient wrapper for net.SplitHostPort with port of type uint16.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { host, port, err := netutil.SplitHostPort("example.com:12345") if err != nil { panic(err) } fmt.Printf("%T(%[1]v)\n", host) fmt.Printf("%T(%[1]v)\n", port) }
Output: string(example.com) uint16(12345)
func Subdomains ¶
Subdomains returns all subdomains of domain, starting from domain itself. domain must be a valid, non-fully-qualified domain name. If domain is empty, Subdomains returns nil.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Printf("%#v\n", netutil.Subdomains("subsub.sub.domain.tld")) fmt.Println() fmt.Printf("%#v\n", netutil.Subdomains("")) }
Output: []string{"subsub.sub.domain.tld", "sub.domain.tld", "domain.tld", "tld"} []string(nil)
func SubnetFromReversedAddr ¶
SubnetFromReversedAddr tries to convert a reversed ARPA address to an IP network. arpa can be domain name or an FQDN.
Any error returned will have the underlying type of *AddrError.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { subnet, err := netutil.SubnetFromReversedAddr("10.in-addr.arpa") if err != nil { panic(err) } fmt.Println(subnet) subnet, err = netutil.SubnetFromReversedAddr("0.10.in-addr.arpa") if err != nil { panic(err) } fmt.Println(subnet) subnet, err = netutil.SubnetFromReversedAddr("3.2.1.d.c.b.a.ip6.arpa") if err != nil { panic(err) } fmt.Println(subnet) }
Output: 10.0.0.0/8 10.0.0.0/16 abcd:1230::/28
Example (DomainOnly) ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { a := `in-addr.arpa` _, err := netutil.SubnetFromReversedAddr(a) fmt.Println(err) }
Output: bad arpa domain name "in-addr.arpa": not a reversed ip network
func ValidateDomainName ¶
ValidateDomainName validates the domain name in accordance to RFC 1035 and RFC 3696 Section 2. As opposed to ValidateHostname, this function only validates the lengths of the name itself and its labels, except the TLD.
Any error returned will have the underlying type of *AddrError.
func ValidateDomainNameLabel ¶
ValidateDomainNameLabel returns an error if label is not a valid label of a domain name. An empty label is considered invalid. Essentially it validates the length of the label since the name in DNS is permitted to contain any printable ASCII character, see RFC 3696 Section 2. label must only contain ASCII characters, see idna.ToASCII.
Any error returned will have the underlying type of *LabelError.
func ValidateHostname ¶
ValidateHostname validates the domain name in accordance to RFC 952, RFC 1035, and with RFC 1123's inclusion of digits at the start of the host. It doesn't validate against two or more hyphens to allow punycode and internationalized domains.
Any error returned will have the underlying type of *AddrError.
func ValidateHostnameLabel ¶
ValidateHostnameLabel returns an error if label is not a valid label of a domain name. An empty label is considered invalid.
Any error returned will have the underlying type of *LabelError.
func ValidateIP ¶
ValidateIP returns an error if ip is not a valid IPv4 or IPv6 address.
Any error returned will have the underlying type of *AddrError.
func ValidateMAC ¶
func ValidateMAC(mac net.HardwareAddr) (err error)
ValidateMAC returns an error if mac is not a valid EUI-48, EUI-64, or 20-octet InfiniBand link-layer address.
Any error returned will have the underlying type of *AddrError.
func ValidateSRVDomainName ¶
ValidateSRVDomainName validates name assuming it belongs to the superset of service domain names in accordance to RFC 2782 and RFC 6763. It doesn't validate against two or more hyphens to allow punycode and internationalized domains.
Any error returned will have the underlying type of *AddrError.
func ValidateServiceNameLabel ¶
ValidateServiceNameLabel returns an error if label is not a valid label of a service domain name. An empty label is considered invalid.
Any error returned will have the underlying type of *LabelError.
func ValidateTLDLabel ¶
ValidateTLDLabel validates the top-level domain label in accordance to RFC 3696 Section 2. In addition to the validations performed by ValidateHostnameLabel, it also checks that the label contains at least one non-digit character.
Any error returned will have the underlying type of *LabelError.
func ZeroPrefix ¶
func ZeroPrefix(fam AddrFamily) (n netip.Prefix)
ZeroPrefix returns an IP subnet with prefix 0 and all bytes of the IP address set to 0. fam must be either AddrFamilyIPv4 or AddrFamilyIPv6.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Println(netutil.ZeroPrefix(netutil.AddrFamilyIPv4)) fmt.Println(netutil.ZeroPrefix(netutil.AddrFamilyIPv6)) // Invalid value for [netutil.AddrFamily]. func() { defer func() { fmt.Println(recover()) }() fmt.Println(netutil.ZeroPrefix(1234)) }() }
Output: 0.0.0.0/0 ::/0 netutil.ZeroPrefix: bad address family 1234
Types ¶
type AddrError ¶
type AddrError struct { // Err is the underlying error, if any. Err error // Kind is the kind of address or address part. Kind AddrKind // Addr is the text of the invalid address. Addr string }
AddrError is the underlying type of errors returned from validation functions when a domain name is invalid.
func (*AddrError) Unwrap ¶
Unwrap implements the errors.Wrapper interface for *AddrError. It returns err.Err.
type AddrFamily ¶
type AddrFamily uint16
AddrFamily is the type for IANA address family numbers.
const ( AddrFamilyNone AddrFamily = 0 AddrFamilyIPv4 AddrFamily = 1 AddrFamilyIPv6 AddrFamily = 2 )
An incomplete list of IANA address family numbers.
See https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml.
func AddrFamilyFromRRType ¶
func AddrFamilyFromRRType(rr uint16) (fam AddrFamily)
AddrFamilyFromRRType returns an AddrFamily appropriate for the DNS resource record type rr. That is, AddrFamilyIPv4 for DNS type A (1), AddrFamilyIPv6 for DNS type AAAA (28), and AddrFamilyNone otherwise.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { // DNS type A. fmt.Println(netutil.AddrFamilyFromRRType(1)) // DNS type AAAA. fmt.Println(netutil.AddrFamilyFromRRType(28)) // Other DNS type. fmt.Println(netutil.AddrFamilyFromRRType(1234)) }
Output: ipv4 ipv6 none
func (AddrFamily) String ¶
func (f AddrFamily) String() (s string)
String implements the fmt.Stringer interface for AddrFamily.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { fmt.Println(netutil.AddrFamilyIPv4, netutil.AddrFamilyIPv6) // An empty family. var fam netutil.AddrFamily fmt.Println(fam) // An unsupported family. fam = netutil.AddrFamily(1234) fmt.Println(fam) }
Output: ipv4 ipv6 none !bad_addr_fam_1234
type AddrKind ¶
type AddrKind = string
AddrKind is a convenient alias for string describing the kind of address and used for error reporting.
const ( AddrKindARPA AddrKind = "arpa domain name" AddrKindCIDR AddrKind = "cidr address" AddrKindHostPort AddrKind = "hostport address" AddrKindIP AddrKind = "ip address" AddrKindIPPort AddrKind = "ipport address" AddrKindIPv4 AddrKind = "ipv4 address" AddrKindMAC AddrKind = "mac address" AddrKindName AddrKind = "hostname" AddrKindDomainName AddrKind = "domain name" AddrKindSRVName AddrKind = "service domain name" )
Kinds of addresses for AddrError.
type HostPort ¶
HostPort is a convenient type for addresses that contain a hostname and a port, like "example.com:12345", "1.2.3.4:56789", or "[1234::cdef]:12345".
func CloneHostPorts ¶
CloneHostPorts returns a deep copy of hps.
func ParseHostPort ¶
ParseHostPort parses a HostPort from addr. Any error returned will have the underlying type of *AddrError.
func (HostPort) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface for HostPort.
Example ¶
package main import ( "encoding/json" "os" "github.com/Potterli20/golibs-fork/netutil" ) func main() { resp := struct { Hosts []netutil.HostPort `json:"hosts"` }{ Hosts: []netutil.HostPort{{ Host: "example.com", Port: 12345, }, { Host: "example.org", Port: 23456, }}, } err := json.NewEncoder(os.Stdout).Encode(resp) if err != nil { panic(err) } respPtrs := struct { HostPtrs []*netutil.HostPort `json:"host_ptrs"` }{ HostPtrs: []*netutil.HostPort{{ Host: "example.com", Port: 12345, }, { Host: "example.org", Port: 23456, }}, } err = json.NewEncoder(os.Stdout).Encode(respPtrs) if err != nil { panic(err) } }
Output: {"hosts":["example.com:12345","example.org:23456"]} {"host_ptrs":["example.com:12345","example.org:23456"]}
func (HostPort) String ¶
String implements the fmt.Stringer interface for *HostPort.
Example ¶
package main import ( "fmt" "github.com/Potterli20/golibs-fork/netutil" ) func main() { hp := &netutil.HostPort{ Host: "example.com", Port: 12345, } fmt.Println(hp) hp.Host = "1234::cdef" fmt.Println(hp) hp.Port = 0 fmt.Println(hp) hp.Host = "" fmt.Println(hp) }
Output: example.com:12345 [1234::cdef]:12345 [1234::cdef]:0 :0
func (*HostPort) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface for *HostPort. Any error returned will have the underlying type of *AddrError.
Example ¶
package main import ( "encoding/json" "fmt" "strings" "github.com/Potterli20/golibs-fork/netutil" ) func main() { resp := &struct { Hosts []netutil.HostPort `json:"hosts"` }{} r := strings.NewReader(`{"hosts":["example.com:12345","example.org:23456"]}`) err := json.NewDecoder(r).Decode(resp) if err != nil { panic(err) } fmt.Printf("%#v\n", resp.Hosts[0]) fmt.Printf("%#v\n", resp.Hosts[1]) respPtrs := &struct { HostPtrs []*netutil.HostPort `json:"host_ptrs"` }{} r = strings.NewReader(`{"host_ptrs":["example.com:12345","example.org:23456"]}`) err = json.NewDecoder(r).Decode(respPtrs) if err != nil { panic(err) } fmt.Printf("%#v\n", respPtrs.HostPtrs[0]) fmt.Printf("%#v\n", respPtrs.HostPtrs[1]) fmt.Println() r = strings.NewReader(`{"host_ptrs":["example.com:99999","example.org:99999"]}`) err = json.NewDecoder(r).Decode(respPtrs) isOutOfRange := err.Error() == `bad hostport address "example.com:99999": `+ `parsing port: strconv.ParseUint: parsing "99999": value out of range` fmt.Printf("got the expected error: %t", isOutOfRange) }
Output: netutil.HostPort{Host:"example.com", Port:0x3039} netutil.HostPort{Host:"example.org", Port:0x5ba0} &netutil.HostPort{Host:"example.com", Port:0x3039} &netutil.HostPort{Host:"example.org", Port:0x5ba0} got the expected error: true
type IPMap
deprecated
type IPMap struct {
// contains filtered or unexported fields
}
IPMap is a map of IP addresses.
Deprecated: Use map[netip.Addr]T instead.
func NewIPMap ¶
NewIPMap returns a new empty IP map using hint as a size hint for the underlying map.
It is not safe for concurrent use, just like the usual Go maps aren't.
func (*IPMap) Clear ¶
func (m *IPMap) Clear()
Clear clears the map but retains its allocated storage. Calling Clear on a nil *IPMap has no effect, just like calling delete in a loop on an empty map doesn't.
func (*IPMap) Del ¶
Del deletes ip from the map. Calling Del on a nil *IPMap has no effect, just like delete on an empty map doesn't.
func (*IPMap) Get ¶
Get returns the value from the map. Calling Get on a nil *IPMap returns nil and false, just like indexing on an empty map does.
func (*IPMap) Len ¶
Len returns the length of the map. A nil *IPMap has a length of zero, just like an empty map.
func (*IPMap) Range ¶
Range calls f with a copy of the key and the value for each key-value pair present in the map in an undefined order. If cont is false, range stops the iteration. Calling Range on a nil *IPMap has no effect, just like ranging over a nil map.
func (*IPMap) Set ¶
Set sets the value. Set panics if the m is a nil *IPMap, just like a nil map does.
func (*IPMap) ShallowClone ¶
ShallowClone returns a shallow clone of the map.
type LabelError ¶
type LabelError struct { // Err is the underlying error, if any. Err error // Kind is the kind of label of the name. Kind LabelKind // Label is the text of the invalid label. Label string }
LabelError is the underlying type of errors returned from validation functions when a label of a name is invalid.
func (*LabelError) Error ¶
func (err *LabelError) Error() (msg string)
Error implements the error interface for *AddrError.
func (*LabelError) Unwrap ¶
func (err *LabelError) Unwrap() (unwrapped error)
Unwrap implements the errors.Wrapper interface for *AddrError. It returns err.Err.
type LabelKind ¶
type LabelKind = string
LabelKind is a convenient alias for string describing the kind of label of a name and used for error reporting.
const ( LabelKindDomain LabelKind = "domain name label" LabelKindHost LabelKind = "hostname label" LabelKindSRV LabelKind = "service name label" LabelKindTLD LabelKind = "top-level domain name label" )
Kinds of labels for LabelError.
type LengthError ¶
type LengthError struct { // Kind is the kind of address or address part. Kind string // Allowed are the allowed lengths for this kind of address. If allowed // is empty, Max should be non-zero. Allowed []int // Max is the maximum length for this part or address kind. If Max is // zero, Allowed should be non-empty. Max int // Length is the length of the provided address. Length int }
LengthError is the underlying type of errors returned from validation functions when an address or a part of an address has a bad length. Kind is either AddrKind or LabelKind.
func (*LengthError) Error ¶
func (err *LengthError) Error() (msg string)
Error implements the error interface for *LengthError.
type RuneError ¶
type RuneError struct { // Kind is the kind of address or address part. Kind string // Rune is the invalid rune. Rune rune }
RuneError is the underlying type of errors returned from validation functions when a rune in the address is invalid. Kind is either AddrKind or LabelKind.
type SliceSubnetSet ¶
SliceSubnetSet is the SubnetSet that checks the address through a slice of *net.IPNet.
type SubnetSet ¶
type SubnetSet interface { // Contains returns true if ip is contained by any of networks the set // contains. ip must be only accessed for reading. Contains(ip net.IP) (ok bool) }
SubnetSet contains the set of IP networks to match the IP address.
Example (Func) ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { s := netutil.SubnetSetFunc(func(ip net.IP) (ok bool) { return len(ip) > 0 && ip[0] == 0xFF }) fmt.Println("contains 255.0.0.1:", s.Contains(net.IP{255, 0, 0, 1})) fmt.Println("contains 254.0.0.1:", s.Contains(net.IP{254, 0, 0, 1})) fmt.Println("contains ff00:::1: ", s.Contains(net.ParseIP("ff00::1"))) fmt.Println("contains ff:::1: ", s.Contains(net.ParseIP("ff::1"))) }
Output: contains 255.0.0.1: true contains 254.0.0.1: false contains ff00:::1: true contains ff:::1: false
Example (Single) ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { var s netutil.SubnetSet _, s, err := net.ParseCIDR("1.2.3.4/16") if err != nil { panic(err) } fmt.Println("contains 1.2.3.4:", s.Contains(net.IP{1, 2, 3, 4})) fmt.Println("contains 4.3.2.1:", s.Contains(net.IP{4, 3, 2, 1})) }
Output: contains 1.2.3.4: true contains 4.3.2.1: false
Example (Slice) ¶
package main import ( "fmt" "net" "github.com/Potterli20/golibs-fork/netutil" ) func main() { nets, err := netutil.ParseSubnets("1.2.3.0/24", "ffff:12ab::/16") if err != nil { panic(err) } s := netutil.SliceSubnetSet(nets) fmt.Println("contains 1.2.3.4: ", s.Contains(net.IP{1, 2, 3, 4})) fmt.Println("contains 4.3.2.1: ", s.Contains(net.IP{4, 3, 2, 1})) fmt.Println("contains ffff:12ab::10:", s.Contains(net.ParseIP("ffff:12ab::10"))) fmt.Println("contains 12ab:ffff::10:", s.Contains(net.ParseIP("12ab:ffff::10"))) fmt.Println() s = netutil.SliceSubnetSet{} fmt.Println("contains 1.2.3.4: ", s.Contains(net.IP{1, 2, 3, 4})) fmt.Println("contains ffff:12ab::10:", s.Contains(net.ParseIP("ffff:12ab::10"))) fmt.Println() s = netutil.SliceSubnetSet{{ IP: make(net.IP, net.IPv4len), Mask: make(net.IPMask, net.IPv4len), }, { IP: make(net.IP, net.IPv6len), Mask: make(net.IPMask, net.IPv6len), }} fmt.Println("contains 1.2.3.4: ", s.Contains(net.IP{1, 2, 3, 4})) fmt.Println("contains ffff:12ab::10:", s.Contains(net.ParseIP("ffff:12ab::10"))) fmt.Println("contains <nil>: ", s.Contains(nil)) }
Output: contains 1.2.3.4: true contains 4.3.2.1: false contains ffff:12ab::10: true contains 12ab:ffff::10: false contains 1.2.3.4: false contains ffff:12ab::10: false contains 1.2.3.4: true contains ffff:12ab::10: true contains <nil>: false
type SubnetSetFunc ¶
SubnetSetFunc is a function determining if ip belongs to the set of subnets.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package sysresolv provides cross-platform functionality to discover DNS resolvers currently used by the system.
|
Package sysresolv provides cross-platform functionality to discover DNS resolvers currently used by the system. |
Package urlutil contains types and utilities for dealing with URLs.
|
Package urlutil contains types and utilities for dealing with URLs. |