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