Add to_subnet bif (fixes #782).

Also fix IPAddr::Mask/ReverseMask not allowing argument of 0.

And clarified return value of to_addr bif when the input string
does not parse into a valid IP address.
This commit is contained in:
Jon Siwek 2012-02-24 12:34:29 -06:00
parent c84394d07f
commit 32aabe8432
9 changed files with 59 additions and 14 deletions

View file

@ -11,7 +11,7 @@ const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0,
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;
@ -40,7 +40,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;

View file

@ -911,11 +911,18 @@ 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"); if ( slash_loc == string::npos )
{
val.subnet_val = new IPPrefix(text, atoi(sep+1)); 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)

View file

@ -2135,7 +2135,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();
@ -2192,7 +2192,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();
@ -2287,9 +2287,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();
@ -2298,13 +2300,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 )
@ -2324,7 +2343,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;
@ -2347,7 +2366,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;

View file

@ -0,0 +1 @@
error: Bad IP address: not an IP

View file

@ -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)

View file

@ -0,0 +1 @@
error: Bad string in SubNetVal ctor: 10.0.0.0

View file

@ -0,0 +1,3 @@
10.0.0.0/8, T
2607:f8b0::/32, T
::/0, T

View file

@ -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", ::);

View 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;