mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 23:58:20 +00:00
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:
commit
2eeac54857
10 changed files with 72 additions and 57 deletions
|
@ -62,7 +62,7 @@ HashKey* BuildExpectedConnHashKey(const ExpectedConn& c)
|
||||||
|
|
||||||
void IPAddr::Mask(int top_bits_to_keep)
|
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);
|
reporter->Error("Bad IPAddr::Mask value %d", top_bits_to_keep);
|
||||||
return;
|
return;
|
||||||
|
@ -91,7 +91,7 @@ void IPAddr::Mask(int top_bits_to_keep)
|
||||||
|
|
||||||
void IPAddr::ReverseMask(int top_bits_to_chop)
|
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);
|
reporter->Error("Bad IPAddr::ReverseMask value %d", top_bits_to_chop);
|
||||||
return;
|
return;
|
||||||
|
@ -118,52 +118,29 @@ 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, 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());
|
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));
|
||||||
|
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
|
else
|
||||||
|
|
|
@ -325,14 +325,6 @@ 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.
|
||||||
|
|
16
src/Val.cc
16
src/Val.cc
|
@ -911,11 +911,19 @@ bool AddrVal::DoUnserialize(UnserialInfo* info)
|
||||||
|
|
||||||
SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET)
|
SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET)
|
||||||
{
|
{
|
||||||
const char* sep = strchr(text, '/');
|
string s(text);
|
||||||
if ( ! sep )
|
size_t slash_loc = s.find('/');
|
||||||
Internal("separator missing in SubNetVal::SubNetVal");
|
|
||||||
|
|
||||||
val.subnet_val = new IPPrefix(text, atoi(sep+1));
|
if ( slash_loc == string::npos )
|
||||||
|
{
|
||||||
|
reporter->Error("Bad string in SubNetVal ctor: %s", text);
|
||||||
|
val.subnet_val = new IPPrefix();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val.subnet_val = new IPPrefix(s.substr(0, slash_loc),
|
||||||
|
atoi(s.substr(slash_loc + 1).c_str()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET)
|
SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET)
|
||||||
|
|
31
src/bro.bif
31
src/bro.bif
|
@ -2105,7 +2105,7 @@ function counts_to_addr%(v: index_vec%): addr
|
||||||
##
|
##
|
||||||
## Returns: The :bro:type:`string` *str* as :bro:type:`int`.
|
## Returns: The :bro:type:`string` *str* as :bro:type:`int`.
|
||||||
##
|
##
|
||||||
## .. bro:see:: to_addr to_port
|
## .. bro:see:: to_addr to_port to_subnet
|
||||||
function to_int%(str: string%): int
|
function to_int%(str: string%): int
|
||||||
%{
|
%{
|
||||||
const char* s = str->CheckString();
|
const char* s = str->CheckString();
|
||||||
|
@ -2162,7 +2162,7 @@ function double_to_count%(d: double%): count
|
||||||
## Returns: The :bro:type:`string` *str* as unsigned integer or if in invalid
|
## Returns: The :bro:type:`string` *str* as unsigned integer or if in invalid
|
||||||
## format.
|
## format.
|
||||||
##
|
##
|
||||||
## .. bro:see:: to_addr to_int to_port
|
## .. bro:see:: to_addr to_int to_port to_subnet
|
||||||
function to_count%(str: string%): count
|
function to_count%(str: string%): count
|
||||||
%{
|
%{
|
||||||
const char* s = str->CheckString();
|
const char* s = str->CheckString();
|
||||||
|
@ -2257,9 +2257,11 @@ function count_to_port%(num: count, proto: transport_proto%): port
|
||||||
##
|
##
|
||||||
## ip: The :bro:type:`string` to convert.
|
## ip: The :bro:type:`string` to convert.
|
||||||
##
|
##
|
||||||
## Returns: The :bro:type:`string` *ip* as :bro:type:`addr`.
|
## Returns: The :bro:type:`string` *ip* as :bro:type:`addr` or the unspecified
|
||||||
|
## address ``::`` if the input string does not parse correctly.
|
||||||
##
|
##
|
||||||
## .. bro:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr
|
## .. bro:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr
|
||||||
|
## to_subnet
|
||||||
function to_addr%(ip: string%): addr
|
function to_addr%(ip: string%): addr
|
||||||
%{
|
%{
|
||||||
char* s = ip->AsString()->Render();
|
char* s = ip->AsString()->Render();
|
||||||
|
@ -2268,13 +2270,30 @@ function to_addr%(ip: string%): addr
|
||||||
return ret;
|
return ret;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
## Converts a :bro:type:`string` to a :bro:type:`subnet`.
|
||||||
|
##
|
||||||
|
## sn: The subnet to convert.
|
||||||
|
##
|
||||||
|
## Returns: The *sn* string as a :bro:type:`subnet` or the unspecified subnet
|
||||||
|
## ``::/0`` if the input string does not parse correctly.
|
||||||
|
##
|
||||||
|
## .. bro:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr
|
||||||
|
## to_addr
|
||||||
|
function to_subnet%(sn: string%): subnet
|
||||||
|
%{
|
||||||
|
char* s = sn->AsString()->Render();
|
||||||
|
Val* ret = new SubNetVal(s);
|
||||||
|
delete [] s;
|
||||||
|
return ret;
|
||||||
|
%}
|
||||||
|
|
||||||
## Converts a :bro:type:`count` to an :bro:type:`addr`.
|
## Converts a :bro:type:`count` to an :bro:type:`addr`.
|
||||||
##
|
##
|
||||||
## ip: The :bro:type:`count` to convert.
|
## ip: The :bro:type:`count` to convert.
|
||||||
##
|
##
|
||||||
## Returns: The :bro:type:`count` *ip* as :bro:type:`addr`.
|
## Returns: The :bro:type:`count` *ip* as :bro:type:`addr`.
|
||||||
##
|
##
|
||||||
## .. bro:see:: raw_bytes_to_v4_addr to_addr
|
## .. bro:see:: raw_bytes_to_v4_addr to_addr to_subnet
|
||||||
function count_to_v4_addr%(ip: count%): addr
|
function count_to_v4_addr%(ip: count%): addr
|
||||||
%{
|
%{
|
||||||
if ( ip > 4294967295LU )
|
if ( ip > 4294967295LU )
|
||||||
|
@ -2294,7 +2313,7 @@ function count_to_v4_addr%(ip: count%): addr
|
||||||
##
|
##
|
||||||
## Returns: The byte :bro:type:`string` *ip* as :bro:type:`addr`.
|
## Returns: The byte :bro:type:`string` *ip* as :bro:type:`addr`.
|
||||||
##
|
##
|
||||||
## .. bro:see:: raw_bytes_to_v4_addr to_addr
|
## .. bro:see:: raw_bytes_to_v4_addr to_addr to_subnet
|
||||||
function raw_bytes_to_v4_addr%(b: string%): addr
|
function raw_bytes_to_v4_addr%(b: string%): addr
|
||||||
%{
|
%{
|
||||||
uint32 a = 0;
|
uint32 a = 0;
|
||||||
|
@ -2317,7 +2336,7 @@ function raw_bytes_to_v4_addr%(b: string%): addr
|
||||||
##
|
##
|
||||||
## Returns: A :bro:type:`port` converted from *s*.
|
## Returns: A :bro:type:`port` converted from *s*.
|
||||||
##
|
##
|
||||||
## .. bro:see:: to_addr to_count to_int
|
## .. bro:see:: to_addr to_count to_int to_subnet
|
||||||
function to_port%(s: string%): port
|
function to_port%(s: string%): port
|
||||||
%{
|
%{
|
||||||
int port = 0;
|
int port = 0;
|
||||||
|
|
1
testing/btest/Baseline/bifs.to_addr/error
Normal file
1
testing/btest/Baseline/bifs.to_addr/error
Normal file
|
@ -0,0 +1 @@
|
||||||
|
error: Bad IP address: not an IP
|
|
@ -6,3 +6,4 @@ to_addr(10.20.30.40) = 10.20.30.40 (SUCCESS)
|
||||||
to_addr(100.200.30.40) = 100.200.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.0.0.0) = 10.0.0.0 (SUCCESS)
|
||||||
to_addr(10.00.00.000) = 10.0.0.0 (SUCCESS)
|
to_addr(10.00.00.000) = 10.0.0.0 (SUCCESS)
|
||||||
|
to_addr(not an IP) = :: (SUCCESS)
|
||||||
|
|
1
testing/btest/Baseline/bifs.to_subnet/error
Normal file
1
testing/btest/Baseline/bifs.to_subnet/error
Normal file
|
@ -0,0 +1 @@
|
||||||
|
error: Bad string in SubNetVal ctor: 10.0.0.0
|
3
testing/btest/Baseline/bifs.to_subnet/output
Normal file
3
testing/btest/Baseline/bifs.to_subnet/output
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
10.0.0.0/8, T
|
||||||
|
2607:f8b0::/32, T
|
||||||
|
::/0, T
|
|
@ -1,5 +1,6 @@
|
||||||
# @TEST-EXEC: bro %INPUT >output
|
# @TEST-EXEC: bro -b %INPUT >output 2>error
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
# @TEST-EXEC: btest-diff error
|
||||||
|
|
||||||
function test_to_addr(ip: string, expect: addr)
|
function test_to_addr(ip: string, expect: addr)
|
||||||
{
|
{
|
||||||
|
@ -16,3 +17,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("100.200.30.40", 100.200.30.40);
|
||||||
test_to_addr("10.0.0.0", 10.0.0.0);
|
test_to_addr("10.0.0.0", 10.0.0.0);
|
||||||
test_to_addr("10.00.00.000", 10.0.0.0);
|
test_to_addr("10.00.00.000", 10.0.0.0);
|
||||||
|
test_to_addr("not an IP", ::);
|
||||||
|
|
11
testing/btest/bifs/to_subnet.bro
Normal file
11
testing/btest/bifs/to_subnet.bro
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# @TEST-EXEC: bro -b %INPUT >output 2>error
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
# @TEST-EXEC: btest-diff error
|
||||||
|
|
||||||
|
global sn: subnet;
|
||||||
|
sn = to_subnet("10.0.0.0/8");
|
||||||
|
print sn, sn == 10.0.0.0/8;
|
||||||
|
sn = to_subnet("2607:f8b0::/32");
|
||||||
|
print sn, sn == 2607:f8b0::/32;
|
||||||
|
sn = to_subnet("10.0.0.0");
|
||||||
|
print sn, sn == ::/0;
|
Loading…
Add table
Add a link
Reference in a new issue