diff options
Diffstat (limited to 'redfish-core/include/utils/ip_utils.hpp')
-rw-r--r-- | redfish-core/include/utils/ip_utils.hpp | 118 |
1 files changed, 54 insertions, 64 deletions
diff --git a/redfish-core/include/utils/ip_utils.hpp b/redfish-core/include/utils/ip_utils.hpp index 2d9b138400..9b18fccce2 100644 --- a/redfish-core/include/utils/ip_utils.hpp +++ b/redfish-core/include/utils/ip_utils.hpp @@ -1,7 +1,5 @@ #pragma once -#include <boost/algorithm/string/classification.hpp> -#include <boost/algorithm/string/split.hpp> #include <boost/asio/ip/address.hpp> #include <boost/asio/ip/address_v4.hpp> #include <boost/asio/ip/address_v6.hpp> @@ -43,80 +41,72 @@ inline std::string toString(const boost::asio::ip::address& ipAddr) * @return true in case of success, false otherwise */ inline bool ipv4VerifyIpAndGetBitcount(const std::string& ip, - uint8_t* bits = nullptr) + uint8_t* prefixLength = nullptr) { - std::vector<std::string> bytesInMask; - - boost::split(bytesInMask, ip, boost::is_any_of(".")); - - static const constexpr int ipV4AddressSectionsCount = 4; - if (bytesInMask.size() != ipV4AddressSectionsCount) + boost::system::error_code ec; + boost::asio::ip::address_v4 addr = boost::asio::ip::make_address_v4(ip, ec); + if (ec) { return false; } - if (bits != nullptr) - { - *bits = 0; - } - - char* endPtr = nullptr; - long previousValue = 255; - bool firstZeroInByteHit = false; - for (const std::string& byte : bytesInMask) + if (prefixLength != nullptr) { - if (byte.empty()) - { - return false; - } - - // Use strtol instead of stroi to avoid exceptions - long value = std::strtol(byte.c_str(), &endPtr, 10); - - // endPtr should point to the end of the string, otherwise given string - // is not 100% number - if (*endPtr != '\0') - { - return false; - } - - // Value should be contained in byte - if (value < 0 || value > 255) + uint8_t prefix = 0; + boost::asio::ip::address_v4::bytes_type maskBytes = addr.to_bytes(); + bool maskFinished = false; + for (unsigned char byte : maskBytes) { - return false; - } - - if (bits != nullptr) - { - // Mask has to be continuous between bytes - if (previousValue != 255 && value != 0) - { - return false; - } - - // Mask has to be continuous inside bytes - firstZeroInByteHit = false; - - // Count bits - for (long bitIdx = 7; bitIdx >= 0; bitIdx--) + if (maskFinished) { - if ((value & (1L << bitIdx)) != 0) - { - if (firstZeroInByteHit) - { - // Continuity not preserved - return false; - } - (*bits)++; - } - else + if (byte != 0U) { - firstZeroInByteHit = true; + return false; } + continue; + } + switch (byte) + { + case 255: + prefix += 8; + break; + case 254: + prefix += 7; + maskFinished = true; + break; + case 252: + prefix += 6; + maskFinished = true; + break; + case 248: + prefix += 5; + maskFinished = true; + break; + case 240: + prefix += 4; + maskFinished = true; + break; + case 224: + prefix += 3; + maskFinished = true; + break; + case 192: + prefix += 2; + maskFinished = true; + break; + case 128: + prefix += 1; + maskFinished = true; + break; + case 0: + maskFinished = true; + break; + default: + // Invalid netmask + return false; } } - - previousValue = value; + *prefixLength = prefix; } return true; |