/* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ #include "zbxagentget.h" #include "zbxversion.h" #include "zbxstr.h" #include "zbxtypes.h" #include <stddef.h> int zbx_get_agent_protocol_version_int(const char *version_str) { int version_int; if (0 != strcmp(ZBX_VERSION_UNDEFINED_STR, version_str) && FAIL != (version_int = zbx_get_component_version(version_str))) { return version_int; } return 0; } void zbx_agent_prepare_request(struct zbx_json *j, const char *key, int timeout) { zbx_json_addstring(j, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_GET_PASSIVE_CHECKS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(j, ZBX_PROTO_TAG_DATA); zbx_json_addobject(j, NULL); zbx_json_addstring(j, ZBX_PROTO_TAG_KEY, key, ZBX_JSON_TYPE_STRING); zbx_json_addint64(j, ZBX_PROTO_TAG_TIMEOUT, (zbx_int64_t)timeout); zbx_json_close(j); } int zbx_agent_handle_response(char *buffer, size_t read_bytes, ssize_t received_len, const char *addr, AGENT_RESULT *result, int *version) { zabbix_log(LOG_LEVEL_DEBUG, "get value from agent result: '%s'", buffer); if (0 == received_len) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Received empty response from Zabbix Agent at [%s]." " Assuming that agent dropped connection because of access permissions.", addr)); return NETWORK_ERROR; } if (ZBX_COMPONENT_VERSION(7, 0, 0) <= *version) { struct zbx_json_parse jp, jp_data, jp_row; const char *p = NULL; size_t value_alloc = 0; char *value = NULL, tmp[MAX_STRING_LEN]; zbx_json_type_t value_type; if (FAIL == zbx_json_open(buffer, &jp)) { *version = 0; return FAIL; } if (FAIL == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_VERSION, tmp, sizeof(tmp), NULL)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "cannot find the \"%s\" object in the received JSON" " object.", ZBX_PROTO_TAG_VERSION)); return NETWORK_ERROR; } *version = zbx_get_agent_protocol_version_int(tmp); if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_ERROR, tmp, sizeof(tmp), NULL)) { zbx_replace_invalid_utf8(tmp); SET_MSG_RESULT(result, zbx_strdup(NULL, tmp)); return NETWORK_ERROR; } if (FAIL == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "cannot find the \"%s\" object in the received JSON" " object.", ZBX_PROTO_TAG_DATA)); return NETWORK_ERROR; } if (NULL == (p = zbx_json_next(&jp_data, p))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "received empty data response")); return NETWORK_ERROR; } if (FAIL == zbx_json_brackets_open(p, &jp_row)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "cannot parse response: %s", zbx_json_strerror())); return NETWORK_ERROR; } if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_ERROR, tmp, sizeof(tmp), NULL)) { zbx_replace_invalid_utf8(tmp); SET_MSG_RESULT(result, zbx_strdup(NULL, tmp)); return NOTSUPPORTED; } if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_VALUE, &value, &value_alloc, &value_type)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "cannot parse response: %s", zbx_json_strerror())); return NETWORK_ERROR; } if (ZBX_JSON_TYPE_NULL != value_type) { zbx_replace_invalid_utf8(value); SET_TEXT_RESULT(result, zbx_strdup(NULL, value)); } else zbx_free_agent_result(result); zbx_free(value); return SUCCEED; } if (0 == strcmp(buffer, ZBX_NOTSUPPORTED)) { /* 'ZBX_NOTSUPPORTED\0<error message>' */ if (sizeof(ZBX_NOTSUPPORTED) < read_bytes) SET_MSG_RESULT(result, zbx_dsprintf(NULL, "%s", buffer + sizeof(ZBX_NOTSUPPORTED))); else SET_MSG_RESULT(result, zbx_strdup(NULL, "Not supported by Zabbix Agent")); return NOTSUPPORTED; } else if (0 == strcmp(buffer, ZBX_ERROR)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Zabbix Agent non-critical error")); return AGENT_ERROR; } else { zbx_replace_invalid_utf8(buffer); SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); return SUCCEED; } }