1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program 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
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #ifndef ZABBIX_ZBXEVAL_H
21 #define ZABBIX_ZBXEVAL_H
22 
23 #include "common.h"
24 #include "zbxalgo.h"
25 #include "zbxvariant.h"
26 
27 /*
28  * Token type flags (32 bits):
29  * | 6 bits       | 4 bits              | 22 bits    |
30  * | token class  | operator precedence | token type |
31  */
32 #define ZBX_EVAL_CLASS_OPERAND		(__UINT64_C(0x01) << 26)
33 #define ZBX_EVAL_CLASS_OPERATOR1	(__UINT64_C(0x02) << 26)
34 #define ZBX_EVAL_CLASS_OPERATOR2	(__UINT64_C(0x04) << 26)
35 #define ZBX_EVAL_CLASS_FUNCTION		(__UINT64_C(0x08) << 26)
36 #define ZBX_EVAL_CLASS_SEPARATOR	(__UINT64_C(0x10) << 26)
37 #define ZBX_EVAL_CLASS_PROPERTY		(__UINT64_C(0x20) << 26)
38 #define ZBX_EVAL_CLASS_OPERATOR		(ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_CLASS_OPERATOR2)
39 
40 #define ZBX_EVAL_BEFORE_OPERAND		(ZBX_EVAL_CLASS_OPERATOR | ZBX_EVAL_CLASS_SEPARATOR)
41 #define ZBX_EVAL_BEFORE_OPERATOR	(ZBX_EVAL_CLASS_OPERAND | ZBX_EVAL_CLASS_PROPERTY)
42 
43 #define ZBX_EVAL_OP_SET_PRECEDENCE(x)	((x) << 22)
44 #define ZBX_EVAL_OP_PRIORITY		ZBX_EVAL_OP_SET_PRECEDENCE(0xf)
45 
46 #define ZBX_EVAL_TOKEN_NOP		(0)
47 #define ZBX_EVAL_TOKEN_OP_ADD		(1 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(4))
48 #define ZBX_EVAL_TOKEN_OP_SUB		(2 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(4))
49 #define ZBX_EVAL_TOKEN_OP_MUL		(3 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(3))
50 #define ZBX_EVAL_TOKEN_OP_DIV		(4 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(3))
51 #define ZBX_EVAL_TOKEN_OP_MINUS		(5 | ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_OP_SET_PRECEDENCE(2))
52 #define ZBX_EVAL_TOKEN_OP_EQ		(6 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(7))
53 #define ZBX_EVAL_TOKEN_OP_LT		(7 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
54 #define ZBX_EVAL_TOKEN_OP_GT		(8 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
55 #define ZBX_EVAL_TOKEN_OP_LE		(9 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
56 #define ZBX_EVAL_TOKEN_OP_GE		(10 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
57 #define ZBX_EVAL_TOKEN_OP_NE		(11 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(7))
58 #define ZBX_EVAL_TOKEN_OP_AND		(12 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(11))
59 #define ZBX_EVAL_TOKEN_OP_OR		(13 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(12))
60 #define ZBX_EVAL_TOKEN_OP_NOT		(14 | ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_OP_SET_PRECEDENCE(2))
61 #define ZBX_EVAL_TOKEN_VAR_NUM		(15 | ZBX_EVAL_CLASS_OPERAND)
62 #define ZBX_EVAL_TOKEN_VAR_STR		(16 | ZBX_EVAL_CLASS_OPERAND)
63 #define ZBX_EVAL_TOKEN_VAR_MACRO	(17 | ZBX_EVAL_CLASS_OPERAND)
64 #define ZBX_EVAL_TOKEN_VAR_USERMACRO	(18 | ZBX_EVAL_CLASS_OPERAND)
65 #define ZBX_EVAL_TOKEN_VAR_LLDMACRO	(19 | ZBX_EVAL_CLASS_OPERAND)
66 #define ZBX_EVAL_TOKEN_FUNCTIONID	(20 | ZBX_EVAL_CLASS_OPERAND)
67 #define ZBX_EVAL_TOKEN_FUNCTION		(21 | ZBX_EVAL_CLASS_FUNCTION)
68 #define ZBX_EVAL_TOKEN_HIST_FUNCTION	(22 | ZBX_EVAL_CLASS_FUNCTION)
69 #define ZBX_EVAL_TOKEN_GROUP_OPEN	(23 | ZBX_EVAL_CLASS_SEPARATOR)
70 #define ZBX_EVAL_TOKEN_GROUP_CLOSE	(24 | ZBX_EVAL_CLASS_OPERAND)
71 #define ZBX_EVAL_TOKEN_COMMA		(25 | ZBX_EVAL_CLASS_SEPARATOR)
72 #define ZBX_EVAL_TOKEN_ARG_QUERY	(26 | ZBX_EVAL_CLASS_OPERAND)
73 #define ZBX_EVAL_TOKEN_ARG_PERIOD	(27 | ZBX_EVAL_CLASS_OPERAND)
74 #define ZBX_EVAL_TOKEN_ARG_NULL		(28 | ZBX_EVAL_CLASS_OPERAND)
75 #define ZBX_EVAL_TOKEN_PROP_TAG		(29 | ZBX_EVAL_CLASS_PROPERTY)
76 #define ZBX_EVAL_TOKEN_PROP_GROUP	(30 | ZBX_EVAL_CLASS_PROPERTY)
77 #define ZBX_EVAL_TOKEN_EXCEPTION	(31 | ZBX_EVAL_CLASS_FUNCTION)
78 
79 /* token parsing rules */
80 
81 #define ZBX_EVAL_PARSE_MACRO		__UINT64_C(0x00000001)
82 #define ZBX_EVAL_PARSE_USERMACRO	__UINT64_C(0x00000002)
83 #define ZBX_EVAL_PARSE_LLDMACRO		__UINT64_C(0x00000004)
84 #define ZBX_EVAL_PARSE_FUNCTIONID	__UINT64_C(0x00000008)
85 #define ZBX_EVAL_PARSE_ITEM_QUERY	__UINT64_C(0x00000010)
86 #define ZBX_EVAL_PARSE_CONST_INDEX	__UINT64_C(0x00000020)
87 #define ZBX_EVAL_PARSE_COMPOUND_CONST	__UINT64_C(0x00000040)
88 #define ZBX_EVAL_PARSE_MATH		__UINT64_C(0x00000080)	/* +, -, *, / */
89 #define ZBX_EVAL_PARSE_COMPARE_EQ	__UINT64_C(0x00000100)	/* =, <> */
90 #define ZBX_EVAL_PARSE_COMPARE_SORT	__UINT64_C(0x00000200)	/* <, <=, >, >= */
91 #define ZBX_EVAL_PARSE_LOGIC		__UINT64_C(0x00000400)	/* or, and, not */
92 #define ZBX_EVAL_PARSE_VAR_NUM		__UINT64_C(0x00000800)	/* number */
93 #define ZBX_EVAL_PARSE_VAR_STR		__UINT64_C(0x00001000)	/* string */
94 #define ZBX_EVAL_PARSE_GROUP		__UINT64_C(0x00002000)	/* (, ) */
95 #define ZBX_EVAL_PARSE_FUNCTION_ARGS	__UINT64_C(0x00004000)
96 #define ZBX_EVAL_PARSE_FUNCTION_NAME	__UINT64_C(0x00008000)
97 #define ZBX_EVAL_PARSE_PROP_TAG		__UINT64_C(0x00010000)	/* 'tag' keyword in item query filter */
98 #define ZBX_EVAL_PARSE_PROP_GROUP	__UINT64_C(0x00020000)	/* 'group' keyword in item query filter */
99 
100 #define ZBX_EVAL_PARSE_FUNCTION		(ZBX_EVAL_PARSE_FUNCTION_NAME | ZBX_EVAL_PARSE_FUNCTION_ARGS	|\
101 					ZBX_EVAL_PARSE_GROUP)
102 #define ZBX_EVAL_PARSE_COMPARE		(ZBX_EVAL_PARSE_COMPARE_EQ | ZBX_EVAL_PARSE_COMPARE_SORT)
103 #define ZBX_EVAL_PARSE_VAR		(ZBX_EVAL_PARSE_VAR_NUM | ZBX_EVAL_PARSE_VAR_STR)
104 #define ZBX_EVAL_PARSE_PROPERTY		(ZBX_EVAL_PARSE_PROP_TAG | ZBX_EVAL_PARSE_PROP_GROUP)
105 
106 /* expression parsing rules */
107 
108 #define	ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION	(ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO 	|\
109 						ZBX_EVAL_PARSE_FUNCTIONID | ZBX_EVAL_PARSE_FUNCTION 	|\
110 						ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE 		|\
111 						ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR)
112 
113 #define	ZBX_EVAL_PARSE_CALC_EXPRESSSION		(ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO 	|\
114 						ZBX_EVAL_PARSE_ITEM_QUERY | ZBX_EVAL_PARSE_FUNCTION	|\
115 						ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE 		|\
116 						ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR 		|\
117 						ZBX_EVAL_PARSE_COMPOUND_CONST)
118 
119 #define ZBX_EVAL_PARSE_QUERY_EXPRESSION		(ZBX_EVAL_PARSE_USERMACRO | ZBX_EVAL_PARSE_COMPARE_EQ		|\
120 						ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_GROUP 			|\
121 						ZBX_EVAL_PARSE_VAR_STR | ZBX_EVAL_PARSE_PROPERTY)
122 
123 #define	ZBX_EVAL_PARSE_EXPRESSION_MACRO		(ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO 	|\
124 						ZBX_EVAL_PARSE_ITEM_QUERY | ZBX_EVAL_PARSE_FUNCTION	|\
125 						ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE 		|\
126 						ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR 		|\
127 						ZBX_EVAL_PARSE_COMPOUND_CONST)
128 /* expression composition rules */
129 
130 #define ZBX_EVAL_COMPOSE_LLD			__UINT64_C(0x01000000)
131 #define ZBX_EVAL_COMPOSE_FUNCTIONID		__UINT64_C(0x02000000)
132 #define ZBX_EVAL_COMPOSE_QUOTE			__UINT64_C(0x04000000)
133 #define ZBX_EVAL_COMPOSE_MASK_ERROR		__UINT64_C(0x08000000)
134 
135 /* expression evaluation rules */
136 
137 #define ZBX_EVAL_PROCESS_ERROR		__UINT64_C(0x000100000000)
138 
139 /* composite rules */
140 
141 #define ZBX_EVAL_TRIGGER_EXPRESSION	(ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION | \
142 					ZBX_EVAL_PARSE_CONST_INDEX | \
143 					ZBX_EVAL_PROCESS_ERROR)
144 
145 #define ZBX_EVAL_TRIGGER_EXPRESSION_LLD	(ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION | \
146 					ZBX_EVAL_PARSE_LLDMACRO | \
147 					ZBX_EVAL_COMPOSE_LLD | \
148 					ZBX_EVAL_COMPOSE_FUNCTIONID)
149 
150 #define ZBX_EVAL_CALC_EXPRESSION_LLD	(ZBX_EVAL_PARSE_CALC_EXPRESSSION | \
151 					ZBX_EVAL_PARSE_LLDMACRO | \
152 					ZBX_EVAL_COMPOSE_LLD)
153 
154 #define ZBX_EVAL_EXPRESSION_MACRO_LLD	(ZBX_EVAL_PARSE_EXPRESSION_MACRO | \
155 					ZBX_EVAL_PARSE_LLDMACRO | \
156 					ZBX_EVAL_COMPOSE_LLD)
157 
158 #define ZBX_EVAL_QUERY_EXPRESSION_LLD	(ZBX_EVAL_PARSE_QUERY_EXPRESSION | \
159 					ZBX_EVAL_PARSE_LLDMACRO | \
160 					ZBX_EVAL_COMPOSE_LLD)
161 
162 typedef zbx_uint32_t zbx_token_type_t;
163 
164 /******************************************************************************
165  *                                                                            *
166  * Typedef: zbx_eval_function_cb_t                                            *
167  *                                                                            *
168  * Purpose: define callback function to calculate custom functions            *
169  *                                                                            *
170  * Parameters: name     - [IN] the function name (not zero terminated)        *
171  *             len      - [IN] the function name length                       *
172  *             args_num - [IN] the number of function arguments               *
173  *             args     - [IN] an array of the function arguments.            *
174  *             data     - [IN] the caller data used for function evaluation   *
175  *             ts       - [IN] the function execution time                    *
176  *             value    - [OUT] the function return value                     *
177  *             error    - [OUT] the error message if function failed          *
178  *                                                                            *
179  * Return value: SUCCEED - the function was executed successfully             *
180  *               FAIL    - otherwise                                          *
181  *                                                                            *
182  ******************************************************************************/
183 typedef	int (*zbx_eval_function_cb_t)(const char *name, size_t len, int args_num, const zbx_variant_t *args,
184 		void *data, const zbx_timespec_t *ts, zbx_variant_t *value, char **error);
185 
186 typedef struct
187 {
188 	zbx_token_type_t	type;
189 	zbx_uint32_t		opt;
190 	zbx_strloc_t		loc;
191 	zbx_variant_t		value;
192 }
193 zbx_eval_token_t;
194 
195 ZBX_VECTOR_DECL(eval_token, zbx_eval_token_t)
196 
197 typedef struct
198 {
199 	const char		*expression;
200 	zbx_token_type_t	last_token_type;
201 	zbx_uint32_t		const_index;
202 	zbx_uint32_t		functionid_index;
203 	zbx_uint64_t		rules;
204 	zbx_timespec_t		ts;
205 	zbx_vector_eval_token_t	stack;
206 	zbx_vector_eval_token_t	ops;
207 	zbx_eval_function_cb_t	common_func_cb;
208 	zbx_eval_function_cb_t	history_func_cb;
209 	void			*data_cb;
210 }
211 zbx_eval_context_t;
212 
213 typedef int (*zbx_macro_resolve_func_t)(const char *str, size_t length, zbx_uint64_t *hostids,
214 		int hostids_num, char **value, char **error);
215 
216 int	zbx_eval_parse_expression(zbx_eval_context_t *ctx, const char *expression, zbx_uint64_t rules, char **error);
217 void	zbx_eval_init(zbx_eval_context_t *ctx);
218 void	zbx_eval_clear(zbx_eval_context_t *ctx);
219 int	zbx_eval_status(const zbx_eval_context_t *ctx);
220 size_t	zbx_eval_serialize(const zbx_eval_context_t *ctx, zbx_mem_malloc_func_t malloc_func, unsigned char **data);
221 void	zbx_eval_deserialize(zbx_eval_context_t *ctx, const char *expression, zbx_uint64_t rules,
222 		const unsigned char *data);
223 void	zbx_eval_compose_expression(const zbx_eval_context_t *ctx, char **expression);
224 int	zbx_eval_execute(zbx_eval_context_t *ctx, const zbx_timespec_t *ts, zbx_variant_t *value, char **error);
225 int	zbx_eval_execute_ext(zbx_eval_context_t *ctx, const zbx_timespec_t *ts, zbx_eval_function_cb_t common_func_cb,
226 		zbx_eval_function_cb_t history_func_cb, void *data, zbx_variant_t *value, char **error);
227 void	zbx_eval_get_functionids(zbx_eval_context_t *ctx, zbx_vector_uint64_t *functionids);
228 void	zbx_eval_get_functionids_ordered(zbx_eval_context_t *ctx, zbx_vector_uint64_t *functionids);
229 int	zbx_eval_expand_user_macros(const zbx_eval_context_t *ctx, zbx_uint64_t *hostids, int hostids_num,
230 		zbx_macro_resolve_func_t resolver_cb, char **error);
231 void	zbx_eval_set_exception(zbx_eval_context_t *ctx, char *message);
232 
233 #define ZBX_EVAL_EXTRACT_FUNCTIONID	0x0001
234 #define ZBX_EVAL_EXTRACT_VAR_STR	0x0002
235 #define ZBX_EVAL_EXTRACT_VAR_MACRO	0x0004
236 
237 #define ZBX_EVAL_EXCTRACT_ALL	(ZBX_EVAL_EXTRACT_FUNCTIONID | ZBX_EVAL_EXTRACT_VAR_STR | ZBX_EVAL_EXTRACT_VAR_MACRO)
238 
239 zbx_eval_context_t *zbx_eval_deserialize_dyn(const unsigned char *data, const char *expression,
240 		zbx_uint64_t mask);
241 int	zbx_eval_check_timer_functions(const zbx_eval_context_t *ctx);
242 void	zbx_get_serialized_expression_functionids(const char *expression, const unsigned char *data,
243 		zbx_vector_uint64_t *functionids);
244 void	zbx_eval_get_constant(const zbx_eval_context_t *ctx, int index, char **value);
245 void	zbx_eval_replace_functionid(zbx_eval_context_t *ctx, zbx_uint64_t old_functionid, zbx_uint64_t new_functionid);
246 int	zbx_eval_validate_replaced_functionids(zbx_eval_context_t *ctx, char **error);
247 void	zbx_eval_copy(zbx_eval_context_t *dst, const zbx_eval_context_t *src, const char *expression);
248 
249 char	*zbx_eval_format_function_error(const char *function, const char *host, const char *key,
250 		const char *parameter, const char *error);
251 
252 void	zbx_eval_extract_item_refs(zbx_eval_context_t *ctx, zbx_vector_str_t *refs);
253 
254 
255 typedef struct
256 {
257 	char	*host;
258 	char	*key;
259 	char	*filter;
260 }
261 zbx_item_query_t;
262 
263 size_t	zbx_eval_parse_query(const char *str, size_t len, zbx_item_query_t *query);
264 void	zbx_eval_clear_query(zbx_item_query_t *query);
265 
266 void	zbx_eval_prepare_filter(zbx_eval_context_t *ctx);
267 int	zbx_eval_get_group_filter(zbx_eval_context_t *ctx, zbx_vector_str_t *groups, char **filter, char **error);
268 
269 typedef int	(*zbx_statistical_func_t)(zbx_vector_dbl_t *values, double *result, char **error);
270 
271 int	zbx_eval_calc_kurtosis(zbx_vector_dbl_t *values, double *result, char **error);
272 int	zbx_eval_calc_mad(zbx_vector_dbl_t *values, double *result, char **error);
273 int	zbx_eval_calc_skewness(zbx_vector_dbl_t *values, double *result, char **error);
274 int	zbx_eval_calc_stddevpop(zbx_vector_dbl_t *values, double *result, char **error);
275 int	zbx_eval_calc_stddevsamp(zbx_vector_dbl_t *values, double *result, char **error);
276 int	zbx_eval_calc_sumofsquares(zbx_vector_dbl_t *values, double *result, char **error);
277 int	zbx_eval_calc_varpop(zbx_vector_dbl_t *values, double *result, char **error);
278 int	zbx_eval_calc_varsamp(zbx_vector_dbl_t *values, double *result, char **error);
279 
280 #endif
281