У меня есть следующий код для поиска диапазона IP-адресов v4. Работает отлично:
uint32_t byte1 = 0, byte2 = 0, byte3 = 0, byte4 = 0, significantBits = 0;
int read = sscanf(ipRangeStr.c_str(), "%3d.%3d.%3d.%3d/%2u", &byte1, &byte2, &byte3, &byte4, &significant);
if (read < 4) {
throw std::runtime_error("Cannot parse ip range: " + ipRangeStr);
}
uint32_t ip = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
uint32_t from = 0, to = 0;
if (4 == read || 32 == significantBits) {
from = ip;
to = ip + 1;
} else {
if (significantBits > 32) {
throw std::runtime_error("Cannot parse ip range: " + ipRangeStr);
}
const uint8_t insignificantBits = 32 - significantBits;
from = ip & (0xFFFFFFFF << insignificantBits);
to = (ip | ((1 << insignificantBits) - 1)) + 1;
}
Еще я написал код для расчета диапазона IP-адресов для IPv6 с сопоставлением IPv4-адресов:
std::string significantBitsStr;
std::string ipRangeStrWithoutSignificantBits;
const size_t position = ipRangeStr.find("/");
if (position != std::string::npos) {
significantBitsStr = ipRangeStr.substr(position + 1u);
ipRangeStrWithoutSignificantBits = ipRangeStr.substr(0u, position);
}
std::string ipV6Address;
boost::system::error_code status;
bool mappedV4Address = false;
boost::asio::ip::address_v6::bytes_type bytes;
boost::asio::ip::address address = boost::asio::ip::address::from_string(ipRangeStrWithoutSignificantBits, status);
if (status != boost::system::errc::success) {
throw std::runtime_error("Cannot parse ip range: " + ipRangeStr);
} else if (address.is_v6()) {
ipV6Address = address.to_string();
bytes = address.to_v6().to_bytes();
} else if (address.is_v4()) {
boost::asio::ip::address_v6 addressV6 = boost::asio::ip::address_v6::v4_mapped(address.to_v4());
ipV6Address = addressV6.to_string();
bytes = addressV6.to_bytes();
mappedV4Address = true;
}
boost::multiprecision::uint128_t ip = 0u;
for (const auto byte : bytes) {
(ip <<= 8u) |= byte;
}
boost::multiprecision::uint128_t from = 0u, to = 0u;
const auto significantBits = boost::lexical_cast<uint32_t>(significantBitsStr);
if ((mappedV4Address && significantBits > 32u) || (significantBits > 128u)) {
throw std::runtime_error("Cannot parse ip range: " + ipRangeStr + " - incorrect significant bits.");
} else if ((mappedV4Address && significantBits == 32u) || (significantBits == 128u)) {
from = ip;
to = ip + 1;
} else {
// Theses interval calculates incorrectly
const uint8_t insignificantBits = 128u - significantBits;
from = ip & (0xFFFFFFFF << insignificantBits);
to = (ip | ((1u << insignificantBits) - 1)) + 1;
}
Но диапазон вычисляется неправильно ... Проблема только с этим кодом :
const uint8_t insignificantBits = 128u - significantBits;
from = ip & (0xFFFFFFFF << insignificantBits);
to = (ip | ((1u << insignificantBits) - 1)) + 1;
Как мне исправить этот код для расчета диапазонов IPv6?