Search code examples
goipcidr

net.IPNet inside other net.IPNet?


In net.IPNet type we have the Contains method to check if a net.IP is inside it. But what I want is to know if a net.IPNet is inside another net.IPNet. I tried a solution working with big.Int but it didn't work (also, the function interface was terrible). Any ideas?

// ipnet2 contains ipnet1 ?
func ContainsCIDR(ipnet1, ipnet2 net.IPNet) bool {
    var begin big.Int
    begin.SetBytes([]byte(ipnet1.IP))

    var mask big.Int
    mask.SetBytes([]byte(ipnet1.Mask))

    var diff big.Int
    diff.Xor(&begin, &mask)

    var end big.Int
    end.Add(&begin, &diff)

    ipBegin := net.IP(begin.Bytes())
    ipEnd := net.IP(end.Bytes())

    return ipnet2.Contains(ipBegin) && ipnet2.Contains(ipEnd)
}

Solution

  • Check that the mask for the outer subnet is the same size or smaller than the inner, then verify that the starting address for the inner subnet is contained in the outer:

    func ContainsCIDR(ipnet1, ipnet2 *net.IPNet) bool {
        ones1, _ := ipnet1.Mask.Size()
        ones2, _ := ipnet2.Mask.Size()
        return ones1 <= ones2 && ipnet1.Contains(ipnet2.IP)
    }