1/* 2 * Copyright (c) 2002-2013 Balabit 3 * Copyright (c) 1998-2011 Balázs Scheidler 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * As an additional exemption you are allowed to compile & link against the 20 * OpenSSL libraries as published by the OpenSSL project. See the file 21 * COPYING for details. 22 * 23 */ 24 25%code requires { 26 27#include "filter/filter-expr-parser.h" 28 29} 30 31%code { 32 33#include "filter/filter-netmask.h" 34#include "filter/filter-netmask6.h" 35#include "filter/filter-op.h" 36#include "filter/filter-cmp.h" 37#include "filter/filter-in-list.h" 38#include "filter/filter-tags.h" 39#include "filter/filter-call.h" 40#include "filter/filter-re.h" 41#include "filter/filter-pri.h" 42#include "filter/filter-throttle.h" 43#include "messages.h" 44#include "template/templates.h" 45#include "syslog-names.h" 46#include "plugin.h" 47#include "cfg-grammar-internal.h" 48 49FilterExprNode *last_filter_expr; 50 51} 52 53%define api.prefix {filter_expr_} 54%lex-param {CfgLexer *lexer} 55%parse-param {CfgLexer *lexer} 56%parse-param {FilterExprNode **result} 57%parse-param {gpointer arg} 58 59/* INCLUDE_DECLS */ 60 61%token KW_PROGRAM 62%token KW_IN_LIST 63%token KW_RATE 64 65%left ';' 66%left KW_OR 67%left KW_AND 68%left KW_NOT 69%left KW_LT KW_LE KW_EQ KW_NE KW_GE KW_GT 70%left KW_NUM_LT KW_NUM_LE KW_NUM_EQ KW_NUM_NE KW_NUM_GE KW_NUM_GT 71 72%type <node> filter_expr 73%type <node> filter_simple_expr 74%type <node> filter_plugin 75%type <node> filter_comparison 76%type <node> filter_throttle 77 78%type <num> filter_fac_list 79%type <num> filter_fac 80%type <num> filter_severity_list 81%type <num> filter_severity 82 83%type <token> operator 84 85%% 86 87start 88 : filter_expr { *result = $1; if (yychar != FILTER_EXPR_EMPTY) { cfg_lexer_unput_token(lexer, &yylval); } YYACCEPT; } 89 ; 90 91filter_expr 92 : filter_simple_expr { $$ = $1; if (!$1) YYERROR; } 93 | KW_NOT filter_expr { ((FilterExprNode *) $2)->comp = !(((FilterExprNode *) $2)->comp); $$ = $2; } 94 | filter_expr KW_OR filter_expr { $$ = fop_or_new($1, $3); } 95 | filter_expr KW_AND filter_expr { $$ = fop_and_new($1, $3); } 96 | filter_expr ';' filter_expr { $$ = fop_and_new($1, $3); } 97 | filter_expr ';' { $$ = $1; } 98 | '(' filter_expr ')' { $$ = $2; } 99 ; 100 101filter_simple_expr 102 : KW_FACILITY '(' filter_fac_list ')' { $$ = filter_facility_new($3); } 103 | KW_FACILITY '(' LL_NUMBER ')' { $$ = filter_facility_new(0x80000000 | $3); } 104 | KW_SEVERITY '(' filter_severity_list ')' { $$ = filter_severity_new($3); } 105 | KW_FILTER '(' string ')' { $$ = filter_call_new($3, configuration); free($3); } 106 | KW_NETMASK '(' string ')' { $$ = filter_netmask_new($3); free($3); } 107 | KW_NETMASK6 '(' string ')' { 108 #if SYSLOG_NG_ENABLE_IPV6 109 $$ = filter_netmask6_new($3); 110 #else 111 YYERROR; 112 #endif 113 free($3); 114 } 115 | KW_TAGS '(' string_list ')' { $$ = filter_tags_new($3); } 116 | KW_IN_LIST '(' string string ')' 117 { 118 const gchar *p = $4; 119 if (p[0] == '$') 120 { 121 msg_warning("Value references in filters should not use the '$' prefix, those are only needed in templates", 122 evt_tag_str("value", $4), 123 cfg_lexer_format_location_tag(lexer, &@4)); 124 p++; 125 } 126 $$ = filter_in_list_new($3, p); 127 free($3); 128 free($4); 129 } 130 | KW_IN_LIST '(' string KW_VALUE '(' string ')' ')' 131 { 132 const gchar *p = $6; 133 if (p[0] == '$') 134 { 135 msg_warning("Value references in filters should not use the '$' prefix, those are only needed in templates", 136 evt_tag_str("value", $6), 137 cfg_lexer_format_location_tag(lexer, &@6)); 138 p++; 139 } 140 $$ = filter_in_list_new($3, p); 141 free($3); 142 free($6); 143 } 144 | filter_re { $$ = last_filter_expr; } 145 | filter_plugin 146 | filter_comparison 147 | filter_throttle { $$ = last_filter_expr; } 148 ; 149 150 151filter_plugin 152 : LL_IDENTIFIER 153 { 154 Plugin *p; 155 gint context = LL_CONTEXT_FILTER; 156 FilterExprNode *node; 157 158 p = cfg_find_plugin(configuration, context, $1); 159 CHECK_ERROR(p, @1, "%s plugin %s not found OR you may not used double quotes in your filter expression", cfg_lexer_lookup_context_name_by_type(context), $1); 160 161 node = (FilterExprNode *) cfg_parse_plugin(configuration, p, &@1, NULL); 162 free($1); 163 if (!node) 164 { 165 YYERROR; 166 } 167 $$ = node; 168 } 169 ; 170 171filter_comparison 172 : LL_STRING operator LL_STRING 173 { 174 LogTemplate *left, *right; 175 GError *error = NULL; 176 177 left = log_template_new(configuration, NULL); 178 right = log_template_new(configuration, NULL); 179 CHECK_ERROR_GERROR(log_template_compile(left, $1, &error), @1, error, "compiling the left-hand-side template failed"); 180 CHECK_ERROR_GERROR(log_template_compile(right, $3, &error), @3, error, "compiling the right-hand-side template failed"); 181 182 free($1); 183 free($3); 184 $$ = fop_cmp_new(left, right, $2); 185 } 186 ; 187 188operator 189 : KW_NUM_LT { $$ = yylval.token; } 190 | KW_NUM_LE { $$ = yylval.token; } 191 | KW_NUM_EQ { $$ = yylval.token; } 192 | KW_NUM_NE { $$ = yylval.token; } 193 | KW_NUM_GE { $$ = yylval.token; } 194 | KW_NUM_GT { $$ = yylval.token; } 195 | KW_LT { $$ = yylval.token; } 196 | KW_LE { $$ = yylval.token; } 197 | KW_EQ { $$ = yylval.token; } 198 | KW_NE { $$ = yylval.token; } 199 | KW_GE { $$ = yylval.token; } 200 | KW_GT { $$ = yylval.token; } 201 ; 202 203filter_re 204 : KW_PROGRAM { last_filter_expr = filter_re_new(LM_V_PROGRAM); } filter_re_params 205 | KW_HOST { last_filter_expr = filter_re_new(LM_V_HOST); } filter_re_params 206 | KW_MESSAGE { last_filter_expr = filter_re_new(LM_V_MESSAGE); } filter_re_params 207 | KW_SOURCE { last_filter_expr = filter_source_new(); } filter_re_params 208 | KW_MATCH { last_filter_expr = filter_match_new(); } filter_match_params 209 ; 210 211filter_re_params 212 : '(' string filter_re_opts ')' 213 { 214 GError *error = NULL; 215 216 CHECK_ERROR_GERROR(filter_re_compile_pattern(last_filter_expr, $2, &error), @2, error, "compiling the regexp failed"); 217 free($2); 218 } 219 ; 220 221filter_re_opts 222 : filter_re_opt filter_re_opts 223 | 224 ; 225 226filter_re_opt 227 : { last_matcher_options = filter_re_get_matcher_options(last_filter_expr); } matcher_option 228 ; 229 230 231filter_match_params 232 : '(' string filter_match_opts ')' 233 { 234 GError *error = NULL; 235 236 CHECK_ERROR_GERROR(filter_re_compile_pattern(last_filter_expr, $2, &error), @2, error, "compiling the regexp failed"); 237 free($2); 238 239 if (filter_match_is_usage_obsolete(last_filter_expr)) 240 { 241 msg_warning_once("WARNING: the match() filter without the use of the value() " 242 "option is deprecated and hinders performance, please use a " 243 "more specific filter like message() and/or program() instead", 244 cfg_lexer_format_location_tag(lexer, &@0)); 245 } 246 247 } 248 249filter_match_opts 250 : filter_match_opt filter_match_opts 251 | 252 ; 253 254filter_match_opt 255 : filter_re_opt 256 | KW_VALUE '(' string ')' 257 { 258 const gchar *p = $3; 259 if (p[0] == '$') 260 { 261 msg_warning("WARNING: value references in filters should not use the '$' prefix, those are only needed in templates, removing automatically", 262 evt_tag_str("value", $3), 263 cfg_lexer_format_location_tag(lexer, &@3)); 264 p++; 265 } 266 if (p[0] == '(' || strchr(p, '$') != NULL) 267 { 268 msg_error("value() reference for the match() filter cannot contain a full template string, use the template() option or stick to a single value", 269 evt_tag_str("value", $3), 270 cfg_lexer_format_location_tag(lexer, &@3)); 271 free($3); 272 YYERROR; 273 } 274 filter_match_set_value_handle(last_filter_expr, log_msg_get_value_handle(p)); 275 free($3); 276 } 277 | KW_TEMPLATE '(' template_content ')' 278 { 279 filter_match_set_template_ref(last_filter_expr, $3); 280 } 281 ; 282 283filter_fac_list 284 : filter_fac filter_fac_list { $$ = $1 | $2; } 285 | filter_fac { $$ = $1; } 286 ; 287 288filter_fac 289 : facility_string LL_DOTDOT facility_string 290 { 291 $$ = syslog_make_range($1 >> 3, $3 >> 3); 292 } 293 | facility_string { $$ = 1 << ($1 >> 3); } 294 ; 295 296filter_severity_list 297 : filter_severity filter_severity_list { $$ = $1 | $2; } 298 | filter_severity { $$ = $1; } 299 ; 300 301filter_severity 302 : severity_string LL_DOTDOT severity_string 303 { 304 $$ = syslog_make_range($1, $3); 305 } 306 | severity_string 307 { 308 $$ = 1 << $1; 309 } 310 ; 311 312filter_throttle_arg 313 : KW_TEMPLATE '(' template_content ')' 314 { 315 filter_throttle_set_key_template(last_filter_expr, $3); 316 log_template_unref($3); 317 } 318 | KW_RATE '(' positive_integer ')' 319 { 320 filter_throttle_set_rate(last_filter_expr, $3); 321 } 322 ; 323 324filter_throttle_args 325 : filter_throttle_arg filter_throttle_args 326 | 327 ; 328 329filter_throttle 330 : KW_THROTTLE { last_filter_expr = filter_throttle_new(); } '(' filter_throttle_args ')' 331 ; 332 333/* INCLUDE_RULES */ 334 335%% 336