141d61c82SJiaqing Zhao #pragma once 241d61c82SJiaqing Zhao 341d61c82SJiaqing Zhao #include <boost/asio/ip/address.hpp> 4d5c80ad9SNan Zhou #include <boost/asio/ip/address_v4.hpp> 5d5c80ad9SNan Zhou #include <boost/asio/ip/address_v6.hpp> 641d61c82SJiaqing Zhao 741d61c82SJiaqing Zhao #include <string> 841d61c82SJiaqing Zhao 941d61c82SJiaqing Zhao namespace redfish 1041d61c82SJiaqing Zhao { 1141d61c82SJiaqing Zhao namespace ip_util 1241d61c82SJiaqing Zhao { 1341d61c82SJiaqing Zhao 1441d61c82SJiaqing Zhao /** 1541d61c82SJiaqing Zhao * @brief Converts boost::asio::ip::address to string 1641d61c82SJiaqing Zhao * Will automatically convert IPv4-mapped IPv6 address back to IPv4. 1741d61c82SJiaqing Zhao * 1841d61c82SJiaqing Zhao * @param[in] ipAddr IP address to convert 1941d61c82SJiaqing Zhao * 2041d61c82SJiaqing Zhao * @return IP address string 2141d61c82SJiaqing Zhao */ 2241d61c82SJiaqing Zhao inline std::string toString(const boost::asio::ip::address& ipAddr) 2341d61c82SJiaqing Zhao { 2441d61c82SJiaqing Zhao if (ipAddr.is_v6() && ipAddr.to_v6().is_v4_mapped()) 2541d61c82SJiaqing Zhao { 2641d61c82SJiaqing Zhao return boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, 2741d61c82SJiaqing Zhao ipAddr.to_v6()) 2841d61c82SJiaqing Zhao .to_string(); 2941d61c82SJiaqing Zhao } 3041d61c82SJiaqing Zhao return ipAddr.to_string(); 3141d61c82SJiaqing Zhao } 3241d61c82SJiaqing Zhao 33033f1e4dSEd Tanous /** 34033f1e4dSEd Tanous * @brief Helper function that verifies IP address to check if it is in 35033f1e4dSEd Tanous * proper format. If bits pointer is provided, also calculates active 36033f1e4dSEd Tanous * bit count for Subnet Mask. 37033f1e4dSEd Tanous * 38033f1e4dSEd Tanous * @param[in] ip IP that will be verified 39033f1e4dSEd Tanous * @param[out] bits Calculated mask in bits notation 40033f1e4dSEd Tanous * 41033f1e4dSEd Tanous * @return true in case of success, false otherwise 42033f1e4dSEd Tanous */ 43033f1e4dSEd Tanous inline bool ipv4VerifyIpAndGetBitcount(const std::string& ip, 44*3a4ad5d9SEd Tanous uint8_t* prefixLength = nullptr) 45033f1e4dSEd Tanous { 46*3a4ad5d9SEd Tanous boost::system::error_code ec; 47*3a4ad5d9SEd Tanous boost::asio::ip::address_v4 addr = boost::asio::ip::make_address_v4(ip, ec); 48*3a4ad5d9SEd Tanous if (ec) 49033f1e4dSEd Tanous { 50033f1e4dSEd Tanous return false; 51033f1e4dSEd Tanous } 52033f1e4dSEd Tanous 53*3a4ad5d9SEd Tanous if (prefixLength != nullptr) 54033f1e4dSEd Tanous { 55*3a4ad5d9SEd Tanous uint8_t prefix = 0; 56*3a4ad5d9SEd Tanous boost::asio::ip::address_v4::bytes_type maskBytes = addr.to_bytes(); 57*3a4ad5d9SEd Tanous bool maskFinished = false; 58*3a4ad5d9SEd Tanous for (unsigned char byte : maskBytes) 59033f1e4dSEd Tanous { 60*3a4ad5d9SEd Tanous if (maskFinished) 61*3a4ad5d9SEd Tanous { 62*3a4ad5d9SEd Tanous if (byte != 0U) 63033f1e4dSEd Tanous { 64033f1e4dSEd Tanous return false; 65033f1e4dSEd Tanous } 66*3a4ad5d9SEd Tanous continue; 67*3a4ad5d9SEd Tanous } 68*3a4ad5d9SEd Tanous switch (byte) 69033f1e4dSEd Tanous { 70*3a4ad5d9SEd Tanous case 255: 71*3a4ad5d9SEd Tanous prefix += 8; 72*3a4ad5d9SEd Tanous break; 73*3a4ad5d9SEd Tanous case 254: 74*3a4ad5d9SEd Tanous prefix += 7; 75*3a4ad5d9SEd Tanous maskFinished = true; 76*3a4ad5d9SEd Tanous break; 77*3a4ad5d9SEd Tanous case 252: 78*3a4ad5d9SEd Tanous prefix += 6; 79*3a4ad5d9SEd Tanous maskFinished = true; 80*3a4ad5d9SEd Tanous break; 81*3a4ad5d9SEd Tanous case 248: 82*3a4ad5d9SEd Tanous prefix += 5; 83*3a4ad5d9SEd Tanous maskFinished = true; 84*3a4ad5d9SEd Tanous break; 85*3a4ad5d9SEd Tanous case 240: 86*3a4ad5d9SEd Tanous prefix += 4; 87*3a4ad5d9SEd Tanous maskFinished = true; 88*3a4ad5d9SEd Tanous break; 89*3a4ad5d9SEd Tanous case 224: 90*3a4ad5d9SEd Tanous prefix += 3; 91*3a4ad5d9SEd Tanous maskFinished = true; 92*3a4ad5d9SEd Tanous break; 93*3a4ad5d9SEd Tanous case 192: 94*3a4ad5d9SEd Tanous prefix += 2; 95*3a4ad5d9SEd Tanous maskFinished = true; 96*3a4ad5d9SEd Tanous break; 97*3a4ad5d9SEd Tanous case 128: 98*3a4ad5d9SEd Tanous prefix += 1; 99*3a4ad5d9SEd Tanous maskFinished = true; 100*3a4ad5d9SEd Tanous break; 101*3a4ad5d9SEd Tanous case 0: 102*3a4ad5d9SEd Tanous maskFinished = true; 103*3a4ad5d9SEd Tanous break; 104*3a4ad5d9SEd Tanous default: 105*3a4ad5d9SEd Tanous // Invalid netmask 106033f1e4dSEd Tanous return false; 107033f1e4dSEd Tanous } 108033f1e4dSEd Tanous } 109*3a4ad5d9SEd Tanous *prefixLength = prefix; 110033f1e4dSEd Tanous } 111033f1e4dSEd Tanous 112033f1e4dSEd Tanous return true; 113033f1e4dSEd Tanous } 114033f1e4dSEd Tanous 11541d61c82SJiaqing Zhao } // namespace ip_util 11641d61c82SJiaqing Zhao } // namespace redfish 117