/* lw-support/src/lib/Net/Address/IPv4.cpp * * (c)2005, Laurence Withers. Released under the GNU GPL. See file * COPYING for more information / terms of license. */ namespace lw { const NetAddressIPv4 NetAddressIPv4::any(0, 0, 0, 0); const NetAddressIPv4 NetAddressIPv4::loopback(127, 0, 0, 1); std::wstring NetAddressIPv4::toString() const { std::wostringstream o; o << (uint)(addr[0]) << L'.' << (uint)(addr[1]) << L'.' << (uint)(addr[2]) << L'.' << (uint)(addr[3]); return o.str(); } NetAddressIPv4 NetAddressIPv4::fromString(const std::wstring& strIn) { std::wstring str = stripWhitespace(strIn); uint8_t addr[4]; int addrPos = 0; uint p = 0; bool seen = false; wchar_t ch; std::wstring::size_type pos = 0, len = str.length(); for(pos = 0; pos < len; ++pos) { ch = str[pos]; switch(ch) { case '0' ... '9': seen = true; p *= 10; p += (ch - '0'); if(p > 255) { throw ParseError(L"Octet cannot be > 255.", str, pos) .chain(L"NetAddressIPv4::fromString()"); } break; case '.': if(!seen) { throw ParseError(L"Empty octet.", str, pos) .chain(L"NetAddressIPv4::fromString()"); } if(addrPos == 3) { throw ParseError(L"Too many octets.", str, pos) .chain(L"NetAddressIPv4::fromString()"); } addr[addrPos++] = p; p = 0; seen = false; break; default: throw ParseError(L"Unexpected symbol.", str, pos) .chain(L"NetAddressIPv4::fromString()"); } } if(addrPos != 3 || !seen) { throw ParseError(L"Not enough octets.", str, pos) .chain(L"NetAddressIPv4::fromString()"); } addr[3] = p; return NetAddressIPv4(addr); } NetAddressIPv4 NetAddressIPv4::fromDNS(const std::string& host) { // attempt to convert from numeric form first try { return fromString(lw::asciiToUcs4(host)); } catch(...) { } // now perform blocking DNS lookup struct hostent he, * hep = 0; int err = 0, result = 0; char buffer[4096]; result = gethostbyname2_r(host.c_str(), AF_INET, &he, buffer, sizeof(buffer), &hep, &err); switch(result) { case 0: // success! break; case HOST_NOT_FOUND: throw DnsError(L"Host not found.", host); case TRY_AGAIN: throw DnsError(L"Temporary failure in name resolution.", host); case NO_RECOVERY: throw DnsError(L"Unrecoverable failure in name resolution.", host); case NO_ADDRESS: throw DnsError(L"Host does not have an associated IPv4 address.", host); default: throw DnsError(L"Unknown DNS error.", host); } return NetAddressIPv4(he.h_addr); } }