diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 3dc0025c2d..f0389a68a6 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -67,52 +67,27 @@ void IPAddr::ReverseMask(int top_bits_to_chop) memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); } -std::string IPAddr::CanonIPv4(const std::string& input) - { - vector parts; - string output; - size_t start = 0; - size_t end; - - do - { - end = input.find('.', start); - string p; - bool in_leading_zeroes = true; - for ( size_t i = start; i != end && i < input.size(); ++i ) - { - if ( in_leading_zeroes && input[i] == '0' ) continue; - in_leading_zeroes = false; - p.push_back(input[i]); - } - - if ( p.size() == 0 ) - p.push_back('0'); - parts.push_back(p); - start = end + 1; - } while ( end != string::npos ); - - for ( size_t i = 0; i < parts.size(); ++i ) - { - if ( i > 0 ) - output += '.'; - output += parts[i]; - } - - return output; - } - void IPAddr::Init(const std::string& s) { if ( s.find(':') == std::string::npos ) // IPv4. { memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); - if ( inet_pton(AF_INET, CanonIPv4(s).c_str(), &in6.s6_addr[12]) <=0 ) + // parse the address directly instead of using inet_pton since + // some platforms have more sensitive implementations than others + // that can't e.g. handle leading zeroes. + int a[4]; + int n = sscanf(s.c_str(), "%d.%d.%d.%d", a+0, a+1, a+2, a+3); + if ( n != 4 || a[0] < 0 || a[1] < 0 || a[2] < 0 || a[3] < 0 || + a[0] > 255 || a[1] > 255 || a[2] > 255 || a[3] > 255 ) { reporter->Error("Bad IP address: %s", s.c_str()); memset(in6.s6_addr, 0, sizeof(in6.s6_addr)); + return; } + uint32_t addr = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]; + addr = htonl(addr); + memcpy(&in6.s6_addr[12], &addr, sizeof(uint32_t)); } else diff --git a/src/IPAddr.h b/src/IPAddr.h index 96e70689b4..c2e57ea7d1 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -261,14 +261,6 @@ public: unsigned int MemoryAllocation() const { return padded_sizeof(*this); } - /** - * Returns a canonicalized IPv4 dotted-decimal string such that - * leading zeroes of each decimal part are removed. - * - * @param s String containing an IPv4 address in dotted-decimal notation. - */ - static std::string CanonIPv4(const std::string& s); - private: /** * Initializes an address instance from a string representation.