From a3e60492a684be09374d0649735da42bdadc6b48 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 27 Dec 2015 22:15:17 +0100 Subject: 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 --- src/parser_bison.y | 267 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 159 insertions(+), 108 deletions(-) (limited to 'src/parser_bison.y') 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 initializer_expr %destructor { expr_free($$); } expr initializer_expr +%type rhs_expr concat_rhs_expr basic_rhs_expr +%destructor { expr_free($$); } rhs_expr concat_rhs_expr basic_rhs_expr +%type primary_rhs_expr list_rhs_expr +%destructor { expr_free($$); } primary_rhs_expr list_rhs_expr + %type relational_expr %destructor { expr_free($$); } relational_expr %type 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; } -- cgit v1.2.3