首页 > 解决方案 > 搜索一个网络是否包含在另一个网络中的功能

问题描述

我需要一种有效的方法来获取一个 CIDR 网络并测试它是否完全包含在其他网络中。

例子:

var (
    subnet string = "10.10.10.8/29"
    route string = "10.10.10.0/24"
)

我想测试“子网”是否在“路由”中并返回 true,因为它是。对于不在 'route' 内或部分在其外的值返回 false。

我有一个解决方案,用于测试单个主机是否在使用 IP/CIDR 解析和包网络中的“x.Contains()”的网络中。我曾尝试将其用于网络,但失败了。

这不起作用: .

if route.Contains(subnet) {
    fmt.Println("%s subnet is contained subnet %s",net, route)
}

编辑:显然对此有些困惑。本段上方的代码片段对我来说无法测试一个网络是否在另一个网络中。SO溢出指南要求我具体说明我尝试过的内容,这就是我将其放在这里的原因。这是我的第一个 SO 帖子。

我有一些想法比我想以这个为主导的想法更庞大:

计算“子网”的第一个IP(网络IP)和最后一个IP(广播IP),使用“net.ParseCIDR()”和已知的子网大小作为常数,然后测试“子网”的网络和广播IP是否都是在“路线”中使用“x.Contains()”。

编辑:我在最初的搜索中没有看到这个线程,但现在遇到了。它是相似的,所以我在这里链接是为了完整性。[如何检测两个 Golang net.IPNet 对象是否相交?]

标签: go

解决方案


对于任何x和IPv4,以及从 0 到y32 的任何整数,网络都包含在当且仅当且在中(您可以自己对此进行证明)。因此,以下将起作用:mnx/my/nm >= nxy/n

func contains(subnet, route string) (bool, error) {
    sIP, sNW, err := net.ParseCIDR(subnet)
    if err != nil {
        return false, err
    }

    _, rNW, err := net.ParseCIDR(route)
    if err != nil {
        return false, err
    }

    sNWMaskSize, _ := sNW.Mask.Size()
    rNWMaskSize, _ := rNW.Mask.Size()

    return rNW.Contains(sIP) && sNWMaskSize >= rNWMaskSize, nil
}

推荐阅读