// public bool IPAddress::inSubnetWithMask(const IPAddress& subnet, ByteRange mask) const { auto mkByteArray4 = [&]() -> ByteArray4 { ByteArray4 ba{{0}}; std::memcpy(ba.data(), mask.begin(), std::min<size_t>(mask.size(), 4)); return ba; }; if (bitCount() == subnet.bitCount()) { if (isV4()) { return asV4().inSubnetWithMask(subnet.asV4(), mkByteArray4()); } else { ByteArray16 ba{{0}}; std::memcpy(ba.data(), mask.begin(), std::min<size_t>(mask.size(), 16)); return asV6().inSubnetWithMask(subnet.asV6(), ba); } } // an IPv4 address can never belong in a IPv6 subnet unless the IPv6 is a 6to4 // address and vice-versa if (isV6()) { const IPAddressV6& v6addr = asV6(); const IPAddressV4& v4subnet = subnet.asV4(); if (v6addr.is6To4()) { return v6addr.getIPv4For6To4().inSubnetWithMask(v4subnet, mkByteArray4()); } } else if (subnet.isV6()) { const IPAddressV6& v6subnet = subnet.asV6(); const IPAddressV4& v4addr = asV4(); if (v6subnet.is6To4()) { return v4addr.inSubnetWithMask(v6subnet.getIPv4For6To4(), mkByteArray4()); } } return false; }
// public bool IPAddress::inSubnet(const IPAddress& subnet, uint8_t cidr) const { if (bitCount() == subnet.bitCount()) { if (isV4()) { return asV4().inSubnet(subnet.asV4(), cidr); } else { return asV6().inSubnet(subnet.asV6(), cidr); } } // an IPv4 address can never belong in a IPv6 subnet unless the IPv6 is a 6to4 // address and vice-versa if (isV6()) { const IPAddressV6& v6addr = asV6(); const IPAddressV4& v4subnet = subnet.asV4(); if (v6addr.is6To4()) { return v6addr.getIPv4For6To4().inSubnet(v4subnet, cidr); } } else if (subnet.isV6()) { const IPAddressV6& v6subnet = subnet.asV6(); const IPAddressV4& v4addr = asV4(); if (v6subnet.is6To4()) { return v4addr.inSubnet(v6subnet.getIPv4For6To4(), cidr); } } return false; }