28 #include <boost/lexical_cast.hpp>
29 #include <boost/utility/value_init.hpp>
41 const boost::asio::ip::address& maxAddress)
42 : m_minAddress(minAddress)
43 , m_maxAddress(maxAddress)
50 using boost::asio::ip::address_v4;
51 static const Network range{address_v4{}, address_v4{0xffffffff}};
58 using boost::asio::ip::address_v6;
59 static const address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
61 static const Network range{address_v6{}, address_v6{maxV6}};
68 auto pos = cidr.find(
'/');
69 if (pos == std::string::npos) {
74 boost::lexical_cast<Network>(cidr);
77 catch (
const boost::bad_lexical_cast&) {
85 return os << network.m_minAddress <<
" <-> " << network.m_maxAddress;
91 namespace ip = boost::asio::ip;
93 std::string networkStr;
96 size_t position = networkStr.find(
'/');
97 if (position == std::string::npos) {
99 network.m_minAddress = ip::make_address(networkStr);
100 network.m_maxAddress = ip::make_address(networkStr);
102 catch (
const boost::system::system_error&) {
103 is.setstate(std::ios::failbit);
108 boost::system::error_code ec;
109 auto address = ip::make_address(networkStr.substr(0, position), ec);
111 is.setstate(std::ios::failbit);
115 auto prefixLenStr = networkStr.substr(position + 1);
116 if (!std::all_of(prefixLenStr.begin(), prefixLenStr.end(),
117 [] (
unsigned char c) { return std::isdigit(c); })) {
118 is.setstate(std::ios::failbit);
123 mask = boost::lexical_cast<size_t>(prefixLenStr);
125 catch (
const boost::bad_lexical_cast&) {
126 is.setstate(std::ios::failbit);
130 if (address.is_v4()) {
132 is.setstate(std::ios::failbit);
136 ip::address_v4::bytes_type maskBytes = boost::initialized_value;
137 for (
size_t i = 0; i < mask; i++) {
138 size_t byteId = i / 8;
139 size_t bitIndex = 7 - i % 8;
140 maskBytes[byteId] |= (1 << bitIndex);
143 ip::address_v4::bytes_type addressBytes = address.to_v4().to_bytes();
144 ip::address_v4::bytes_type min;
145 ip::address_v4::bytes_type max;
147 for (
size_t i = 0; i < addressBytes.size(); i++) {
148 min[i] = addressBytes[i] & maskBytes[i];
149 max[i] = addressBytes[i] | ~(maskBytes[i]);
152 network.m_minAddress = ip::address_v4(min);
153 network.m_maxAddress = ip::address_v4(max);
157 is.setstate(std::ios::failbit);
161 ip::address_v6::bytes_type maskBytes = boost::initialized_value;
162 for (
size_t i = 0; i < mask; i++) {
163 size_t byteId = i / 8;
164 size_t bitIndex = 7 - i % 8;
165 maskBytes[byteId] |= (1 << bitIndex);
168 ip::address_v6::bytes_type addressBytes = address.to_v6().to_bytes();
169 ip::address_v6::bytes_type min;
170 ip::address_v6::bytes_type max;
172 for (
size_t i = 0; i < addressBytes.size(); i++) {
173 min[i] = addressBytes[i] & maskBytes[i];
174 max[i] = addressBytes[i] | ~(maskBytes[i]);
177 network.m_minAddress = ip::address_v6(min);
178 network.m_maxAddress = ip::address_v6(max);
static bool isValidCidr(std::string_view cidr) noexcept
static const Network & getMaxRangeV6()
static const Network & getMaxRangeV4()
std::ostream & operator<<(std::ostream &os, const Network &network)
std::istream & operator>>(std::istream &is, Network &network)