mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
Decrease strictness of parsing IPv4 strings into addrs. (fixes #775)
IPv4 strings in dotted-decimal format with decimal parts containing leading zeroes now parse better.
This commit is contained in:
parent
1f7bfbb83c
commit
b66b74e5dc
4 changed files with 72 additions and 1 deletions
|
@ -1,5 +1,7 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "IPAddr.h"
|
#include "IPAddr.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
|
|
||||||
|
@ -65,13 +67,48 @@ void IPAddr::ReverseMask(int top_bits_to_chop)
|
||||||
memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr));
|
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)
|
void IPAddr::Init(const std::string& s)
|
||||||
{
|
{
|
||||||
if ( s.find(':') == std::string::npos ) // IPv4.
|
if ( s.find(':') == std::string::npos ) // IPv4.
|
||||||
{
|
{
|
||||||
memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix));
|
memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix));
|
||||||
|
|
||||||
if ( inet_pton(AF_INET, s.c_str(), &in6.s6_addr[12]) <=0 )
|
if ( inet_pton(AF_INET, CanonIPv4(s).c_str(), &in6.s6_addr[12]) <=0 )
|
||||||
{
|
{
|
||||||
reporter->Error("Bad IP address: %s", s.c_str());
|
reporter->Error("Bad IP address: %s", s.c_str());
|
||||||
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
|
memset(in6.s6_addr, 0, sizeof(in6.s6_addr));
|
||||||
|
|
|
@ -261,6 +261,14 @@ public:
|
||||||
|
|
||||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
|
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:
|
private:
|
||||||
/**
|
/**
|
||||||
* Initializes an address instance from a string representation.
|
* Initializes an address instance from a string representation.
|
||||||
|
|
8
testing/btest/Baseline/bifs.to_addr/output
Normal file
8
testing/btest/Baseline/bifs.to_addr/output
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
to_addr(0.0.0.0) = 0.0.0.0 (SUCCESS)
|
||||||
|
to_addr(1.2.3.4) = 1.2.3.4 (SUCCESS)
|
||||||
|
to_addr(01.02.03.04) = 1.2.3.4 (SUCCESS)
|
||||||
|
to_addr(001.002.003.004) = 1.2.3.4 (SUCCESS)
|
||||||
|
to_addr(10.20.30.40) = 10.20.30.40 (SUCCESS)
|
||||||
|
to_addr(100.200.30.40) = 100.200.30.40 (SUCCESS)
|
||||||
|
to_addr(10.0.0.0) = 10.0.0.0 (SUCCESS)
|
||||||
|
to_addr(10.00.00.000) = 10.0.0.0 (SUCCESS)
|
18
testing/btest/bifs/to_addr.bro
Normal file
18
testing/btest/bifs/to_addr.bro
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# @TEST-EXEC: bro %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
function test_to_addr(ip: string, expect: addr)
|
||||||
|
{
|
||||||
|
local result = to_addr(ip);
|
||||||
|
print fmt("to_addr(%s) = %s (%s)", ip, result,
|
||||||
|
result == expect ? "SUCCESS" : "FAILURE");
|
||||||
|
}
|
||||||
|
|
||||||
|
test_to_addr("0.0.0.0", 0.0.0.0);
|
||||||
|
test_to_addr("1.2.3.4", 1.2.3.4);
|
||||||
|
test_to_addr("01.02.03.04", 1.2.3.4);
|
||||||
|
test_to_addr("001.002.003.004", 1.2.3.4);
|
||||||
|
test_to_addr("10.20.30.40", 10.20.30.40);
|
||||||
|
test_to_addr("100.200.30.40", 100.200.30.40);
|
||||||
|
test_to_addr("10.0.0.0", 10.0.0.0);
|
||||||
|
test_to_addr("10.00.00.000", 10.0.0.0);
|
Loading…
Add table
Add a link
Reference in a new issue