Filter: Check whether IP is 4 or 6

This commit is contained in:
Jan Moskyto Matejka 2017-03-22 14:53:37 +01:00
parent 3c74416465
commit 61e501da89
4 changed files with 15 additions and 2 deletions

View file

@ -1186,7 +1186,8 @@ foot).
<tag><label id="type-ip">ip</tag> <tag><label id="type-ip">ip</tag>
This type can hold a single IP address. Depending on the compile-time This type can hold a single IP address. Depending on the compile-time
configuration of BIRD you are using, it is either an IPv4 or IPv6 configuration of BIRD you are using, it is either an IPv4 or IPv6
address. IP addresses are written in the standard notation address; this may be checked by <cf>.is_ip4</cf> which returns <cf/bool/.
IP addresses are written in the standard notation
(<cf/10.20.30.40/ or <cf/fec0:3:4::1/). You can apply special operator (<cf/10.20.30.40/ or <cf/fec0:3:4::1/). You can apply special operator
<cf>.mask(<M>num</M>)</cf> on values of type ip. It masks out all but <cf>.mask(<M>num</M>)</cf> on values of type ip. It masks out all but
first <cf><M>num</M></cf> bits from the IP address. So first <cf><M>num</M></cf> bits from the IP address. So

View file

@ -400,6 +400,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX,
PREFERENCE, PREFERENCE,
ROA_CHECK, ASN, ROA_CHECK, ASN,
IS_V4, IS_V6,
LEN, MAXLEN, LEN, MAXLEN,
DEFINED, DEFINED,
ADD, DELETE, CONTAINS, RESET, ADD, DELETE, CONTAINS, RESET,
@ -890,6 +891,7 @@ term:
| rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); } | rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); }
| term '.' IS_V4 { $$ = f_new_inst(); $$->code = P('I','i'); $$->a1.p = $1; }
| term '.' TYPE { $$ = f_new_inst(); $$->code = 'T'; $$->a1.p = $1; } | term '.' TYPE { $$ = f_new_inst(); $$->code = 'T'; $$->a1.p = $1; }
| term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; } | term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; }
| term '.' RD { $$ = f_new_inst(); $$->code = P('R','D'); $$->a1.p = $1; $$->aux = T_RD; } | term '.' RD { $$ = f_new_inst(); $$->code = P('R','D'); $$->a1.p = $1; $$->aux = T_RD; }

View file

@ -829,6 +829,13 @@ interpret(struct f_inst *what)
runtime( "Can't determine type of this item" ); runtime( "Can't determine type of this item" );
} }
break; break;
case P('I','i'):
ONEARG;
if (v1.type != T_IP)
runtime( "IP version check needs an IP address" );
res.type = T_BOOL;
res.val.i = ipa_is_ip4(v1.val.ip);
break;
/* Set to indirect value, a1 = variable, a2 = value */ /* Set to indirect value, a1 = variable, a2 = value */
case 's': case 's':

View file

@ -312,15 +312,18 @@ function t_ip()
ip p; ip p;
{ {
p = 127.1.2.3; p = 127.1.2.3;
bt_assert(p.is_v4);
bt_assert(p.mask(8) = 127.0.0.0); bt_assert(p.mask(8) = 127.0.0.0);
bt_assert(1.2.3.4 = 1.2.3.4); bt_assert(1.2.3.4 = 1.2.3.4);
bt_assert(1.2.3.4 = onetwo); bt_assert(1.2.3.4 = onetwo);
bt_assert(format(p) = "127.1.2.3"); bt_assert(format(p) = "127.1.2.3");
p = ::fffe:6:c0c:936d:88c7:35d3; p = ::fffe:6:c0c:936d:88c7:35d3;
bt_assert(!p.is_v4);
bt_assert(format(p) = "::fffe:6:c0c:936d:88c7:35d3"); bt_assert(format(p) = "::fffe:6:c0c:936d:88c7:35d3");
p = 1234:5678::; p = 1234:5678::;
bt_assert(!p.is_v4);
bt_assert(p.mask(24) = 1234:5600::); bt_assert(p.mask(24) = 1234:5600::);
} }