1 #pragma once 2 3 #include <boost/asio/ip/address.hpp> 4 #include <boost/asio/ip/address_v4.hpp> 5 #include <boost/asio/ip/address_v6.hpp> 6 7 #include <string> 8 9 namespace redfish 10 { 11 namespace ip_util 12 { 13 14 /** 15 * @brief Converts boost::asio::ip::address to string 16 * Will automatically convert IPv4-mapped IPv6 address back to IPv4. 17 * 18 * @param[in] ipAddr IP address to convert 19 * 20 * @return IP address string 21 */ 22 inline std::string toString(const boost::asio::ip::address& ipAddr) 23 { 24 if (ipAddr.is_v6() && ipAddr.to_v6().is_v4_mapped()) 25 { 26 return boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, 27 ipAddr.to_v6()) 28 .to_string(); 29 } 30 return ipAddr.to_string(); 31 } 32 33 /** 34 * @brief Helper function that verifies IP address to check if it is in 35 * proper format. If bits pointer is provided, also calculates active 36 * bit count for Subnet Mask. 37 * 38 * @param[in] ip IP that will be verified 39 * @param[out] bits Calculated mask in bits notation 40 * 41 * @return true in case of success, false otherwise 42 */ 43 inline bool ipv4VerifyIpAndGetBitcount(const std::string& ip, 44 uint8_t* prefixLength = nullptr) 45 { 46 boost::system::error_code ec; 47 boost::asio::ip::address_v4 addr = boost::asio::ip::make_address_v4(ip, ec); 48 if (ec) 49 { 50 return false; 51 } 52 53 if (prefixLength != nullptr) 54 { 55 uint8_t prefix = 0; 56 boost::asio::ip::address_v4::bytes_type maskBytes = addr.to_bytes(); 57 bool maskFinished = false; 58 for (unsigned char byte : maskBytes) 59 { 60 if (maskFinished) 61 { 62 if (byte != 0U) 63 { 64 return false; 65 } 66 continue; 67 } 68 switch (byte) 69 { 70 case 255: 71 prefix += 8; 72 break; 73 case 254: 74 prefix += 7; 75 maskFinished = true; 76 break; 77 case 252: 78 prefix += 6; 79 maskFinished = true; 80 break; 81 case 248: 82 prefix += 5; 83 maskFinished = true; 84 break; 85 case 240: 86 prefix += 4; 87 maskFinished = true; 88 break; 89 case 224: 90 prefix += 3; 91 maskFinished = true; 92 break; 93 case 192: 94 prefix += 2; 95 maskFinished = true; 96 break; 97 case 128: 98 prefix += 1; 99 maskFinished = true; 100 break; 101 case 0: 102 maskFinished = true; 103 break; 104 default: 105 // Invalid netmask 106 return false; 107 } 108 } 109 *prefixLength = prefix; 110 } 111 112 return true; 113 } 114 115 } // namespace ip_util 116 } // namespace redfish 117