28 #include <netinet/in.h> 30 #include <boost/algorithm/string.hpp> 42 IPAddress unix_dnslookup(
const std::string &url,
unsigned int port);
55 void IPAddress::construct_(
unsigned long address,
unsigned int port)
61 << std::uppercase << std::hex <<
address << std::nouppercase
62 <<
") is outside of the allowed range (0x00000000 - 0xFFFFFFFF).";
63 throw std::out_of_range(ss.str());
68 throw std::out_of_range(
69 "port number (" + std::to_string(
port) +
70 ") is outside of the allowed range (0 - 65535).");
90 construct_(other.address_,
port);
130 unsigned int port = 0;
131 std::vector<std::string> parts;
132 boost::split(parts,
address, [](
char c)
138 if (parts.size() == 2)
140 std::istringstream(parts.back()) >>
port;
144 if (parts.size() != 1)
146 throw std::invalid_argument(
"Invalid IP address string.");
155 throw std::invalid_argument(
"Invalid IP address string.");
160 if (!(c ==
'.' || isdigit(c)))
162 throw std::invalid_argument(
"Invalid IP address string.");
168 std::vector<unsigned long> octets;
169 std::istringstream ss(
address);
174 octets.push_back(octet);
178 if (octets.size() != 4)
180 throw std::invalid_argument(
"Invalid IP address string.");
184 for (
auto i : octets)
187 throw std::out_of_range(
188 "Address octet (" + std::to_string(i) +
189 ") is outside of the allowed range (0 - 255).");
195 construct_((octets[0] << 8 * 3) | (octets[1] << 8 * 2) |
196 (octets[2] << 8) | octets[3],
port);
299 return (lhs < rhs) || (lhs == rhs);
315 return (lhs > rhs) || (lhs == rhs);
342 const auto bytes =
to_bytes(ipaddress.address_);
344 for (
size_t i = 3; i > 0; --i)
346 os << static_cast<int>(bytes[i]) <<
".";
349 os << static_cast<int>(bytes[0]);
351 if (ipaddress.port_ != 0)
353 os <<
":" << ipaddress.port_;
374 return unix_dnslookup(url, 0);
376 return win32_dnslookup(url, 0);
397 IPAddress unix_dnslookup(
const std::string &url,
unsigned int port)
399 std::set<IPAddress> addresses;
401 struct addrinfo hints;
402 std::memset(&hints, 0,
sizeof(hints));
403 hints.ai_family = AF_INET;
404 hints.ai_protocol =
static_cast<int>(port);
406 struct addrinfo *result_ptr =
nullptr;
408 if (getaddrinfo(url.c_str(),
nullptr, &hints, &result_ptr))
413 std::unique_ptr<struct addrinfo, void(*)(struct addrinfo *)>
414 result(result_ptr, freeaddrinfo);
415 result_ptr =
nullptr;
417 for (result_ptr = result.get(); result_ptr !=
nullptr;
418 result_ptr = result_ptr->ai_next)
420 struct sockaddr_in *address_ptr =
421 reinterpret_cast<struct sockaddr_in *
>(result_ptr->ai_addr);
422 unsigned long address = ntohl(address_ptr->sin_addr.s_addr);
423 addresses.insert(
IPAddress(address, port));
427 if (addresses.empty())
434 return *(addresses.begin());
unsigned int port() const
bool operator!=(const IPAddress &lhs, const IPAddress &rhs)
std::array< ByteType, sizeof(T)> to_bytes(T number)
IPAddress(const IPAddress &other)=default
std::ostream & operator<<(std::ostream &os, const Action &action)
unsigned long address() const
bool operator<=(const IPAddress &lhs, const IPAddress &rhs)
IPAddress dnslookup(const std::string &url)
bool operator==(const IPAddress &lhs, const IPAddress &rhs)
bool operator>=(const IPAddress &lhs, const IPAddress &rhs)
bool operator>(const IPAddress &lhs, const IPAddress &rhs)
bool operator<(const IPAddress &lhs, const IPAddress &rhs)