Merge remote-tracking branch 'origin/fastpath'

* origin/fastpath:
  Add to_subnet bif (fixes #782).
  Refactor IPAddr v4 initialization from string. (fixes #775)

Closes #782.
Closes #775.
Closes #784.
This commit is contained in:
Robin Sommer 2012-02-24 15:26:18 -08:00
commit 2eeac54857
10 changed files with 72 additions and 57 deletions

View file

@ -62,7 +62,7 @@ HashKey* BuildExpectedConnHashKey(const ExpectedConn& c)
void IPAddr::Mask(int top_bits_to_keep)
{
if ( top_bits_to_keep <= 0 || top_bits_to_keep > 128 )
if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 )
{
reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep);
return;
@ -91,7 +91,7 @@ void IPAddr::Mask(int top_bits_to_keep)
void IPAddr::ReverseMask(int top_bits_to_chop)
{
if ( top_bits_to_chop <= 0 || top_bits_to_chop > 128 )
if ( top_bits_to_chop < 0 || top_bits_to_chop > 128 )
{
reporter->Error("Bad IPAddr::ReverseMask value %d", top_bits_to_chop);
return;
@ -118,52 +118,29 @@ 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<string> 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