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