Go 1.18
You can use the new package net/netip
. The package defines the type netip.Addr
which is a significant improvement over the old one:
Compared to the net.IP type, this package's Addr type takes less memory, is immutable, and is comparable (supports == and being a map key).
You can check if an IP is within a network with the method Prefix.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. If ip has an IPv6 zone, Contains returns false, because
Prefixes strip zones.
An example:
package main
import (
"fmt"
"net/netip"
)
func main() {
network, err := netip.ParsePrefix("172.17.0.0/16")
if err != nil {
panic(err)
}
ip, err := netip.ParseAddr("172.17.0.2")
if err != nil {
panic(err)
}
b := network.Contains(ip)
fmt.Println(b) // true
}
If the IP you want to check also has the subnet mask, like 172.17.0.2/16
as in your example, you can use ip, err := netip.ParsePrefix
again, and then obtain the address with ip.Addr()
and pass that to Contains
.
Code in the playground: https://go.dev/play/p/ikWRpPa1egI
For those who are interested in the implementation details, you can see this blog post by Brad Fitzpatrick (former member of the Go team). The net/netip
package is based on that work.