From 033f1e4d7ffe66b742b2d3fb6f18f2ba2025afb8 Mon Sep 17 00:00:00 2001 From: Ed Tanous Date: Mon, 15 Aug 2022 09:47:37 -0700 Subject: Move ipv4VerifyIpAndGetBitcount into ip_utils This is a minor reorganization of helper code from ethernet (which is redfish specific) into utils. This function is generic, and should be in ip utils. Tested: Code compiles. Code move only. Signed-off-by: Ed Tanous Change-Id: I4aac5a98379c9844aea6c21d2294d1ed7ae2ea9b --- redfish-core/include/utils/ip_utils.hpp | 92 ++++++++++++++++++++++++++++ redfish-core/lib/ethernet.hpp | 103 +++----------------------------- redfish-core/lib/hypervisor_system.hpp | 9 ++- 3 files changed, 106 insertions(+), 98 deletions(-) diff --git a/redfish-core/include/utils/ip_utils.hpp b/redfish-core/include/utils/ip_utils.hpp index 815243eb1d..2d9b138400 100644 --- a/redfish-core/include/utils/ip_utils.hpp +++ b/redfish-core/include/utils/ip_utils.hpp @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include #include @@ -30,5 +32,95 @@ inline std::string toString(const boost::asio::ip::address& ipAddr) return ipAddr.to_string(); } +/** + * @brief Helper function that verifies IP address to check if it is in + * proper format. If bits pointer is provided, also calculates active + * bit count for Subnet Mask. + * + * @param[in] ip IP that will be verified + * @param[out] bits Calculated mask in bits notation + * + * @return true in case of success, false otherwise + */ +inline bool ipv4VerifyIpAndGetBitcount(const std::string& ip, + uint8_t* bits = nullptr) +{ + std::vector bytesInMask; + + boost::split(bytesInMask, ip, boost::is_any_of(".")); + + static const constexpr int ipV4AddressSectionsCount = 4; + if (bytesInMask.size() != ipV4AddressSectionsCount) + { + return false; + } + + if (bits != nullptr) + { + *bits = 0; + } + + char* endPtr = nullptr; + long previousValue = 255; + bool firstZeroInByteHit = false; + for (const std::string& byte : bytesInMask) + { + 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) + { + 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 ((value & (1L << bitIdx)) != 0) + { + if (firstZeroInByteHit) + { + // Continuity not preserved + return false; + } + (*bits)++; + } + else + { + firstZeroInByteHit = true; + } + } + } + + previousValue = value; + } + + return true; +} + } // namespace ip_util } // namespace redfish diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp index 0469f74098..342884533a 100644 --- a/redfish-core/lib/ethernet.hpp +++ b/redfish-core/lib/ethernet.hpp @@ -15,6 +15,8 @@ */ #pragma once +#include "utils/ip_utils.hpp" + #include #include #include @@ -580,96 +582,6 @@ inline void } } -/** - * @brief Helper function that verifies IP address to check if it is in - * proper format. If bits pointer is provided, also calculates active - * bit count for Subnet Mask. - * - * @param[in] ip IP that will be verified - * @param[out] bits Calculated mask in bits notation - * - * @return true in case of success, false otherwise - */ -inline bool ipv4VerifyIpAndGetBitcount(const std::string& ip, - uint8_t* bits = nullptr) -{ - std::vector bytesInMask; - - boost::split(bytesInMask, ip, boost::is_any_of(".")); - - static const constexpr int ipV4AddressSectionsCount = 4; - if (bytesInMask.size() != ipV4AddressSectionsCount) - { - return false; - } - - if (bits != nullptr) - { - *bits = 0; - } - - char* endPtr = nullptr; - long previousValue = 255; - bool firstZeroInByteHit = false; - for (const std::string& byte : bytesInMask) - { - 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) - { - 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 ((value & (1L << bitIdx)) != 0) - { - if (firstZeroInByteHit) - { - // Continuity not preserved - return false; - } - (*bits)++; - } - else - { - firstZeroInByteHit = true; - } - } - } - - previousValue = value; - } - - return true; -} - /** * @brief Deletes given IPv4 interface * @@ -1402,7 +1314,7 @@ inline void handleIPv4StaticPatch( bool errorInEntry = false; if (address) { - if (ipv4VerifyIpAndGetBitcount(*address)) + if (ip_util::ipv4VerifyIpAndGetBitcount(*address)) { addr = &(*address); } @@ -1426,7 +1338,8 @@ inline void handleIPv4StaticPatch( if (subnetMask) { - if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength)) + if (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask, + &prefixLength)) { messages::propertyValueFormatError( asyncResp->res, *subnetMask, @@ -1436,8 +1349,8 @@ inline void handleIPv4StaticPatch( } else if (nicIpEntry != ipv4Data.cend()) { - if (!ipv4VerifyIpAndGetBitcount(nicIpEntry->netmask, - &prefixLength)) + if (!ip_util::ipv4VerifyIpAndGetBitcount(nicIpEntry->netmask, + &prefixLength)) { messages::propertyValueFormatError( asyncResp->res, nicIpEntry->netmask, @@ -1454,7 +1367,7 @@ inline void handleIPv4StaticPatch( if (gateway) { - if (ipv4VerifyIpAndGetBitcount(*gateway)) + if (ip_util::ipv4VerifyIpAndGetBitcount(*gateway)) { gw = &(*gateway); } diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp index 34227618d1..5c60016841 100644 --- a/redfish-core/lib/hypervisor_system.hpp +++ b/redfish-core/lib/hypervisor_system.hpp @@ -1,5 +1,7 @@ #pragma once +#include "utils/ip_utils.hpp" + #include #include #include @@ -607,7 +609,7 @@ inline void handleHypervisorIPv4StaticPatch( bool errorInEntry = false; if (address) { - if (!ipv4VerifyIpAndGetBitcount(*address)) + if (!ip_util::ipv4VerifyIpAndGetBitcount(*address)) { messages::propertyValueFormatError(asyncResp->res, *address, pathString + "/Address"); @@ -622,7 +624,8 @@ inline void handleHypervisorIPv4StaticPatch( if (subnetMask) { - if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength)) + if (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask, + &prefixLength)) { messages::propertyValueFormatError(asyncResp->res, *subnetMask, pathString + "/SubnetMask"); @@ -638,7 +641,7 @@ inline void handleHypervisorIPv4StaticPatch( if (gateway) { - if (!ipv4VerifyIpAndGetBitcount(*gateway)) + if (!ip_util::ipv4VerifyIpAndGetBitcount(*gateway)) { messages::propertyValueFormatError(asyncResp->res, *gateway, pathString + "/Gateway"); -- cgit v1.2.3