How to determine if two Golang net.IPNet objects intersect?

How to determine if there is an intersection between two Golang net.IPNet objects?

That is, how to check how , if the first network is a subnet of the second OR , if the second network is a subnet of the first.

Does Go provide any useful feature ready for this particular task?

See test code below.

package main import ( "fmt" "net" ) func main() { _, net1, _ := net.ParseCIDR("1.1.1.1/24") _, net2, _ := net.ParseCIDR("1.1.0.2/16") _, net3, _ := net.ParseCIDR("1.1.1.3/25") _, net4, _ := net.ParseCIDR("1.2.0.4/16") test(net1, net2, true) test(net2, net1, true) test(net1, net3, true) test(net3, net1, true) test(net1, net4, false) test(net4, net1, false) } func test(n1, n2 *net.IPNet, expect bool) { result := intersect(n1, n2) var label string if result == expect { label = "good" } else { label = "FAIL" } fmt.Printf("test intersect(%v,%v)=%v expected=%v => %s\n", n1, n2, result, expect, label) } func intersect(n1, n2 *net.IPNet) bool { return false // FIXME WRITEME } 

Run it on Go to the Playground

+5
source share
2 answers

If (as it seems to you, as your test examples show), it doesn’t matter which side contains, but just overlap, that should be enough.

 func intersect(n1, n2 *net.IPNet) bool { return n2.Contains(n1.IP) || n1.Contains(n2.IP) } 
+5
source

You can use the fact that IP addresses ( net.IP ) and network masks ( net.IPMask ) are just byte fragments ( []byte ) containing binary IP addresses. You can use regular bitwise operators on network addresses and their masks to determine if one subnet network is another:

 func intersect(n1, n2 *net.IPNet) bool { for i := range n1.IP { if n1.IP[i] & n1.Mask[i] != n2.IP[i] & n2.Mask[i] & n1.Mask[i] { return false } } return true } 

This function does not have some basic health checks (for example, it is interrupted when one IPv4 and one IPv6 address are transmitted), but this example should be enough to get its gist.

It succeeds in all test cases from your question except the first. But in the end, 1.1.0.2/16 is not really a 1.1.1.1/24 subnet (it's the other way around).

https://play.golang.org/p/Kur5n2hfLg

+3
source

Source: https://habr.com/ru/post/1240376/


All Articles