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

早过忘川 提交于 2019-12-22 07:51:46

问题


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

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

Does Go provide any utility function ready for this specific 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 Playground


回答1:


If (as your test cases seem to imply) you don't care about which side contains which, but just that there's overlap, this should be sufficient.

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



回答2:


You can use the fact that IP addresses (net.IP) and netmasks (net.IPMask) are simply byte slices ([]byte) that contain the binary IP addresses. You can use the usual bitwise-operators on the network addresses and their masks to determine if one network is a subnet of 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 is missing some basic sanity checks (for example, it would break when passed one IPv4 and one IPv6 address), but the example should be sufficient to get the gist of it.

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

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



来源:https://stackoverflow.com/questions/34729158/how-to-detect-if-two-golang-net-ipnet-objects-intersect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!