diff options
author | Ed Tanous <edtanous@google.com> | 2022-08-15 19:47:37 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2022-09-02 03:33:25 +0300 |
commit | 033f1e4d7ffe66b742b2d3fb6f18f2ba2025afb8 (patch) | |
tree | eadef0db80f2f23dfffdffaddc39e0b00c80a52f | |
parent | 44c70412e763a63310ef9451f24714c4decef91a (diff) | |
download | bmcweb-033f1e4d7ffe66b742b2d3fb6f18f2ba2025afb8.tar.xz |
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 <edtanous@google.com>
Change-Id: I4aac5a98379c9844aea6c21d2294d1ed7ae2ea9b
-rw-r--r-- | redfish-core/include/utils/ip_utils.hpp | 92 | ||||
-rw-r--r-- | redfish-core/lib/ethernet.hpp | 103 | ||||
-rw-r--r-- | 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 <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> @@ -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<std::string> 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 <app.hpp> #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> @@ -581,96 +583,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<std::string> 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 * * @param[in] ifaceId Id of interface whose IP should be deleted @@ -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 <app.hpp> #include <boost/container/flat_set.hpp> #include <dbus_singleton.hpp> @@ -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"); |