///////////////////////////////////////////////////////
| 107 | |
| 108 | //////////////////////////////////////////////////////////// |
| 109 | std::optional<IpAddress> IpAddress::fromString(std::string_view address) |
| 110 | { |
| 111 | using namespace std::string_view_literals; |
| 112 | |
| 113 | if (address.empty()) |
| 114 | return std::nullopt; |
| 115 | |
| 116 | // Optimizations for known address strings |
| 117 | if (address == "0.0.0.0"sv) |
| 118 | return AnyV4; |
| 119 | |
| 120 | if (address == "127.0.0.1"sv) |
| 121 | return LocalHostV4; |
| 122 | |
| 123 | if (address == "255.255.255.255"sv) |
| 124 | return BroadcastV4; |
| 125 | |
| 126 | // Optimizations for known address strings |
| 127 | if (address == "::"sv) |
| 128 | return AnyV6; |
| 129 | |
| 130 | if (address == "::1"sv) |
| 131 | return LocalHostV6; |
| 132 | |
| 133 | // inet_pton expects the string to be null-terminated |
| 134 | const std::string addressString(address); |
| 135 | |
| 136 | // Try to convert the address from dotted-decimal notation ("xxx.xxx.xxx.xxx") |
| 137 | if (in_addr addr{}; inet_pton(AF_INET, addressString.c_str(), &addr) == 1) |
| 138 | return IpAddress(ntohl(addr.s_addr)); |
| 139 | |
| 140 | // Try to convert the address from internet standard notation ("xxxx:xxxx::xxxx:xxxx") |
| 141 | if (in6_addr addr{}; inet_pton(AF_INET6, addressString.c_str(), &addr) == 1) |
| 142 | return IpAddress( |
| 143 | {addr.s6_addr[0], |
| 144 | addr.s6_addr[1], |
| 145 | addr.s6_addr[2], |
| 146 | addr.s6_addr[3], |
| 147 | addr.s6_addr[4], |
| 148 | addr.s6_addr[5], |
| 149 | addr.s6_addr[6], |
| 150 | addr.s6_addr[7], |
| 151 | addr.s6_addr[8], |
| 152 | addr.s6_addr[9], |
| 153 | addr.s6_addr[10], |
| 154 | addr.s6_addr[11], |
| 155 | addr.s6_addr[12], |
| 156 | addr.s6_addr[13], |
| 157 | addr.s6_addr[14], |
| 158 | addr.s6_addr[15]}); |
| 159 | |
| 160 | return std::nullopt; |
| 161 | } |
| 162 | |
| 163 | |
| 164 | //////////////////////////////////////////////////////////// |