summaryrefslogtreecommitdiffstats
path: root/src/parser_bison.y
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2015-12-27 22:15:17 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2016-01-03 20:53:37 +0100
commita3e60492a684be09374d0649735da42bdadc6b48 (patch)
treeb25f36eccccc7af644bc7111dba273fda4ad9764 /src/parser_bison.y
parent19fd6ae16cbc61a34f046accf3e6076d8b1128e6 (diff)
parser: restrict relational rhs expression recursion
The relational expression allows recursion from both sides, this doesn't allow us to know what hand side the input is coming from. This patch adds a new expr_rhs rule that specifies what can be found on the constant side of the relational. Besides making it easier to understand what is actually supported, this allows us to use reserve words both as constant and statements. This is used by the following patch to allow to use redirect as constant from the icmp payload match. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/parser_bison.y')
-rw-r--r--src/parser_bison.y267
1 files changed, 159 insertions, 108 deletions
diff --git a/src/parser_bison.y b/src/parser_bison.y
index fbfe7eaf..be1c7403 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -508,6 +508,11 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%type <expr> expr initializer_expr
%destructor { expr_free($$); } expr initializer_expr
+%type <expr> rhs_expr concat_rhs_expr basic_rhs_expr
+%destructor { expr_free($$); } rhs_expr concat_rhs_expr basic_rhs_expr
+%type <expr> primary_rhs_expr list_rhs_expr
+%destructor { expr_free($$); } primary_rhs_expr list_rhs_expr
+
%type <expr> relational_expr
%destructor { expr_free($$); } relational_expr
%type <val> relational_op
@@ -1825,13 +1830,13 @@ list_expr : basic_expr COMMA basic_expr
}
;
-prefix_expr : basic_expr SLASH NUM
+prefix_expr : basic_rhs_expr SLASH NUM
{
$$ = prefix_expr_alloc(&@$, $1, $3);
}
;
-range_expr : basic_expr DASH basic_expr
+range_expr : basic_rhs_expr DASH basic_rhs_expr
{
$$ = range_expr_alloc(&@$, $1, $3);
}
@@ -1853,7 +1858,7 @@ multiton_expr : prefix_expr
| wildcard_expr
;
-map_expr : concat_expr MAP expr
+map_expr : concat_expr MAP rhs_expr
{
$$ = map_expr_alloc(&@$, $1, $3);
}
@@ -1926,11 +1931,11 @@ set_elem_option : TIMEOUT time_spec
}
;
-set_lhs_expr : concat_expr
+set_lhs_expr : concat_rhs_expr
| multiton_expr
;
-set_rhs_expr : concat_expr
+set_rhs_expr : concat_rhs_expr
| verdict_expr
;
@@ -1938,20 +1943,166 @@ initializer_expr : expr
| list_expr
;
-relational_expr : expr /* implicit */ expr
+relational_expr : expr /* implicit */ rhs_expr
{
$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
}
- | expr /* implicit */ list_expr
+ | expr /* implicit */ list_rhs_expr
{
$$ = relational_expr_alloc(&@$, OP_FLAGCMP, $1, $2);
}
- | expr relational_op expr
+ | expr relational_op rhs_expr
{
$$ = relational_expr_alloc(&@2, $2, $1, $3);
}
;
+list_rhs_expr : basic_rhs_expr COMMA basic_rhs_expr
+ {
+ $$ = list_expr_alloc(&@$);
+ compound_expr_add($$, $1);
+ compound_expr_add($$, $3);
+ }
+ | list_rhs_expr COMMA basic_rhs_expr
+ {
+ $1->location = @$;
+ compound_expr_add($1, $3);
+ $$ = $1;
+ }
+ ;
+
+rhs_expr : concat_rhs_expr { $$ = $1; }
+ | multiton_expr { $$ = $1; }
+ | set_expr { $$ = $1; }
+ ;
+
+concat_rhs_expr : basic_rhs_expr { $$ = $1; }
+ | concat_rhs_expr DOT basic_rhs_expr
+ {
+ if ($$->ops->type != EXPR_CONCAT) {
+ $$ = concat_expr_alloc(&@$);
+ compound_expr_add($$, $1);
+ } else {
+ struct location rhs[] = {
+ [1] = @2,
+ [2] = @3,
+ };
+ location_update(&$3->location, rhs, 2);
+
+ $$ = $1;
+ $$->location = @$;
+ }
+ compound_expr_add($$, $3);
+ }
+ ;
+
+basic_rhs_expr : primary_rhs_expr { $$ = $1; }
+ ;
+
+primary_rhs_expr : symbol_expr { $$ = $1; }
+ | integer_expr { $$ = $1; }
+ | ETHER
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "ether");
+ }
+ | IP
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "ip");
+ }
+ | IP6
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "ip6");
+ }
+ | VLAN
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "vlan");
+ }
+ | ARP
+ {
+ $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+ current_scope(state),
+ "arp");
+ }
+ | TCP
+ {
+ uint8_t data = IPPROTO_TCP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | UDP
+ {
+ uint8_t data = IPPROTO_UDP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | UDPLITE
+ {
+ uint8_t data = IPPROTO_UDPLITE;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | ESP
+ {
+ uint8_t data = IPPROTO_ESP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | AH
+ {
+ uint8_t data = IPPROTO_AH;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | ICMP
+ {
+ uint8_t data = IPPROTO_ICMP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | ICMP6
+ {
+ uint8_t data = IPPROTO_ICMPV6;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | COMP
+ {
+ uint8_t data = IPPROTO_COMP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | DCCP
+ {
+ uint8_t data = IPPROTO_DCCP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ | SCTP
+ {
+ uint8_t data = IPPROTO_SCTP;
+ $$ = constant_expr_alloc(&@$, &inet_protocol_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(data) * BITS_PER_BYTE, &data);
+ }
+ ;
+
relational_op : EQ { $$ = OP_EQ; }
| NEQ { $$ = OP_NEQ; }
| LT { $$ = OP_LT; }
@@ -2107,12 +2258,6 @@ eth_hdr_expr : ETHER eth_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_eth, $2);
}
- | ETHER
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "ether");
- }
;
eth_hdr_field : SADDR { $$ = ETHHDR_SADDR; }
@@ -2124,12 +2269,6 @@ vlan_hdr_expr : VLAN vlan_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_vlan, $2);
}
- | VLAN
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "vlan");
- }
;
vlan_hdr_field : ID { $$ = VLANHDR_VID; }
@@ -2142,12 +2281,6 @@ arp_hdr_expr : ARP arp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_arp, $2);
}
- | ARP
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "arp");
- }
;
arp_hdr_field : HTYPE { $$ = ARPHDR_HRD; }
@@ -2161,12 +2294,6 @@ ip_hdr_expr : IP ip_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_ip, $2);
}
- | IP
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "ip");
- }
;
ip_hdr_field : HDRVERSION { $$ = IPHDR_VERSION; }
@@ -2186,13 +2313,6 @@ icmp_hdr_expr : ICMP icmp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_icmp, $2);
}
- | ICMP
- {
- uint8_t data = IPPROTO_ICMP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
icmp_hdr_field : TYPE { $$ = ICMPHDR_TYPE; }
@@ -2208,12 +2328,6 @@ ip6_hdr_expr : IP6 ip6_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_ip6, $2);
}
- | IP6
- {
- $$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
- current_scope(state),
- "ip6");
- }
;
ip6_hdr_field : HDRVERSION { $$ = IP6HDR_VERSION; }
@@ -2229,13 +2343,6 @@ icmp6_hdr_expr : ICMP6 icmp6_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_icmp6, $2);
}
- | ICMP6
- {
- uint8_t data = IPPROTO_ICMPV6;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
icmp6_hdr_field : TYPE { $$ = ICMP6HDR_TYPE; }
@@ -2252,13 +2359,6 @@ auth_hdr_expr : AH auth_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_ah, $2);
}
- | AH
- {
- uint8_t data = IPPROTO_AH;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
auth_hdr_field : NEXTHDR { $$ = AHHDR_NEXTHDR; }
@@ -2272,13 +2372,6 @@ esp_hdr_expr : ESP esp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_esp, $2);
}
- | ESP
- {
- uint8_t data = IPPROTO_ESP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
esp_hdr_field : SPI { $$ = ESPHDR_SPI; }
@@ -2289,13 +2382,6 @@ comp_hdr_expr : COMP comp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_comp, $2);
}
- | COMP
- {
- uint8_t data = IPPROTO_COMP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
comp_hdr_field : NEXTHDR { $$ = COMPHDR_NEXTHDR; }
@@ -2307,13 +2393,6 @@ udp_hdr_expr : UDP udp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_udp, $2);
}
- | UDP
- {
- uint8_t data = IPPROTO_UDP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
udp_hdr_field : SPORT { $$ = UDPHDR_SPORT; }
@@ -2326,13 +2405,6 @@ udplite_hdr_expr : UDPLITE udplite_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_udplite, $2);
}
- | UDPLITE
- {
- uint8_t data = IPPROTO_UDPLITE;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
udplite_hdr_field : SPORT { $$ = UDPHDR_SPORT; }
@@ -2345,13 +2417,6 @@ tcp_hdr_expr : TCP tcp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_tcp, $2);
}
- | TCP
- {
- uint8_t data = IPPROTO_TCP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
tcp_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
@@ -2370,13 +2435,6 @@ dccp_hdr_expr : DCCP dccp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
}
- | DCCP
- {
- uint8_t data = IPPROTO_DCCP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
dccp_hdr_field : SPORT { $$ = DCCPHDR_SPORT; }
@@ -2388,13 +2446,6 @@ sctp_hdr_expr : SCTP sctp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_sctp, $2);
}
- | SCTP
- {
- uint8_t data = IPPROTO_SCTP;
- $$ = constant_expr_alloc(&@$, &inet_protocol_type,
- BYTEORDER_HOST_ENDIAN,
- sizeof(data) * BITS_PER_BYTE, &data);
- }
;
sctp_hdr_field : SPORT { $$ = SCTPHDR_SPORT; }