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 #include "common.h"
21 #include "checks_internal.h"
22 #include "checks_java.h"
23 #include "dbcache.h"
24 #include "zbxself.h"
25 #include "valuecache.h"
26 #include "proxy.h"
27 #include "preproc.h"
28
29 #include "../vmware/vmware.h"
30 #include "../../libs/zbxserver/zabbix_stats.h"
31 #include "../../libs/zbxsysinfo/common/zabbix_stats.h"
32
33 extern unsigned char program_type;
34
compare_interfaces(const void * p1,const void * p2)35 static int compare_interfaces(const void *p1, const void *p2)
36 {
37 const DC_INTERFACE2 *i1 = (DC_INTERFACE2 *)p1, *i2 = (DC_INTERFACE2 *)p2;
38
39 if (i1->type > i2->type) /* 1st criterion: 'type' in ascending order */
40 return 1;
41
42 if (i1->type < i2->type)
43 return -1;
44
45 if (i1->main > i2->main) /* 2nd criterion: 'main' in descending order */
46 return -1;
47
48 if (i1->main < i2->main)
49 return 1;
50
51 if (i1->interfaceid > i2->interfaceid) /* 3rd criterion: 'interfaceid' in ascending order */
52 return 1;
53
54 if (i1->interfaceid < i2->interfaceid)
55 return -1;
56
57 return 0;
58 }
59
60 /******************************************************************************
61 * *
62 * Function: zbx_host_interfaces_discovery *
63 * *
64 * Purpose: get data of all network interfaces for a host from configuration *
65 * cache and pack into JSON for LLD *
66 * *
67 * Parameter: hostid - [IN] the host identifier *
68 * j - [OUT] JSON with interface data *
69 * error - [OUT] error message *
70 * *
71 * Return value: SUCCEED - interface data in JSON *
72 * FAIL - host not found, 'error' message allocated *
73 * *
74 * Comments: if host is found but has no interfaces (should not happen) an *
75 * empty JSON {"data":[]} is returned *
76 * *
77 ******************************************************************************/
zbx_host_interfaces_discovery(zbx_uint64_t hostid,struct zbx_json * j,char ** error)78 static int zbx_host_interfaces_discovery(zbx_uint64_t hostid, struct zbx_json *j, char **error)
79 {
80 DC_INTERFACE2 *interfaces = NULL;
81 int n = 0; /* number of interfaces */
82 int i;
83
84 /* get interface data from configuration cache */
85
86 if (SUCCEED != zbx_dc_get_host_interfaces(hostid, &interfaces, &n))
87 {
88 *error = zbx_strdup(*error, "host not found in configuration cache");
89
90 return FAIL;
91 }
92
93 /* sort results in a predictable order */
94
95 if (1 < n)
96 qsort(interfaces, (size_t)n, sizeof(DC_INTERFACE2), compare_interfaces);
97
98 /* repair 'addr' pointers broken by sorting */
99
100 for (i = 0; i < n; i++)
101 interfaces[i].addr = (1 == interfaces[i].useip ? interfaces[i].ip_orig : interfaces[i].dns_orig);
102
103 /* pack results into JSON */
104
105 zbx_json_init(j, ZBX_JSON_STAT_BUF_LEN);
106 zbx_json_addarray(j, ZBX_PROTO_TAG_DATA);
107
108 for (i = 0; i < n; i++)
109 {
110 const char *p;
111 char buf[16];
112
113 zbx_json_addobject(j, NULL);
114 zbx_json_addstring(j, "{#IF.CONN}", interfaces[i].addr, ZBX_JSON_TYPE_STRING);
115 zbx_json_addstring(j, "{#IF.IP}", interfaces[i].ip_orig, ZBX_JSON_TYPE_STRING);
116 zbx_json_addstring(j, "{#IF.DNS}", interfaces[i].dns_orig, ZBX_JSON_TYPE_STRING);
117 zbx_json_addstring(j, "{#IF.PORT}", interfaces[i].port_orig, ZBX_JSON_TYPE_STRING);
118
119 switch (interfaces[i].type)
120 {
121 case INTERFACE_TYPE_AGENT:
122 p = "AGENT";
123 break;
124 case INTERFACE_TYPE_SNMP:
125 p = "SNMP";
126 break;
127 case INTERFACE_TYPE_IPMI:
128 p = "IPMI";
129 break;
130 case INTERFACE_TYPE_JMX:
131 p = "JMX";
132 break;
133 case INTERFACE_TYPE_UNKNOWN:
134 default:
135 p = "UNKNOWN";
136 }
137 zbx_json_addstring(j, "{#IF.TYPE}", p, ZBX_JSON_TYPE_STRING);
138
139 zbx_snprintf(buf, sizeof(buf), "%hhu", interfaces[i].main);
140 zbx_json_addstring(j, "{#IF.DEFAULT}", buf, ZBX_JSON_TYPE_INT);
141
142 if (INTERFACE_TYPE_SNMP == interfaces[i].type)
143 {
144 zbx_snprintf(buf, sizeof(buf), "%hhu", interfaces[i].bulk);
145 zbx_json_addstring(j, "{#IF.SNMP.BULK}", buf, ZBX_JSON_TYPE_INT);
146 }
147
148 zbx_json_close(j);
149 }
150
151 zbx_json_close(j);
152
153 zbx_free(interfaces);
154
155 return SUCCEED;
156 }
157
158 /******************************************************************************
159 * *
160 * Function: get_value_internal *
161 * *
162 * Purpose: retrieve data from Zabbix server (internally supported items) *
163 * *
164 * Parameters: item - item we are interested in *
165 * *
166 * Return value: SUCCEED - data successfully retrieved and stored in result *
167 * NOTSUPPORTED - requested item is not supported *
168 * *
169 * Author: Alexei Vladishev *
170 * *
171 ******************************************************************************/
get_value_internal(DC_ITEM * item,AGENT_RESULT * result)172 int get_value_internal(DC_ITEM *item, AGENT_RESULT *result)
173 {
174 AGENT_REQUEST request;
175 int ret = NOTSUPPORTED, nparams;
176 const char *tmp, *tmp1;
177
178 init_request(&request);
179
180 if (SUCCEED != parse_item_key(item->key, &request))
181 {
182 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
183 goto out;
184 }
185
186 if (0 != strcmp("zabbix", get_rkey(&request)))
187 {
188 SET_MSG_RESULT(result, zbx_strdup(NULL, "Unsupported item key for this item type."));
189 goto out;
190 }
191
192 /* NULL check to silence analyzer warning */
193 if (0 == (nparams = get_rparams_num(&request)) || NULL == (tmp = get_rparam(&request, 0)))
194 {
195 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
196 goto out;
197 }
198
199 if (0 == strcmp(tmp, "triggers")) /* zabbix["triggers"] */
200 {
201 if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
202 goto out;
203
204 if (1 != nparams)
205 {
206 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
207 goto out;
208 }
209
210 SET_UI64_RESULT(result, DCget_trigger_count());
211 }
212 else if (0 == strcmp(tmp, "items")) /* zabbix["items"] */
213 {
214 if (1 != nparams)
215 {
216 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
217 goto out;
218 }
219
220 SET_UI64_RESULT(result, DCget_item_count(0));
221 }
222 else if (0 == strcmp(tmp, "items_unsupported")) /* zabbix["items_unsupported"] */
223 {
224 if (1 != nparams)
225 {
226 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
227 goto out;
228 }
229
230 SET_UI64_RESULT(result, DCget_item_unsupported_count(0));
231 }
232 else if (0 == strcmp(tmp, "hosts")) /* zabbix["hosts"] */
233 {
234 if (1 != nparams)
235 {
236 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
237 goto out;
238 }
239
240 SET_UI64_RESULT(result, DCget_host_count());
241 }
242 else if (0 == strcmp(tmp, "history") || /* zabbix["history"] */
243 0 == strcmp(tmp, "history_log") || /* zabbix["history_log"] */
244 0 == strcmp(tmp, "history_str") || /* zabbix["history_str"] */
245 0 == strcmp(tmp, "history_text") || /* zabbix["history_text"] */
246 0 == strcmp(tmp, "history_uint")) /* zabbix["history_uint"] */
247 {
248 if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
249 goto out;
250
251 if (1 != nparams)
252 {
253 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
254 goto out;
255 }
256
257 SET_UI64_RESULT(result, DBget_row_count(tmp));
258 }
259 else if (0 == strcmp(tmp, "trends") || /* zabbix["trends"] */
260 0 == strcmp(tmp, "trends_uint")) /* zabbix["trends_uint"] */
261 {
262 if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
263 goto out;
264
265 if (1 != nparams)
266 {
267 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
268 goto out;
269 }
270
271 SET_UI64_RESULT(result, DBget_row_count(tmp));
272 }
273 else if (0 == strcmp(tmp, "queue")) /* zabbix["queue",<from>,<to>] */
274 {
275 int from = ZBX_QUEUE_FROM_DEFAULT, to = ZBX_QUEUE_TO_INFINITY;
276
277 if (3 < nparams)
278 {
279 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
280 goto out;
281 }
282
283 if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp &&
284 FAIL == is_time_suffix(tmp, &from, ZBX_LENGTH_UNLIMITED))
285 {
286 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
287 goto out;
288 }
289
290 if (NULL != (tmp = get_rparam(&request, 2)) && '\0' != *tmp &&
291 FAIL == is_time_suffix(tmp, &to, ZBX_LENGTH_UNLIMITED))
292 {
293 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
294 goto out;
295 }
296
297 if (ZBX_QUEUE_TO_INFINITY != to && from > to)
298 {
299 SET_MSG_RESULT(result, zbx_strdup(NULL, "Parameters represent an invalid interval."));
300 goto out;
301 }
302
303 SET_UI64_RESULT(result, DCget_item_queue(NULL, from, to));
304 }
305 else if (0 == strcmp(tmp, "requiredperformance")) /* zabbix["requiredperformance"] */
306 {
307 if (1 != nparams)
308 {
309 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
310 goto out;
311 }
312
313 SET_DBL_RESULT(result, DCget_required_performance());
314 }
315 else if (0 == strcmp(tmp, "uptime")) /* zabbix["uptime"] */
316 {
317 if (1 != nparams)
318 {
319 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
320 goto out;
321 }
322
323 SET_UI64_RESULT(result, time(NULL) - CONFIG_SERVER_STARTUP_TIME);
324 }
325 else if (0 == strcmp(tmp, "boottime")) /* zabbix["boottime"] */
326 {
327 if (1 != nparams)
328 {
329 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
330 goto out;
331 }
332
333 SET_UI64_RESULT(result, CONFIG_SERVER_STARTUP_TIME);
334 }
335 else if (0 == strcmp(tmp, "host")) /* zabbix["host",*] */
336 {
337 if (3 != nparams)
338 {
339 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
340 goto out;
341 }
342
343 tmp = get_rparam(&request, 2);
344
345 if (0 == strcmp(tmp, "available")) /* zabbix["host",<type>,"available"] */
346 {
347 tmp = get_rparam(&request, 1);
348
349 if (0 == strcmp(tmp, "agent"))
350 SET_UI64_RESULT(result, item->host.available);
351 else if (0 == strcmp(tmp, "snmp"))
352 SET_UI64_RESULT(result, item->host.snmp_available);
353 else if (0 == strcmp(tmp, "ipmi"))
354 SET_UI64_RESULT(result, item->host.ipmi_available);
355 else if (0 == strcmp(tmp, "jmx"))
356 SET_UI64_RESULT(result, item->host.jmx_available);
357 else
358 {
359 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
360 goto out;
361 }
362
363 result->ui64 = 2 - result->ui64;
364 }
365 else if (0 == strcmp(tmp, "maintenance")) /* zabbix["host",,"maintenance"] */
366 {
367 /* this item is always processed by server */
368 if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp)
369 {
370 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
371 goto out;
372 }
373
374 if (HOST_MAINTENANCE_STATUS_ON == item->host.maintenance_status)
375 SET_UI64_RESULT(result, item->host.maintenance_type + 1);
376 else
377 SET_UI64_RESULT(result, 0);
378 }
379 else if (0 == strcmp(tmp, "items")) /* zabbix["host",,"items"] */
380 {
381 /* this item is always processed by server */
382 if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp)
383 {
384 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
385 goto out;
386 }
387
388 SET_UI64_RESULT(result, DCget_item_count(item->host.hostid));
389 }
390 else if (0 == strcmp(tmp, "items_unsupported")) /* zabbix["host",,"items_unsupported"] */
391 {
392 /* this item is always processed by server */
393 if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp)
394 {
395 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
396 goto out;
397 }
398
399 SET_UI64_RESULT(result, DCget_item_unsupported_count(item->host.hostid));
400 }
401 else if (0 == strcmp(tmp, "interfaces")) /* zabbix["host","discovery","interfaces"] */
402 {
403 struct zbx_json j;
404 char *error = NULL;
405
406 /* this item is always processed by server */
407 if (NULL == (tmp = get_rparam(&request, 1)) || 0 != strcmp(tmp, "discovery"))
408 {
409 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
410 goto out;
411 }
412
413 if (SUCCEED != zbx_host_interfaces_discovery(item->host.hostid, &j, &error))
414 {
415 SET_MSG_RESULT(result, error);
416 goto out;
417 }
418
419 SET_STR_RESULT(result, zbx_strdup(NULL, j.buffer));
420
421 zbx_json_free(&j);
422 }
423 else
424 {
425 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
426 goto out;
427 }
428 }
429 else if (0 == strcmp(tmp, "proxy")) /* zabbix["proxy",<hostname>,"lastaccess"] */
430 {
431 int lastaccess;
432 char *error = NULL;
433
434 /* this item is always processed by server */
435
436 if (3 != nparams)
437 {
438 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
439 goto out;
440 }
441
442 tmp = get_rparam(&request, 2);
443 if ('\0' == *tmp || 0 != strcmp(tmp, "lastaccess"))
444 {
445 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
446 goto out;
447 }
448
449 if (FAIL == DBget_proxy_lastaccess(get_rparam(&request, 1), &lastaccess, &error))
450 {
451 SET_MSG_RESULT(result, error);
452 goto out;
453 }
454
455 SET_UI64_RESULT(result, lastaccess);
456 }
457 else if (0 == strcmp(tmp, "java")) /* zabbix["java",...] */
458 {
459 int res;
460
461 zbx_alarm_on(CONFIG_TIMEOUT);
462 res = get_value_java(ZBX_JAVA_GATEWAY_REQUEST_INTERNAL, item, result);
463 zbx_alarm_off();
464
465 if (SUCCEED != res)
466 {
467 tmp1 = get_rparam(&request, 2);
468 /* the default error code "NOTSUPPORTED" renders nodata() trigger function nonfunctional */
469 if (NULL != tmp1 && 0 == strcmp(tmp1, "ping"))
470 ret = GATEWAY_ERROR;
471 goto out;
472 }
473 }
474 else if (0 == strcmp(tmp, "process")) /* zabbix["process",<type>,<mode>,<state>] */
475 {
476 unsigned char process_type = ZBX_PROCESS_TYPE_UNKNOWN;
477 int process_forks;
478 double value;
479
480 if (2 > nparams || nparams > 4)
481 {
482 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
483 goto out;
484 }
485
486 process_type = get_process_type_by_name(get_rparam(&request, 1));
487
488 switch (process_type)
489 {
490 case ZBX_PROCESS_TYPE_ALERTMANAGER:
491 case ZBX_PROCESS_TYPE_ALERTER:
492 case ZBX_PROCESS_TYPE_ESCALATOR:
493 case ZBX_PROCESS_TYPE_PROXYPOLLER:
494 case ZBX_PROCESS_TYPE_TIMER:
495 if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
496 process_type = ZBX_PROCESS_TYPE_UNKNOWN;
497 break;
498 case ZBX_PROCESS_TYPE_DATASENDER:
499 case ZBX_PROCESS_TYPE_HEARTBEAT:
500 if (0 == (program_type & ZBX_PROGRAM_TYPE_PROXY))
501 process_type = ZBX_PROCESS_TYPE_UNKNOWN;
502 break;
503 }
504
505 if (ZBX_PROCESS_TYPE_UNKNOWN == process_type)
506 {
507 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
508 goto out;
509 }
510
511 process_forks = get_process_type_forks(process_type);
512
513 if (NULL == (tmp = get_rparam(&request, 2)))
514 tmp = "";
515
516 if (0 == strcmp(tmp, "count"))
517 {
518 if (4 == nparams)
519 {
520 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
521 goto out;
522 }
523
524 SET_UI64_RESULT(result, process_forks);
525 }
526 else
527 {
528 unsigned char aggr_func, state;
529 unsigned short process_num = 0;
530
531 if ('\0' == *tmp || 0 == strcmp(tmp, "avg"))
532 aggr_func = ZBX_AGGR_FUNC_AVG;
533 else if (0 == strcmp(tmp, "max"))
534 aggr_func = ZBX_AGGR_FUNC_MAX;
535 else if (0 == strcmp(tmp, "min"))
536 aggr_func = ZBX_AGGR_FUNC_MIN;
537 else if (SUCCEED == is_ushort(tmp, &process_num) && 0 < process_num)
538 aggr_func = ZBX_AGGR_FUNC_ONE;
539 else
540 {
541 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
542 goto out;
543 }
544
545 if (0 == process_forks)
546 {
547 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No \"%s\" processes started.",
548 get_process_type_string(process_type)));
549 goto out;
550 }
551 else if (process_num > process_forks)
552 {
553 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Process \"%s #%d\" is not started.",
554 get_process_type_string(process_type), process_num));
555 goto out;
556 }
557
558 if (NULL == (tmp = get_rparam(&request, 3)) || '\0' == *tmp || 0 == strcmp(tmp, "busy"))
559 state = ZBX_PROCESS_STATE_BUSY;
560 else if (0 == strcmp(tmp, "idle"))
561 state = ZBX_PROCESS_STATE_IDLE;
562 else
563 {
564 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter."));
565 goto out;
566 }
567
568 get_selfmon_stats(process_type, aggr_func, process_num, state, &value);
569
570 SET_DBL_RESULT(result, value);
571 }
572 }
573 else if (0 == strcmp(tmp, "wcache")) /* zabbix[wcache,<cache>,<mode>] */
574 {
575 if (2 > nparams || nparams > 3)
576 {
577 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
578 goto out;
579 }
580
581 tmp = get_rparam(&request, 1);
582 tmp1 = get_rparam(&request, 2);
583
584 if (0 == strcmp(tmp, "values"))
585 {
586 if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "all"))
587 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_COUNTER));
588 else if (0 == strcmp(tmp1, "float"))
589 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FLOAT_COUNTER));
590 else if (0 == strcmp(tmp1, "uint"))
591 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_UINT_COUNTER));
592 else if (0 == strcmp(tmp1, "str"))
593 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_STR_COUNTER));
594 else if (0 == strcmp(tmp1, "log"))
595 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_LOG_COUNTER));
596 else if (0 == strcmp(tmp1, "text"))
597 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TEXT_COUNTER));
598 else if (0 == strcmp(tmp1, "not supported"))
599 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_NOTSUPPORTED_COUNTER));
600 else
601 {
602 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
603 goto out;
604 }
605 }
606 else if (0 == strcmp(tmp, "history"))
607 {
608 if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
609 SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_PFREE));
610 else if (0 == strcmp(tmp1, "total"))
611 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TOTAL));
612 else if (0 == strcmp(tmp1, "used"))
613 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_USED));
614 else if (0 == strcmp(tmp1, "free"))
615 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FREE));
616 else if (0 == strcmp(tmp1, "pused"))
617 SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_PUSED));
618 else
619 {
620 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
621 goto out;
622 }
623 }
624 else if (0 == strcmp(tmp, "trend"))
625 {
626 if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
627 {
628 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
629 goto out;
630 }
631
632 if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
633 SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TREND_PFREE));
634 else if (0 == strcmp(tmp1, "total"))
635 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_TOTAL));
636 else if (0 == strcmp(tmp1, "used"))
637 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_USED));
638 else if (0 == strcmp(tmp1, "free"))
639 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_FREE));
640 else if (0 == strcmp(tmp1, "pused"))
641 SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TREND_PUSED));
642 else
643 {
644 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
645 goto out;
646 }
647 }
648 else if (0 == strcmp(tmp, "index"))
649 {
650 if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
651 SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_INDEX_PFREE));
652 else if (0 == strcmp(tmp1, "total"))
653 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_TOTAL));
654 else if (0 == strcmp(tmp1, "used"))
655 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_USED));
656 else if (0 == strcmp(tmp1, "free"))
657 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_FREE));
658 else if (0 == strcmp(tmp1, "pused"))
659 SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_INDEX_PUSED));
660 else
661 {
662 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
663 goto out;
664 }
665 }
666 else
667 {
668 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
669 goto out;
670 }
671 }
672 else if (0 == strcmp(tmp, "rcache")) /* zabbix[rcache,<cache>,<mode>] */
673 {
674 if (2 > nparams || nparams > 3)
675 {
676 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
677 goto out;
678 }
679
680 tmp = get_rparam(&request, 1);
681 tmp1 = get_rparam(&request, 2);
682
683 if (0 == strcmp(tmp, "buffer"))
684 {
685 if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
686 SET_DBL_RESULT(result, *(double *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_PFREE));
687 else if (0 == strcmp(tmp1, "total"))
688 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_TOTAL));
689 else if (0 == strcmp(tmp1, "used"))
690 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_USED));
691 else if (0 == strcmp(tmp1, "free"))
692 SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_FREE));
693 else if (0 == strcmp(tmp1, "pused"))
694 SET_DBL_RESULT(result, *(double *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_PUSED));
695 else
696 {
697 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
698 goto out;
699 }
700 }
701 else
702 {
703 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
704 goto out;
705 }
706 }
707 else if (0 == strcmp(tmp, "vcache"))
708 {
709 zbx_vc_stats_t stats;
710
711 if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
712 goto out;
713
714 if (FAIL == zbx_vc_get_statistics(&stats))
715 {
716 SET_MSG_RESULT(result, zbx_strdup(NULL, "Value cache is disabled."));
717 goto out;
718 }
719
720 if (2 > nparams || nparams > 3)
721 {
722 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
723 goto out;
724 }
725
726 tmp = get_rparam(&request, 1);
727 if (NULL == (tmp1 = get_rparam(&request, 2)))
728 tmp1 = "";
729
730 if (0 == strcmp(tmp, "buffer"))
731 {
732 if (0 == strcmp(tmp1, "free"))
733 SET_UI64_RESULT(result, stats.free_size);
734 else if (0 == strcmp(tmp1, "pfree"))
735 SET_DBL_RESULT(result, (double)stats.free_size / stats.total_size * 100);
736 else if (0 == strcmp(tmp1, "total"))
737 SET_UI64_RESULT(result, stats.total_size);
738 else if (0 == strcmp(tmp1, "used"))
739 SET_UI64_RESULT(result, stats.total_size - stats.free_size);
740 else if (0 == strcmp(tmp1, "pused"))
741 SET_DBL_RESULT(result, (double)(stats.total_size - stats.free_size) /
742 stats.total_size * 100);
743 else
744 {
745 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
746 goto out;
747 }
748 }
749 else if (0 == strcmp(tmp, "cache"))
750 {
751 if (0 == strcmp(tmp1, "hits"))
752 SET_UI64_RESULT(result, stats.hits);
753 else if (0 == strcmp(tmp1, "requests"))
754 SET_UI64_RESULT(result, stats.hits + stats.misses);
755 else if (0 == strcmp(tmp1, "misses"))
756 SET_UI64_RESULT(result, stats.misses);
757 else if (0 == strcmp(tmp1, "mode"))
758 SET_UI64_RESULT(result, stats.mode);
759 else
760 {
761 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
762 goto out;
763 }
764 }
765 else
766 {
767 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
768 goto out;
769 }
770 }
771 else if (0 == strcmp(tmp, "proxy_history"))
772 {
773 if (0 == (program_type & ZBX_PROGRAM_TYPE_PROXY))
774 goto out;
775
776 if (1 != nparams)
777 {
778 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
779 goto out;
780 }
781
782 SET_UI64_RESULT(result, proxy_get_history_count());
783 }
784 else if (0 == strcmp(tmp, "vmware"))
785 {
786 zbx_vmware_stats_t stats;
787
788 if (FAIL == zbx_vmware_get_statistics(&stats))
789 {
790 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No \"%s\" processes started.",
791 get_process_type_string(ZBX_PROCESS_TYPE_VMWARE)));
792 goto out;
793 }
794
795 if (2 > nparams || nparams > 3)
796 {
797 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
798 goto out;
799 }
800
801 tmp = get_rparam(&request, 1);
802 if (NULL == (tmp1 = get_rparam(&request, 2)))
803 tmp1 = "";
804
805 if (0 == strcmp(tmp, "buffer"))
806 {
807 if (0 == strcmp(tmp1, "free"))
808 {
809 SET_UI64_RESULT(result, stats.memory_total - stats.memory_used);
810 }
811 else if (0 == strcmp(tmp1, "pfree"))
812 {
813 SET_DBL_RESULT(result, (double)(stats.memory_total - stats.memory_used) /
814 stats.memory_total * 100);
815 }
816 else if (0 == strcmp(tmp1, "total"))
817 {
818 SET_UI64_RESULT(result, stats.memory_total);
819 }
820 else if (0 == strcmp(tmp1, "used"))
821 {
822 SET_UI64_RESULT(result, stats.memory_used);
823 }
824 else if (0 == strcmp(tmp1, "pused"))
825 {
826 SET_DBL_RESULT(result, (double)stats.memory_used / stats.memory_total * 100);
827 }
828 else
829 {
830 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
831 goto out;
832 }
833 }
834 else
835 {
836 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
837 goto out;
838 }
839 }
840 else if (0 == strcmp(tmp, "preprocessing_queue"))
841 {
842 if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
843 goto out;
844
845 if (1 != nparams)
846 {
847 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
848 goto out;
849 }
850
851 SET_UI64_RESULT(result, zbx_preprocessor_get_queue_size());
852 }
853 else if (0 == strcmp(tmp, "stats")) /* zabbix[stats,...] */
854 {
855 const char *ip_str, *port_str, *ip;
856 unsigned short port_number;
857 struct zbx_json json;
858
859 if (6 < nparams)
860 {
861 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
862 goto out;
863 }
864
865 if (NULL == (ip_str = get_rparam(&request, 1)) || '\0' == *ip_str)
866 ip = "127.0.0.1";
867 else
868 ip = ip_str;
869
870 if (NULL == (port_str = get_rparam(&request, 2)) || '\0' == *port_str)
871 {
872 port_number = ZBX_DEFAULT_SERVER_PORT;
873 }
874 else if (SUCCEED != is_ushort(port_str, &port_number))
875 {
876 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
877 goto out;
878 }
879
880 if (3 >= nparams)
881 {
882 if ((NULL == ip_str || '\0' == *ip_str) && (NULL == port_str || '\0' == *port_str))
883 {
884 zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
885
886 /* Adding "data" object to JSON structure to make identical JSONPath expressions */
887 /* work for both data received from internal and external source. */
888 zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA);
889
890 zbx_get_zabbix_stats(&json);
891
892 zbx_json_close(&json);
893
894 set_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer);
895
896 zbx_json_free(&json);
897 }
898 else if (SUCCEED != zbx_get_remote_zabbix_stats(ip, port_number, result))
899 goto out;
900 }
901 else
902 {
903 tmp1 = get_rparam(&request, 3);
904
905 if (0 == strcmp(tmp1, ZBX_PROTO_VALUE_ZABBIX_STATS_QUEUE))
906 {
907 tmp = get_rparam(&request, 4); /* from */
908 tmp1 = get_rparam(&request, 5); /* to */
909
910 if ((NULL == ip_str || '\0' == *ip_str) && (NULL == port_str || '\0' == *port_str))
911 {
912 int from = ZBX_QUEUE_FROM_DEFAULT, to = ZBX_QUEUE_TO_INFINITY;
913
914 if (NULL != tmp && '\0' != *tmp &&
915 FAIL == is_time_suffix(tmp, &from, ZBX_LENGTH_UNLIMITED))
916 {
917 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter."));
918 goto out;
919 }
920
921 if (NULL != tmp1 && '\0' != *tmp1 &&
922 FAIL == is_time_suffix(tmp1, &to, ZBX_LENGTH_UNLIMITED))
923 {
924 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid sixth parameter."));
925 goto out;
926 }
927
928 if (ZBX_QUEUE_TO_INFINITY != to && from > to)
929 {
930 SET_MSG_RESULT(result, zbx_strdup(NULL, "Parameters represent an"
931 " invalid interval."));
932 goto out;
933 }
934
935 zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
936
937 zbx_json_adduint64(&json, ZBX_PROTO_VALUE_ZABBIX_STATS_QUEUE,
938 DCget_item_queue(NULL, from, to));
939
940 set_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer);
941
942 zbx_json_free(&json);
943 }
944 else if (SUCCEED != zbx_get_remote_zabbix_stats_queue(ip, port_number, tmp, tmp1,
945 result))
946 {
947 goto out;
948 }
949 }
950 else
951 {
952 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid forth parameter."));
953 goto out;
954 }
955 }
956 }
957 else
958 {
959 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
960 goto out;
961 }
962
963 ret = SUCCEED;
964 out:
965 if (NOTSUPPORTED == ret && !ISSET_MSG(result))
966 SET_MSG_RESULT(result, zbx_strdup(NULL, "Internal check is not supported."));
967
968 free_request(&request);
969
970 return ret;
971 }
972