int SYSTEM_CPU_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) { int i; zbx_vector_uint64_t cpus; struct zbx_json json; zbx_vector_uint64_create(&cpus); if (SUCCEED != get_cpu_statuses(&cpus)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Collector is not started.")); zbx_vector_uint64_destroy(&cpus); return SYSINFO_RET_FAIL; } zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); for (i = 0; i < cpus.values_num; i++) { zbx_json_addobject(&json, NULL); zbx_json_adduint64(&json, "{#CPU.NUMBER}", i); zbx_json_addstring(&json, "{#CPU.STATUS}", (SYSINFO_RET_OK == cpus.values[i] ? "online" : "offline"), ZBX_JSON_TYPE_STRING); zbx_json_close(&json); } zbx_json_close(&json); SET_STR_RESULT(result, zbx_strdup(result->str, json.buffer)); zbx_json_free(&json); zbx_vector_uint64_destroy(&cpus); return SYSINFO_RET_OK; }
int USER_PERFCOUNTER(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { PERF_COUNTERS *perfs = NULL; int ret = SYSINFO_RET_FAIL; if ( !PERF_COLLECTOR_STARTED(collector) ) { SET_MSG_RESULT(result, strdup("Collector is not started!")); return SYSINFO_RET_OK; } for(perfs = collector->perfs.pPerfCounterList; perfs; perfs=perfs->next) { if ( 0 == strcmp(perfs->name, param) ) { SET_DBL_RESULT(result, perfs->lastValue); ret = SYSINFO_RET_OK; break; } } return ret; }
static int get_net_stat(const char *if_name, net_stat_t *ns, char **error) { #if defined(HAVE_LIBPERFSTAT) perfstat_id_t ps_id; perfstat_netinterface_t ps_netif; if (NULL == if_name || '\0' == *if_name) { *error = zbx_strdup(NULL, "Network interface name cannot be empty."); return SYSINFO_RET_FAIL; } strscpy(ps_id.name, if_name); if (-1 == perfstat_netinterface(&ps_id, &ps_netif, sizeof(ps_netif), 1)) { *error = zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)); return SYSINFO_RET_FAIL; } ns->ibytes = (zbx_uint64_t)ps_netif.ibytes; ns->ipackets = (zbx_uint64_t)ps_netif.ipackets; ns->ierr = (zbx_uint64_t)ps_netif.ierrors; ns->obytes = (zbx_uint64_t)ps_netif.obytes; ns->opackets = (zbx_uint64_t)ps_netif.opackets; ns->oerr = (zbx_uint64_t)ps_netif.oerrors; ns->colls = (zbx_uint64_t)ps_netif.collisions; return SYSINFO_RET_OK; #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API.")); return SYSINFO_RET_FAIL; #endif }
static int web_set_required_response(AGENT_RESULT *result, struct web *opt, const char *params, int param_id) { char req_code_tmp[WEB_MAX_HTTP_CODE_STRLEN] = {0}; zbx_uint64_t req_code_test; if (get_param(params, param_id, req_code_tmp, WEB_MAX_HTTP_CODE_STRLEN)) goto failed; if (strlen(req_code_tmp)) { if (is_uint_range(req_code_tmp, &req_code_test, WEB_MIN_HTTP_CODE, WEB_MAX_HTTP_CODE)) goto failed; opt->required_response = (int) req_code_test; return SUCCEED; } else { opt->required_response = WEB_DEF_HTTP_CODE; return SUCCEED; } failed: SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Invalid RESPONSE CODE parameter", NULL)); return FAIL; }
int SYSTEM_HOSTNAME(AGENT_REQUEST *request, AGENT_RESULT *result) { char *hostname; long hostbufsize = 0; #ifdef _SC_HOST_NAME_MAX hostbufsize = sysconf(_SC_HOST_NAME_MAX) + 1; #endif if (0 == hostbufsize) hostbufsize = 256; hostname = zbx_malloc(NULL, hostbufsize); if (0 != gethostname(hostname, hostbufsize)) { zbx_free(hostname); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } SET_STR_RESULT(result, hostname); return SYSINFO_RET_OK; }
int SYSTEM_CPU_UTIL(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char cpuname[MAX_STRING_LEN]; char type[MAX_STRING_LEN]; char mode[MAX_STRING_LEN]; int cpu_num = 0; assert(result); init_result(result); if(num_param(param) > 3) { return SYSINFO_RET_FAIL; } if(get_param(param, 1, cpuname, sizeof(cpuname)) != 0) { cpuname[0] = '\0'; } if(cpuname[0] == '\0') { /* default parameter */ zbx_snprintf(cpuname, sizeof(cpuname), "all"); } if(get_param(param, 2, type, sizeof(type)) != 0) { type[0] = '\0'; } if(type[0] == '\0') { /* default parameter */ zbx_snprintf(type, sizeof(type), "user"); } if(get_param(param, 3, mode, sizeof(mode)) != 0) { mode[0] = '\0'; } if(mode[0] == '\0') { /* default parameter */ zbx_snprintf(mode, sizeof(mode), "avg1"); } if ( !CPU_COLLECTOR_STARTED(collector) ) { SET_MSG_RESULT(result, strdup("Collector is not started!")); return SYSINFO_RET_OK; } if(strcmp(cpuname,"all") == 0) { cpu_num = 0; } else { cpu_num = atoi(cpuname)+1; if ((cpu_num < 1) || (cpu_num > collector->cpus.count)) return SYSINFO_RET_FAIL; } if( 0 == strcmp(type,"idle")) { if( 0 == strcmp(mode,"avg1")) SET_DBL_RESULT(result, collector->cpus.cpu[cpu_num].idle1) else if( 0 == strcmp(mode,"avg5")) SET_DBL_RESULT(result, collector->cpus.cpu[cpu_num].idle5) else if( 0 == strcmp(mode,"avg15")) SET_DBL_RESULT(result, collector->cpus.cpu[cpu_num].idle15) else return SYSINFO_RET_FAIL; } else if( 0 == strcmp(type,"nice"))
static int vfs_dev_rw(const char *param, AGENT_RESULT *result, int rw) { ZBX_SINGLE_DISKDEVICE_DATA *device; char devname[32], tmp[16]; int type, mode, nparam; zbx_uint64_t dstats[ZBX_DSTAT_MAX]; char *pd; /* pointer to device name without '/dev/' prefix, e.g. 'da0' */ if (3 < (nparam = num_param(param))) /* too many parameters? */ return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, devname, sizeof(devname))) return SYSINFO_RET_FAIL; pd = devname; if ('\0' != *pd) { if (0 == strcmp(pd, "all")) *pd = '\0'; else { /* skip prefix ZBX_DEV_PFX, if present */ if (0 == strncmp(pd, ZBX_DEV_PFX, sizeof(ZBX_DEV_PFX) - 1)) pd += sizeof(ZBX_DEV_PFX) - 1; } } if (0 != get_param(param, 2, tmp, sizeof(tmp))) *tmp = '\0'; if ('\0' == *tmp || 0 == strcmp(tmp, "bps")) /* default parameter */ type = ZBX_DSTAT_TYPE_BPS; else if (0 == strcmp(tmp, "ops")) type = ZBX_DSTAT_TYPE_OPS; else if (0 == strcmp(tmp, "bytes")) type = ZBX_DSTAT_TYPE_BYTE; else if (0 == strcmp(tmp, "operations")) type = ZBX_DSTAT_TYPE_OPER; else return SYSINFO_RET_FAIL; if (type == ZBX_DSTAT_TYPE_BYTE || type == ZBX_DSTAT_TYPE_OPER) { if (nparam > 2) return SYSINFO_RET_FAIL; if (FAIL == get_diskstat(pd, dstats)) return SYSINFO_RET_FAIL; if (ZBX_DSTAT_TYPE_BYTE == type) SET_UI64_RESULT(result, dstats[(ZBX_DEV_READ == rw ? ZBX_DSTAT_R_BYTE : ZBX_DSTAT_W_BYTE)]); else /* ZBX_DSTAT_TYPE_OPER */ SET_UI64_RESULT(result, dstats[(ZBX_DEV_READ == rw ? ZBX_DSTAT_R_OPER : ZBX_DSTAT_W_OPER)]); return SYSINFO_RET_OK; } if (0 != get_param(param, 3, tmp, sizeof(tmp))) *tmp = '\0'; if ('\0' == *tmp || 0 == strcmp(tmp, "avg1")) /* default parameter */ mode = ZBX_AVG1; else if (0 == strcmp(tmp, "avg5")) mode = ZBX_AVG5; else if (0 == strcmp(tmp, "avg15")) mode = ZBX_AVG15; else return SYSINFO_RET_FAIL; if (NULL == collector) { /* CPU statistics collector and (optionally) disk statistics collector is started only when Zabbix */ /* agentd is running as a daemon. When Zabbix agent or agentd is started with "-p" or "-t" parameter */ /* the collectors are not available and keys "vfs.dev.read", "vfs.dev.write" with some parameters */ /* (e.g. sps, ops) are not supported. */ SET_MSG_RESULT(result, strdup("This parameter is available only in daemon mode when collectors are started.")); return SYSINFO_RET_FAIL; } if (NULL == (device = collector_diskdevice_get(pd))) { if (FAIL == get_diskstat(pd, dstats)) /* validate device name */ return SYSINFO_RET_FAIL; if (NULL == (device = collector_diskdevice_add(pd))) return SYSINFO_RET_FAIL; } if (ZBX_DSTAT_TYPE_BPS == type) /* default parameter */ SET_DBL_RESULT(result, (ZBX_DEV_READ == rw ? device->r_bps[mode] : device->w_bps[mode])); else if (ZBX_DSTAT_TYPE_OPS == type) SET_DBL_RESULT(result, (ZBX_DEV_READ == rw ? device->r_ops[mode] : device->w_ops[mode])); return SYSINFO_RET_OK; }
int PROC_NUM(AGENT_REQUEST *request, AGENT_RESULT *result) { char *procname, *proccomm, *param; int zbx_proc_stat, count, i, proc_ok, stat_ok, comm_ok; int proccount = 0; size_t sz; struct passwd *usrinfo; #ifdef KERN_PROC2 int mib[6]; struct kinfo_proc2 *proc = NULL; #else int mib[4]; struct kinfo_proc *proc = NULL; #endif char **argv = NULL, *args = NULL; size_t argv_alloc = 0, args_alloc = 0; int argc; if (4 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } procname = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL != param && '\0' != *param) { errno = 0; if (NULL == (usrinfo = getpwnam(param))) { if (0 == errno) SET_MSG_RESULT(result, zbx_strdup(NULL, "Specified user does not exist.")); else SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain user information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } } else usrinfo = NULL; param = get_rparam(request, 2); if (NULL == param || '\0' == *param || 0 == strcmp(param, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else if (0 == strcmp(param, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(param, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(param, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } proccomm = get_rparam(request, 3); mib[0] = CTL_KERN; if (NULL != usrinfo) { mib[2] = KERN_PROC_UID; mib[3] = usrinfo->pw_uid; } else { mib[2] = KERN_PROC_ALL; mib[3] = 0; } #ifdef KERN_PROC2 mib[1] = KERN_PROC2; mib[4] = sizeof(struct kinfo_proc2); mib[5] = 0; sz = 0; if (0 != sysctl(mib, 6, NULL, &sz, NULL, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain necessary buffer size from system: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } proc = (struct kinfo_proc2 *)zbx_malloc(proc, sz); mib[5] = (int)(sz / sizeof(struct kinfo_proc2)); if (0 != sysctl(mib, 6, proc, &sz, NULL, 0)) { zbx_free(proc); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain process information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } count = sz / sizeof(struct kinfo_proc2); #else mib[1] = KERN_PROC; sz = 0; if (0 != sysctl(mib, 4, NULL, &sz, NULL, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain necessary buffer size from system: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } proc = (struct kinfo_proc *)zbx_malloc(proc, sz); if (0 != sysctl(mib, 4, proc, &sz, NULL, 0)) { zbx_free(proc); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain process information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } count = sz / sizeof(struct kinfo_proc); #endif for (i = 0; i < count; i++) { proc_ok = 0; stat_ok = 0; comm_ok = 0; if (NULL == procname || '\0' == *procname || 0 == strcmp(procname, proc[i].ZBX_P_COMM)) proc_ok = 1; stat_ok = (zbx_proc_stat == ZBX_PROC_STAT_ALL || (zbx_proc_stat == ZBX_PROC_STAT_RUN && (proc[i].ZBX_P_STAT == SRUN || proc[i].ZBX_P_STAT == SONPROC)) || (zbx_proc_stat == ZBX_PROC_STAT_SLEEP && proc[i].ZBX_P_STAT == SSLEEP) || (zbx_proc_stat == ZBX_PROC_STAT_ZOMB && (proc[i].ZBX_P_STAT == SZOMB || proc[i].ZBX_P_STAT == SDEAD))); if (NULL != proccomm && '\0' != *proccomm) { if (SUCCEED == proc_argv(proc[i].ZBX_P_PID, &argv, &argv_alloc, &argc)) { collect_args(argv, argc, &args, &args_alloc); if (NULL != zbx_regexp_match(args, proccomm, NULL)) comm_ok = 1; } } else comm_ok = 1; if (proc_ok && stat_ok && comm_ok) proccount++; } zbx_free(proc); zbx_free(argv); zbx_free(args); SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
static bool convert_result(PyObject *py_result, AGENT_RESULT *result, const char *request_key) { uint64_t ui64; bool has_ui64_val; if (!get_uint64_attr_from_py(py_result, result_attr_ui64, &ui64, &has_ui64_val)) { log(LOG_ERR, "Unable to get value '%s': " "unable to get attribute '%s'", request_key, result_attr_ui64); return false; } if (has_ui64_val) { SET_UI64_RESULT(result, ui64); } double dbl; bool has_dbl_val; if (!get_double_attr_from_py(py_result, result_attr_dbl, &dbl, &has_dbl_val)) { log(LOG_ERR, "Unable to get value '%s': " "unable to get attribute '%s'", request_key, result_attr_dbl); return false; } if (has_dbl_val) { SET_DBL_RESULT(result, dbl); } char *str = NULL; if (!get_string_attr_from_py(py_result, result_attr_str, &str, true)) { log(LOG_ERR, "Unable to get value '%s': " "unable to get attribute '%s'", request_key, result_attr_str); return false; } if (str) { SET_STR_RESULT(result, str); } char *text = NULL; if (!get_string_attr_from_py(py_result, result_attr_text, &text, true)) { log(LOG_ERR, "Unable to get value '%s': " "unable to get attribute '%s'", request_key, result_attr_text); return false; } if (text) { SET_TEXT_RESULT(result, text); } char *msg = NULL; if (!get_string_attr_from_py(py_result, result_attr_msg, &msg, true)) { log(LOG_ERR, "Unable to get value '%s': " "unable to get attribute '%s'", request_key, result_attr_msg); return false; } if (msg) { SET_MSG_RESULT(result, msg); } return true; }
int check_service(AGENT_REQUEST *request, const char *default_addr, AGENT_RESULT *result, int perf) { unsigned short port = 0; char *service, *ip_str, ip[MAX_ZBX_DNSNAME_LEN + 1], *port_str; int value_int, ret = SYSINFO_RET_FAIL; double check_time; check_time = zbx_time(); if (3 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } service = get_rparam(request, 0); ip_str = get_rparam(request, 1); port_str = get_rparam(request, 2); if (NULL == service || '\0' == *service) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == ip_str || '\0' == *ip_str) strscpy(ip, default_addr); else strscpy(ip, ip_str); if (NULL != port_str && '\0' != *port_str && SUCCEED != is_ushort(port_str, &port)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } if (0 == strncmp("net.tcp.service", get_rkey(request), 15)) { if (0 == strcmp(service, "ssh")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_SSH_PORT; ret = check_ssh(ip, port, CONFIG_TIMEOUT, &value_int); } else if (0 == strcmp(service, "ldap")) { #ifdef HAVE_LDAP if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_LDAP_PORT; ret = check_ldap(ip, port, CONFIG_TIMEOUT, &value_int); #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for LDAP check was not compiled in.")); #endif } else if (0 == strcmp(service, "smtp")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_SMTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_smtp, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "ftp")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_FTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_ftp, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "http")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_HTTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int); } else if (0 == strcmp(service, "pop")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_POP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_pop, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "nntp")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_NNTP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_nntp, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "imap")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_IMAP_PORT; ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_imap, "a1 LOGOUT\r\n", &value_int); } else if (0 == strcmp(service, "tcp")) { if (NULL == port_str || '\0' == *port_str) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int); } else if (0 == strcmp(service, "https")) { #ifdef HAVE_LIBCURL if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_HTTPS_PORT; ret = check_https(ip, port, CONFIG_TIMEOUT, &value_int); #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for HTTPS check was not compiled in.")); #endif } else if (0 == strcmp(service, "telnet")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_TELNET_PORT; ret = check_telnet(ip, port, CONFIG_TIMEOUT, &value_int); } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return ret; } } else /* net.udp.service */ { if (0 == strcmp(service, "ntp")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_NTP_PORT; ret = check_ntp(ip, port, CONFIG_TIMEOUT, &value_int); } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return ret; } } if (SYSINFO_RET_OK == ret) { if (0 != perf) { if (0 != value_int) { check_time = zbx_time() - check_time; if (ZBX_FLOAT_PRECISION > check_time) check_time = ZBX_FLOAT_PRECISION; SET_DBL_RESULT(result, check_time); } else SET_DBL_RESULT(result, 0.0); } else SET_UI64_RESULT(result, value_int); } return ret; }
/****************************************************************************** * * * Function: evaluate_aggregate * * * * Parameters: item - [IN] aggregated item * * grp_func - [IN] one of ZBX_GRP_FUNC_* * * groups - [IN] list of comma-separated host groups * * itemkey - [IN] item key to aggregate * * item_func - [IN] one of ZBX_DB_GET_HIST_* * * param - [IN] item_func parameter (optional) * * * * Return value: SUCCEED - aggregate item evaluated successfully * * FAIL - otherwise * * * ******************************************************************************/ static int evaluate_aggregate(DC_ITEM *item, AGENT_RESULT *res, int grp_func, const char *groups, const char *itemkey, int item_func, const char *param) { const char *__function_name = "evaluate_aggregate"; char *sql = NULL; size_t sql_alloc = 1024, sql_offset = 0; zbx_uint64_t itemid; zbx_vector_uint64_t itemids; DB_RESULT result; DB_ROW row; unsigned char value_type; history_value_t value; int num = 0, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() grp_func:%d groups:'%s' itemkey:'%s' item_func:%d param:'%s'", __function_name, grp_func, groups, itemkey, item_func, param); memset(&value, 0, sizeof(value)); zbx_vector_uint64_create(&itemids); aggregate_get_items(&itemids, groups, itemkey); if (0 == itemids.values_num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No items for key [%s] in group(s) [%s]", itemkey, groups)); goto clean; } sql = zbx_malloc(sql, sql_alloc); if (ZBX_DB_GET_HIST_VALUE == item_func) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select value_type,lastvalue" " from items" " where lastvalue is not null" " and value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { value_type = (unsigned char)atoi(row[0]); evaluate_one(item, &value, &num, grp_func, row[1], value_type); } DBfree_result(result); } else { int clock_from; unsigned int period; char **h_value; if (FAIL == is_uint_suffix(param, &period)) { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter")); goto clean; } clock_from = time(NULL) - period; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,value_type" " from items" " where value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); value_type = (unsigned char)atoi(row[1]); h_value = DBget_history(itemid, value_type, item_func, clock_from, 0, NULL, NULL, 0); if (NULL != h_value[0]) evaluate_one(item, &value, &num, grp_func, h_value[0], value_type); DBfree_history(h_value); } DBfree_result(result); } if (0 == num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key \"%s\" in group(s) \"%s\"", itemkey, groups)); goto clean; } if (ZBX_GRP_FUNC_AVG == grp_func) { switch (item->value_type) { case ITEM_VALUE_TYPE_FLOAT: value.dbl = value.dbl / num; break; case ITEM_VALUE_TYPE_UINT64: value.ui64 = value.ui64 / num; break; default: assert(0); } } if (ITEM_VALUE_TYPE_FLOAT == item->value_type) SET_DBL_RESULT(res, value.dbl); else SET_UI64_RESULT(res, value.ui64); ret = SUCCEED; clean: zbx_vector_uint64_destroy(&itemids); zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: get_value_agent * * * * Purpose: retrieve data from Zabbix agent * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * and result_str (as string) * * NETWORK_ERROR - network related error occurred * * NOTSUPPORTED - item not supported by the agent * * AGENT_ERROR - uncritical error on agent side occurred * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: error will contain error message * * * ******************************************************************************/ int get_value_agent(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value_agent"; zbx_socket_t s; char buffer[MAX_STRING_LEN]; int ret = SUCCEED; ssize_t received_len; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' addr:'%s' key:'%s'", __function_name, item->host.host, item->interface.addr, item->key); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0))) { zbx_snprintf(buffer, sizeof(buffer), "%s\n", item->key); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", buffer); /* send requests using old protocol */ if (SUCCEED != zbx_tcp_send_raw(&s, buffer)) ret = NETWORK_ERROR; else if (FAIL != (received_len = zbx_tcp_recv_ext(&s, ZBX_TCP_READ_UNTIL_CLOSE, 0))) ret = SUCCEED; else ret = TIMEOUT_ERROR; } else ret = NETWORK_ERROR; if (SUCCEED == ret) { zbx_rtrim(s.buffer, " \r\n"); zbx_ltrim(s.buffer, " "); zabbix_log(LOG_LEVEL_DEBUG, "get value from agent result: '%s'", s.buffer); if (0 == strcmp(s.buffer, ZBX_NOTSUPPORTED)) { /* 'ZBX_NOTSUPPORTED\0<error message>' */ if (sizeof(ZBX_NOTSUPPORTED) < s.read_bytes) zbx_snprintf(buffer, sizeof(buffer), "%s", s.buffer + sizeof(ZBX_NOTSUPPORTED)); else zbx_snprintf(buffer, sizeof(buffer), "Not supported by Zabbix Agent"); SET_MSG_RESULT(result, strdup(buffer)); ret = NOTSUPPORTED; } else if (0 == strcmp(s.buffer, ZBX_ERROR)) { zbx_snprintf(buffer, sizeof(buffer), "Zabbix Agent non-critical error"); SET_MSG_RESULT(result, strdup(buffer)); ret = AGENT_ERROR; } else if (0 == received_len) { zbx_snprintf(buffer, sizeof(buffer), "Received empty response from Zabbix Agent at [%s]." " Assuming that agent dropped connection because of access permissions.", item->interface.addr); SET_MSG_RESULT(result, strdup(buffer)); ret = NETWORK_ERROR; } else if (SUCCEED != set_result_type(result, item->value_type, item->data_type, s.buffer)) ret = NOTSUPPORTED; } else { zbx_snprintf(buffer, sizeof(buffer), "Get value from agent failed: %s", zbx_socket_strerror()); SET_MSG_RESULT(result, strdup(buffer)); } zbx_tcp_close(&s); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function : This function will run a redis command and set the reply * * Returns : 0 (success), 1 (failure) * * * ******************************************************************************/ int redis_command(AGENT_RESULT *result, char *zbx_key, redisContext *redisC, redisReply **redisRptr, char *command, char *param, int redisReplyType) { // Declare Variables char zbx_msg[MAX_LENGTH_MSG] = ""; char redisCmd[MAX_LENGTH_STRING]; redisReply *redisR; // If there are parameters if (param != NULL) {zbx_snprintf(redisCmd,MAX_LENGTH_STRING,"%s %s",command,param);} // If there are no parameters if (param == NULL) {zbx_snprintf(redisCmd,MAX_LENGTH_STRING,"%s",command);} // If the connection is lost if (redisC == NULL || redisC->err) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"Redis connection lost (%s)",redisC->errstr); goto command_invalid; } // Run the redis command redisR = redisCommand(redisC,redisCmd); // If the connection is lost if (redisR == NULL) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"Redis connection lost (%s)",redisC->errstr); goto command_invalid; } // If the reply type is an error if (redisR->type == REDIS_REPLY_ERROR) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"Redis command error (%s)",redisR->str); goto command_invalid; } // If the redis reply type is to be checked if (redisReplyType == 9999) {goto command_valid;} // If the reply is not valid if (redis_reply_valid(redisR->type,redisReplyType,command,zbx_key,zbx_msg) == 1) {goto command_invalid;} command_valid: // Assign the reply *redisRptr = redisR; return 0; command_invalid: // Log message zabbix_log(LOG_LEVEL_DEBUG,"Module (%s) - %s - Key %s",MODULE,zbx_msg,zbx_key); // Set message SET_MSG_RESULT(result,strdup(zbx_msg)); return 1; }
/****************************************************************************** * * * Function : This function will create a redis session on a redis server * * Returns : 0 (success), 1 (failure) * * * ******************************************************************************/ redisContext * redis_session(AGENT_RESULT *result, char *zbx_key, char *redis_server, char *redis_port, char *redis_timeout, char *redis_password) { // Declare Variables char zbx_msg[MAX_LENGTH_MSG] = ""; redisReply *redisR; redisContext *redisC; struct timeval timeout; // Set Timeout timeout.tv_sec = atol(redis_timeout); timeout.tv_usec = 0; // Attempt the connection redisC = redisConnectWithTimeout(redis_server,atol(redis_port),timeout); // If there was an error connecting if (redisC == NULL || redisC->err) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"Redis connection failed (Unknown)"); // If there is an error message if (redisC->err) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"Redis connection failed (%s)",redisC->errstr); } goto session_invalid; } // Authenticate with blank password (The assumption is that there could be a blank password) if (strlen(redis_password) == 0) {redisR = redisCommand(redisC,"AUTH ''");} if (strlen(redis_password) > 0) {redisR = redisCommand(redisC,"AUTH %s",redis_password);} // If the connection is lost if(redisR == NULL) {goto error_connection_lost;} // Free the reply freeReplyObject(redisR); // Test whether authentication has been successful redisR = redisCommand(redisC,"ECHO Authentication-Test"); // If the connection is lost if(redisR == NULL) {goto error_connection_lost;} // If the authentication failed if (strcmp(redisR->str,"NOAUTH Authentication required.") == 0) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"Redis authentication failed",MODULE); // Free the reply freeReplyObject(redisR); goto session_invalid; } // Free the reply freeReplyObject(redisR); // We want to set the client name in order to exclude from client discovery redisR = redisCommand(redisC,"CLIENT SETNAME %s",MODULE); // If the connection is lost if(redisR == NULL) {goto error_connection_lost;} // Free the reply freeReplyObject(redisR); goto session_valid; error_connection_lost: // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"Redis connection lost (%s)",redisC->errstr); goto session_invalid; session_valid: return redisC; session_invalid: // Free the context redisFree(redisC); // Log message zabbix_log(LOG_LEVEL_DEBUG,"Module (%s) - %s - Key %s",MODULE,zbx_msg,zbx_key); // Set message SET_MSG_RESULT(result,strdup(zbx_msg)); return NULL; }
/************************************************************* * * * Function : This function will validate standard params * * Returns : 0 (valid), 1 (invalid) * * * *************************************************************/ int validate_param(AGENT_RESULT *result,char *zbx_key, char *param, char *value, char *value_default, int allow_empty, int min, int max) { // Declare variables char zbx_msg[MAX_LENGTH_MSG] = ""; // If the value is empty and there is a default value if (strlen(value) == 0 && strlen(value_default) > 0) { // Set the value to default zbx_strlcpy(value,value_default,MAX_LENGTH_PARAM); } // If the value is empty and thats not allowed if (strlen(value) == 0 && ! allow_empty) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"%s must not be empty",param); goto param_invalid; } // If there is a minimum required if (min > 0 && atol(value) < min) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"%s must be an integer greater than or equal to %lld",param,min); goto param_invalid; } // If there is a maximum required if (max > 0 && atol(value) > max) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"%s must be an integer less than or equal to %lld",param,max); goto param_invalid; } // For specific parameters that required specific values if (strcmp(param,"Datatype") == 0) { // Validate value contents if (strcmp(value,"integer") != 0 && strcmp(value,"float") != 0 && strcmp(value,"string") != 0 && strcmp(value,"text") != 0) { // Form message zbx_snprintf(zbx_msg,MAX_LENGTH_MSG,"%s must be an integer,float,string,text",param); goto param_invalid; } } param_valid: return 0; param_invalid: // Log message zabbix_log(LOG_LEVEL_DEBUG,"Module (%s) - %s - Key %s",MODULE,zbx_msg,zbx_key); // Set message SET_MSG_RESULT(result,strdup(zbx_msg)); return 1; }
int telnet_execute(ZBX_SOCKET socket_fd, const char *command, AGENT_RESULT *result, const char *encoding) { const char *__function_name = "telnet_execute"; char buf[MAX_BUFFER_LEN]; size_t sz, offset; int rc, ret = FAIL; char *command_lf = NULL, *command_crlf = NULL; size_t i, offset_lf, offset_crlf; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); /* `command' with multiple lines may contain CR+LF from the browser; */ /* it should be converted to plain LF to remove echo later on properly */ offset_lf = strlen(command); command_lf = zbx_malloc(command_lf, offset_lf + 1); zbx_strlcpy(command_lf, command, offset_lf + 1); convert_telnet_to_unix_eol(command_lf, &offset_lf); /* telnet protocol requires that end-of-line is transferred as CR+LF */ command_crlf = zbx_malloc(command_crlf, offset_lf * 2 + 1); convert_unix_to_telnet_eol(command_lf, offset_lf, command_crlf, &offset_crlf); telnet_socket_write(socket_fd, command_crlf, offset_crlf); telnet_socket_write(socket_fd, "\r\n", 2); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc = telnet_read(socket_fd, buf, &sz, &offset))) { if (prompt_char == telnet_lastchar(buf, offset)) break; } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() command output:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No prompt: %s", zbx_tcp_strerror())); goto fail; } telnet_rm_echo(buf, &offset, command_lf, offset_lf); /* multi-line commands may have returned additional prompts; */ /* this is not a perfect solution, because in case of multiple */ /* multi-line shell statements these prompts might appear in */ /* the middle of the output, but we still try to be helpful by */ /* removing additional prompts at least from the beginning */ for (i = 0; i < offset_lf; i++) { if ('\n' == command_lf[i]) if (SUCCEED != telnet_rm_echo(buf, &offset, "$ ", 2) && SUCCEED != telnet_rm_echo(buf, &offset, "# ", 2) && SUCCEED != telnet_rm_echo(buf, &offset, "> ", 2) && SUCCEED != telnet_rm_echo(buf, &offset, "% ", 2)) { break; } } telnet_rm_echo(buf, &offset, "\n", 1); telnet_rm_prompt(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() stripped command output:'%.*s'", __function_name, offset, buf); if (MAX_BUFFER_LEN == offset) offset--; buf[offset] = '\0'; SET_STR_RESULT(result, convert_to_utf8(buf, offset, encoding)); ret = SUCCEED; fail: zbx_free(command_lf); zbx_free(command_crlf); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int telnet_login(ZBX_SOCKET socket_fd, const char *username, const char *password, AGENT_RESULT *result) { const char *__function_name = "telnet_login"; char buf[MAX_BUFFER_LEN], c; size_t sz, offset; int rc, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc = telnet_read(socket_fd, buf, &sz, &offset))) { if (':' == telnet_lastchar(buf, offset)) break; } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() login prompt:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No login prompt")); goto fail; } telnet_socket_write(socket_fd, username, strlen(username)); telnet_socket_write(socket_fd, "\r\n", 2); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc == telnet_read(socket_fd, buf, &sz, &offset))) { if (':' == telnet_lastchar(buf, offset)) break; } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() password prompt:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No password prompt")); goto fail; } telnet_socket_write(socket_fd, password, strlen(password)); telnet_socket_write(socket_fd, "\r\n", 2); sz = sizeof(buf); offset = 0; while (ZBX_TCP_ERROR != (rc = telnet_read(socket_fd, buf, &sz, &offset))) { if ('$' == (c = telnet_lastchar(buf, offset)) || '#' == c || '>' == c || '%' == c) { prompt_char = c; break; } } convert_telnet_to_unix_eol(buf, &offset); zabbix_log(LOG_LEVEL_DEBUG, "%s() prompt:'%.*s'", __function_name, offset, buf); if (ZBX_TCP_ERROR == rc) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Login failed")); goto fail; } ret = SUCCEED; fail: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int SYSTEM_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) { char *tmp; int cpu_num, state, mode; if (3 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 0); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all")) cpu_num = ZBX_CPUNUM_ALL; else if (SUCCEED != is_uint31_1(tmp, &cpu_num)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 1); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "user")) state = ZBX_CPU_STATE_USER; else if (0 == strcmp(tmp, "system")) state = ZBX_CPU_STATE_SYSTEM; else if (0 == strcmp(tmp, "idle")) state = ZBX_CPU_STATE_IDLE; else if (0 == strcmp(tmp, "iowait")) state = ZBX_CPU_STATE_IOWAIT; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 2); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1")) mode = ZBX_AVG1; else if (0 == strcmp(tmp, "avg5")) mode = ZBX_AVG5; else if (0 == strcmp(tmp, "avg15")) mode = ZBX_AVG15; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } if (SYSINFO_RET_FAIL == get_cpustat(result, cpu_num, state, mode)) { if (!ISSET_MSG(result)) SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain CPU information.")); return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
int SYSTEM_CPU_LOAD(AGENT_REQUEST *request, AGENT_RESULT *result) { #ifdef HAVE_LIBPERFSTAT #if !defined(SBITS) # define SBITS 16 #endif char *tmp; int mode, per_cpu = 1; perfstat_cpu_total_t ps_cpu_total; double value; if (2 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 0); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all")) per_cpu = 0; else if (0 != strcmp(tmp, "percpu")) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 1); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1")) mode = ZBX_AVG1; else if (0 == strcmp(tmp, "avg5")) mode = ZBX_AVG5; else if (0 == strcmp(tmp, "avg15")) mode = ZBX_AVG15; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } if (-1 == perfstat_cpu_total(NULL, &ps_cpu_total, sizeof(ps_cpu_total), 1)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } value = (double)ps_cpu_total.loadavg[mode] / (1 << SBITS); if (1 == per_cpu) { if (0 >= ps_cpu_total.ncpus) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain number of CPUs.")); return SYSINFO_RET_FAIL; } value /= ps_cpu_total.ncpus; } SET_DBL_RESULT(result, value); return SYSINFO_RET_OK; #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API.")); return SYSINFO_RET_FAIL; #endif }
static int db_odbc_discovery(DC_ITEM *item, AGENT_REQUEST *request, AGENT_RESULT *result) { const char *__function_name = "db_odbc_discovery"; int ret = NOTSUPPORTED, i, j; ZBX_ODBC_DBH dbh; ZBX_ODBC_ROW row; char **columns, *p, macro[MAX_STRING_LEN]; struct zbx_json json; zabbix_log(LOG_LEVEL_DEBUG, "In %s() query:'%s'", __function_name, item->params); if (2 != request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } if (SUCCEED != odbc_DBconnect(&dbh, request->params[1], item->username, item->password, CONFIG_TIMEOUT)) { SET_MSG_RESULT(result, zbx_strdup(NULL, get_last_odbc_strerror())); goto out; } if (NULL != odbc_DBselect(&dbh, item->params)) { columns = zbx_malloc(NULL, sizeof(char *) * dbh.col_num); if (SUCCEED == get_result_columns(&dbh, columns)) { for (i = 0; i < dbh.col_num; i++) zabbix_log(LOG_LEVEL_DEBUG, "%s() column[%d]:'%s'", __function_name, i + 1, columns[i]); for (i = 0; i < dbh.col_num; i++) { for (p = columns[i]; '\0' != *p; p++) { if (0 != isalpha((unsigned char)*p)) *p = toupper((unsigned char)*p); if (SUCCEED != is_macro_char(*p)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot convert column #%d name to macro.", i + 1)); goto clean; } } for (j = 0; j < i; j++) { if (0 == strcmp(columns[i], columns[j])) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Duplicate macro name: {#%s}.", columns[i])); goto clean; } } } zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); while (NULL != (row = odbc_DBfetch(&dbh))) { zbx_json_addobject(&json, NULL); for (i = 0; i < dbh.col_num; i++) { zbx_snprintf(macro, MAX_STRING_LEN, "{#%s}", columns[i]); zbx_json_addstring(&json, macro, row[i], ZBX_JSON_TYPE_STRING); } zbx_json_close(&json); } zbx_json_close(&json); SET_STR_RESULT(result, zbx_strdup(NULL, json.buffer)); zbx_json_free(&json); ret = SUCCEED; clean: for (i = 0; i < dbh.col_num; i++) zbx_free(columns[i]); } else SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain column names.")); zbx_free(columns); } else SET_MSG_RESULT(result, zbx_strdup(NULL, get_last_odbc_strerror())); odbc_DBclose(&dbh); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/* example ssh.run["ls /"] */ static int ssh_run(DC_ITEM *item, AGENT_RESULT *result, const char *encoding) { const char *__function_name = "ssh_run"; zbx_sock_t s; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int auth_pw = 0, rc, ret = NOTSUPPORTED, exitcode, bytecount = 0; char buffer[MAX_BUFFER_LEN], buf[16], *userauthlist, *publickey = NULL, *privatekey = NULL, *ssherr; size_t sz; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot connect to SSH server: %s", zbx_tcp_strerror())); goto close; } /* initializes an SSH session object */ if (NULL == (session = libssh2_session_init())) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot initialize SSH session")); goto tcp_close; } /* set blocking mode on session */ libssh2_session_set_blocking(session, 1); /* Create a session instance and start it up. This will trade welcome */ /* banners, exchange keys, and setup crypto, compression, and MAC layers */ if (0 != libssh2_session_startup(session, s.socket)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot establish SSH session: %s", ssherr)); goto session_free; } /* check what authentication methods are available */ if (NULL != (userauthlist = libssh2_userauth_list(session, item->username, strlen(item->username)))) { if (NULL != strstr(userauthlist, "password")) auth_pw |= 1; if (NULL != strstr(userauthlist, "keyboard-interactive")) auth_pw |= 2; if (NULL != strstr(userauthlist, "publickey")) auth_pw |= 4; } else { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain authentication methods: %s", ssherr)); goto session_close; } zabbix_log(LOG_LEVEL_DEBUG, "%s() supported authentication methods:'%s'", __function_name, userauthlist); switch (item->authtype) { case ITEM_AUTHTYPE_PASSWORD: if (auth_pw & 1) { /* we could authenticate via password */ if (0 != libssh2_userauth_password(session, item->username, item->password)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Password authentication failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() password authentication succeeded", __function_name); } else if (auth_pw & 2) { /* or via keyboard-interactive */ password = item->password; if (0 != libssh2_userauth_keyboard_interactive(session, item->username, &kbd_callback)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Keyboard-interactive authentication" " failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() keyboard-interactive authentication succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; case ITEM_AUTHTYPE_PUBLICKEY: if (auth_pw & 4) { if (NULL == CONFIG_SSH_KEY_LOCATION) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Authentication by public key failed." " SSHKeyLocation option is not set")); goto session_close; } /* or by public key */ publickey = zbx_dsprintf(publickey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->publickey); privatekey = zbx_dsprintf(privatekey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->privatekey); if (SUCCEED != zbx_is_regular_file(publickey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access public key file %s", publickey)); goto session_close; } if (SUCCEED != zbx_is_regular_file(privatekey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access private key file %s", privatekey)); goto session_close; } rc = libssh2_userauth_publickey_fromfile(session, item->username, publickey, privatekey, item->password); zbx_free(publickey); zbx_free(privatekey); if (0 != rc) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Public key authentication failed:" " %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() authentication by public key succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; } /* exec non-blocking on the remove host */ while (NULL == (channel = libssh2_channel_open_session(session))) { switch (libssh2_session_last_error(session, NULL, NULL, 0)) { /* marked for non-blocking I/O but the call would block. */ case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot establish generic session channel")); goto session_close; } } dos2unix(item->params); /* CR+LF (Windows) => LF (Unix) */ /* request a shell on a channel and execute command */ while (0 != (rc = libssh2_channel_exec(channel, item->params))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot request a shell")); goto channel_close; } } for (;;) { /* loop until we block */ do { if (0 < (rc = libssh2_channel_read(channel, buf, sizeof(buf)))) { sz = (size_t)rc; if (sz > MAX_BUFFER_LEN - (bytecount + 1)) sz = MAX_BUFFER_LEN - (bytecount + 1); if (0 == sz) continue; memcpy(buffer + bytecount, buf, sz); bytecount += sz; } } while (rc > 0); /* this is due to blocking that would occur otherwise so we loop on * this condition */ if (LIBSSH2_ERROR_EAGAIN == rc) waitsocket(s.socket, session); else if (rc < 0) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read data from SSH server")); goto channel_close; } else break; } buffer[bytecount] = '\0'; SET_STR_RESULT(result, convert_to_utf8(buffer, bytecount, encoding)); ret = SYSINFO_RET_OK; channel_close: /* close an active data channel */ exitcode = 127; while (0 != (rc = libssh2_channel_close(channel))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: libssh2_session_last_error(session, &ssherr, NULL, 0); zabbix_log(LOG_LEVEL_WARNING, "%s() cannot close generic session channel: %s", __function_name, ssherr); break; } } if (0 == rc) exitcode = libssh2_channel_get_exit_status(channel); zabbix_log(LOG_LEVEL_DEBUG, "%s() exitcode: %d bytecount: %d", __function_name, exitcode, bytecount); libssh2_channel_free(channel); channel = NULL; session_close: libssh2_session_disconnect(session, "Normal Shutdown"); session_free: libssh2_session_free(session); tcp_close: zbx_tcp_close(&s); close: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int SYSTEM_CPU_LOAD(AGENT_REQUEST *request, AGENT_RESULT *result) { char *tmp; int mode, per_cpu = 1, cpu_num; double load[ZBX_AVG_COUNT], value; if (2 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 0); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all")) { per_cpu = 0; } else if (0 != strcmp(tmp, "percpu")) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 1); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1")) mode = ZBX_AVG1; else if (0 == strcmp(tmp, "avg5")) mode = ZBX_AVG5; else if (0 == strcmp(tmp, "avg15")) mode = ZBX_AVG15; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } if (mode >= getloadavg(load, 3)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain load average.")); return SYSINFO_RET_FAIL; } value = load[mode]; if (1 == per_cpu) { if (0 >= (cpu_num = sysconf(_SC_NPROCESSORS_ONLN))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain number of CPUs: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } value /= cpu_num; } SET_DBL_RESULT(result, value); return SYSINFO_RET_OK; }
int get_value_ipmi(DC_ITEM *item, AGENT_RESULT *value) { const char *__function_name = "get_value_ipmi"; zbx_ipmi_host_t *h; zbx_ipmi_sensor_t *s; zbx_ipmi_control_t *c = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s:%s'", __function_name, item->host.host, item->key_orig); if (NULL == os_hnd) { SET_MSG_RESULT(value, strdup("IPMI handler is not initialised")); return NOTSUPPORTED; } h = init_ipmi_host(item->interface.addr, item->interface.port, item->host.ipmi_authtype, item->host.ipmi_privilege, item->host.ipmi_username, item->host.ipmi_password); if (0 == h->domain_up) { if (NULL != h->err) { SET_MSG_RESULT(value, strdup(h->err)); } return h->ret; } s = get_ipmi_sensor_by_id(h, item->ipmi_sensor); if (NULL == s) c = get_ipmi_control_by_name(h, item->ipmi_sensor); if (NULL == s && NULL == c) { SET_MSG_RESULT(value, zbx_dsprintf(NULL, "sensor or control %s@[%s]:%d does not exist", item->ipmi_sensor, h->ip, h->port)); return NOTSUPPORTED; } if (NULL != s) read_ipmi_sensor(h, s); else read_ipmi_control(h, c); if (h->ret != SUCCEED) { if (NULL != h->err) { SET_MSG_RESULT(value, strdup(h->err)); } return h->ret; } if (NULL != s) { if (IPMI_EVENT_READING_TYPE_THRESHOLD == s->reading_type) SET_DBL_RESULT(value, s->value.threshold); else SET_UI64_RESULT(value, s->value.discrete); } if (NULL != c) SET_DBL_RESULT(value, c->val[0]); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(h->ret)); return h->ret; }
int zbx_module_redis_status(AGENT_REQUEST *request, AGENT_RESULT *result) { char *CONFIG_SOURCE_IP = NULL; zbx_sock_t s; char *rs_host, *str_rs_port, *key; unsigned int rs_port; char rs_st_name[MAX_STRING_LEN]; zbx_uint64_t rs_st_value; const char *buf; char *tmp; char *p; int ret = SYSINFO_RET_FAIL; int find = 0; int net_error = 0; if (request->nparam == 3) { rs_host = get_rparam(request, 0); str_rs_port = get_rparam(request, 1); rs_port = atoi(str_rs_port); key = get_rparam(request, 2); } else if (request->nparam == 2) { rs_host = REDIS_DEFAULT_INSTANCE_HOST; str_rs_port = get_rparam(request, 0); rs_port = atoi(str_rs_port); key = get_rparam(request, 1); } else { /* set optional error message */ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters")); return ret; } /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], args:[%s,%d]", rs_host, rs_port); */ if (SUCCEED == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, rs_host, rs_port, 0)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], connect to [%s:%d] successful", rs_host, rs_port); */ if (SUCCEED == zbx_tcp_send_raw(&s, "info\r\nquit\r\n")) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], send request successful"); */ while (NULL != (buf = zbx_tcp_recv_line(&s))) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], got [%s]", buf); */ if (2 == sscanf(buf, "%[^:]:" ZBX_FS_UI64, rs_st_name, &rs_st_value)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], parse result name :[%s] value:[%d]", rs_st_name, rs_st_value); */ if (0 == strcmp(rs_st_name, key)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_status], args:[%d,%s] value:[%d]", rs_port, key, rs_st_value); */ find = 1; SET_UI64_RESULT(result, rs_st_value); ret = SYSINFO_RET_OK; break; } } } } else { net_error = 1; zabbix_log(LOG_LEVEL_WARNING, "module [redis], func [zbx_module_redis_status],get redis status error: [%s]", zbx_tcp_strerror()); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Get redis status error [%s]", zbx_tcp_strerror())); } zbx_tcp_close(&s); } else { net_error = 1; zabbix_log(LOG_LEVEL_WARNING, "module [redis], func [zbx_module_redis_status], connect to redis error: [%s]", zbx_tcp_strerror()); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Connect to redis error [%s]", zbx_tcp_strerror())); } if (find != 1 && net_error == 0) { zabbix_log(LOG_LEVEL_WARNING, "module [redis], func [zbx_module_redis_status], can't find key: [%s]", key); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Not supported key [%s]", key)); } return ret; }
/****************************************************************************** * * * Function: get_value_aggregate * * * * Purpose: retrieve data from Zabbix server (aggregate items) * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * and result_str (as string) * * NOTSUPPORTED - requested item is not supported * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int get_value_aggregate(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value_aggregate"; char tmp[8], params[MAX_STRING_LEN], groups[MAX_STRING_LEN], itemkey[MAX_STRING_LEN], funcp[32]; int grp_func, item_func, ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s'", __function_name, item->key_orig); if (ITEM_VALUE_TYPE_FLOAT != item->value_type && ITEM_VALUE_TYPE_UINT64 != item->value_type) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Value type must be Numeric for aggregate items")); return NOTSUPPORTED; } if (2 != parse_command(item->key, tmp, sizeof(tmp), params, sizeof(params))) return NOTSUPPORTED; if (0 == strcmp(tmp, "grpmin")) grp_func = ZBX_GRP_FUNC_MIN; else if (0 == strcmp(tmp, "grpavg")) grp_func = ZBX_GRP_FUNC_AVG; else if (0 == strcmp(tmp, "grpmax")) grp_func = ZBX_GRP_FUNC_MAX; else if (0 == strcmp(tmp, "grpsum")) grp_func = ZBX_GRP_FUNC_SUM; else return NOTSUPPORTED; if (4 != num_param(params)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters")); return NOTSUPPORTED; } if (0 != get_param(params, 1, groups, sizeof(groups))) return NOTSUPPORTED; if (0 != get_param(params, 2, itemkey, sizeof(itemkey))) return NOTSUPPORTED; if (0 != get_param(params, 3, tmp, sizeof(tmp))) return NOTSUPPORTED; if (0 == strcmp(tmp, "min")) item_func = ZBX_DB_GET_HIST_MIN; else if (0 == strcmp(tmp, "avg")) item_func = ZBX_DB_GET_HIST_AVG; else if (0 == strcmp(tmp, "max")) item_func = ZBX_DB_GET_HIST_MAX; else if (0 == strcmp(tmp, "sum")) item_func = ZBX_DB_GET_HIST_SUM; else if (0 == strcmp(tmp, "count")) item_func = ZBX_DB_GET_HIST_COUNT; else if (0 == strcmp(tmp, "last")) item_func = ZBX_DB_GET_HIST_VALUE; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter")); return NOTSUPPORTED; } if (0 != get_param(params, 4, funcp, sizeof(funcp))) return NOTSUPPORTED; if (SUCCEED != evaluate_aggregate(item, result, grp_func, groups, itemkey, item_func, funcp)) ret = NOTSUPPORTED; zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int PROC_MEM(AGENT_REQUEST *request, AGENT_RESULT *result) { char *procname, *proccomm, *param; int do_task, pagesize, count, i, proc_ok, comm_ok; double value = 0.0, memsize = 0; int proccount = 0; size_t sz; struct passwd *usrinfo; #ifdef KERN_PROC2 int mib[6]; struct kinfo_proc2 *proc = NULL; #else int mib[4]; struct kinfo_proc *proc = NULL; #endif char **argv = NULL, *args = NULL; size_t argv_alloc = 0, args_alloc = 0; int argc; if (4 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } procname = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL != param && '\0' != *param) { errno = 0; if (NULL == (usrinfo = getpwnam(param))) { if (0 == errno) SET_MSG_RESULT(result, zbx_strdup(NULL, "Specified user does not exist.")); else SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain user information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } } else usrinfo = NULL; param = get_rparam(request, 2); if (NULL == param || '\0' == *param || 0 == strcmp(param, "sum")) do_task = ZBX_DO_SUM; else if (0 == strcmp(param, "avg")) do_task = ZBX_DO_AVG; else if (0 == strcmp(param, "max")) do_task = ZBX_DO_MAX; else if (0 == strcmp(param, "min")) do_task = ZBX_DO_MIN; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } proccomm = get_rparam(request, 3); pagesize = getpagesize(); mib[0] = CTL_KERN; if (NULL != usrinfo) { mib[2] = KERN_PROC_UID; mib[3] = usrinfo->pw_uid; } else { mib[2] = KERN_PROC_ALL; mib[3] = 0; } #ifdef KERN_PROC2 mib[1] = KERN_PROC2; mib[4] = sizeof(struct kinfo_proc2); mib[5] = 0; sz = 0; if (0 != sysctl(mib, 6, NULL, &sz, NULL, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain necessary buffer size from system: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } proc = (struct kinfo_proc2 *)zbx_malloc(proc, sz); mib[5] = (int)(sz / sizeof(struct kinfo_proc2)); if (0 != sysctl(mib, 6, proc, &sz, NULL, 0)) { zbx_free(proc); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain process information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } count = sz / sizeof(struct kinfo_proc2); #else mib[1] = KERN_PROC; sz = 0; if (0 != sysctl(mib, 4, NULL, &sz, NULL, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain necessary buffer size from system: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } proc = (struct kinfo_proc *)zbx_malloc(proc, sz); if (0 != sysctl(mib, 4, proc, &sz, NULL, 0)) { zbx_free(proc); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain process information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } count = sz / sizeof(struct kinfo_proc); #endif for (i = 0; i < count; i++) { proc_ok = 0; comm_ok = 0; if (NULL == procname || '\0' == *procname || 0 == strcmp(procname, proc[i].ZBX_P_COMM)) proc_ok = 1; if (NULL != proccomm && '\0' != *proccomm) { if (SUCCEED == proc_argv(proc[i].ZBX_P_PID, &argv, &argv_alloc, &argc)) { collect_args(argv, argc, &args, &args_alloc); if (NULL != zbx_regexp_match(args, proccomm, NULL)) comm_ok = 1; } } else comm_ok = 1; if (proc_ok && comm_ok) { value = proc[i].ZBX_P_VM_TSIZE + proc[i].ZBX_P_VM_DSIZE + proc[i].ZBX_P_VM_SSIZE; value *= pagesize; if (0 == proccount++) memsize = value; else { if (ZBX_DO_MAX == do_task) memsize = MAX(memsize, value); else if (ZBX_DO_MIN == do_task) memsize = MIN(memsize, value); else memsize += value; } } } zbx_free(proc); zbx_free(argv); zbx_free(args); if (ZBX_DO_AVG == do_task) SET_DBL_RESULT(result, proccount == 0 ? 0 : memsize/proccount); else SET_UI64_RESULT(result, memsize); return SYSINFO_RET_OK; }
int SYSTEM_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) { char *tmp; int cpu_num, state, mode; if (3 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 0); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all")) { cpu_num = 0; } else if (SUCCEED != is_uint31_1(tmp, &cpu_num)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } else cpu_num++; tmp = get_rparam(request, 1); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "user")) state = ZBX_CPU_STATE_USER; else if (0 == strcmp(tmp, "nice")) state = ZBX_CPU_STATE_NICE; else if (0 == strcmp(tmp, "system")) state = ZBX_CPU_STATE_SYSTEM; else if (0 == strcmp(tmp, "idle")) state = ZBX_CPU_STATE_IDLE; else if (0 == strcmp(tmp, "iowait")) state = ZBX_CPU_STATE_IOWAIT; else if (0 == strcmp(tmp, "interrupt")) state = ZBX_CPU_STATE_INTERRUPT; else if (0 == strcmp(tmp, "softirq")) state = ZBX_CPU_STATE_SOFTIRQ; else if (0 == strcmp(tmp, "steal")) state = ZBX_CPU_STATE_STEAL; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } tmp = get_rparam(request, 2); if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1")) mode = ZBX_AVG1; else if (0 == strcmp(tmp, "avg5")) mode = ZBX_AVG5; else if (0 == strcmp(tmp, "avg15")) mode = ZBX_AVG15; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } return get_cpustat(result, cpu_num, state, mode); }
int SYSTEM_LOCALTIME(AGENT_REQUEST *request, AGENT_RESULT *result) { char *type, buf[32]; struct tm *tm; size_t offset; int gmtoff, ms; unsigned short h, m; #ifdef _WINDOWS struct _timeb tv; #else struct timeval tv; struct timezone tz; #endif if (1 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } type = get_rparam(request, 0); if (NULL == type || '\0' == *type || 0 == strcmp(type, "utc")) { SET_UI64_RESULT(result, time(NULL)); } else if (0 == strcmp(type, "local")) { #ifdef _WINDOWS _ftime(&tv); tm = localtime(&tv.time); ms = tv.millitm; #else gettimeofday(&tv, &tz); tm = localtime(&tv.tv_sec); ms = (int)(tv.tv_usec / 1000); #endif offset = zbx_snprintf(buf, sizeof(buf), "%04d-%02d-%02d,%02d:%02d:%02d.%03d,", 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, ms); /* timezone offset */ #if defined(HAVE_TM_TM_GMTOFF) gmtoff = tm->tm_gmtoff; #else gmtoff = -timezone; #endif #ifdef _WINDOWS if (0 < tm->tm_isdst) /* daylight saving time */ gmtoff += SEC_PER_HOUR; /* assume DST is one hour */ #endif h = (unsigned short)(abs(gmtoff) / SEC_PER_HOUR); m = (unsigned short)((abs(gmtoff) - h * SEC_PER_HOUR) / SEC_PER_MIN); if (0 <= gmtoff) offset += zbx_snprintf(buf + offset, sizeof(buf) - offset, "+"); else offset += zbx_snprintf(buf + offset, sizeof(buf) - offset, "-"); offset += zbx_snprintf(buf + offset, sizeof(buf) - offset, "%02d:%02d", (int)h, (int)m); SET_STR_RESULT(result, strdup(buf)); } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
int zbx_module_redis_ping(AGENT_REQUEST *request, AGENT_RESULT *result) { char *CONFIG_SOURCE_IP = NULL; zbx_sock_t s; char *rs_host, *str_rs_port; unsigned int rs_port; const char *buf; char rv[MAX_STRING_LEN]; int rs_status = 0; time_t now; char str_time[MAX_STRING_LEN]; char cmd[MAX_STRING_LEN]; char hv[MAX_STRING_LEN]; struct tm *tm = NULL; if (request->nparam == 2) { rs_host = get_rparam(request, 0); str_rs_port = get_rparam(request, 1); rs_port = atoi(str_rs_port); } else if (request->nparam == 1) { rs_host = REDIS_DEFAULT_INSTANCE_HOST; str_rs_port = get_rparam(request, 0); rs_port = atoi(str_rs_port); } else { /* set optional error message */ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters")); return SYSINFO_RET_FAIL; } /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], args:[%s,%d]", rs_host, rs_port); */ time(&now); tm = localtime(&now); strftime(str_time, MAX_STRING_LEN, "%Y%m%d%H%M%S", tm); /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], str_time:[%s]", str_time); */ zbx_snprintf(cmd, MAX_STRING_LEN, "set ZBX_PING %s\r\nget ZBX_PING\r\nquit\r\n",str_time); zbx_snprintf(hv, MAX_STRING_LEN, "+OK$%d%s+OK", strlen(str_time), str_time); if (SUCCEED == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, rs_host, rs_port, 0)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], connect to [%s:%d] successful", rs_host, rs_port); */ if (SUCCEED == zbx_tcp_send_raw(&s, cmd)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], send request successful"); */ strscpy(rv, ""); while (NULL != (buf = zbx_tcp_recv_line(&s))) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], get [%s]", buf); */ zbx_strlcat(rv, buf, MAX_STRING_LEN); } /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], all get [%s]", rv); */ if (0 == strcmp(rv, hv)) { /* for dev zabbix_log(LOG_LEVEL_INFORMATION, "module [redis], func [zbx_module_redis_ping], redis instance:[%s:%d] is up", rs_host, rs_port); */ rs_status = 1; } } zbx_tcp_close(&s); } if (rs_status == 1) { SET_UI64_RESULT(result, 1); } else { SET_UI64_RESULT(result, 0); } return SYSINFO_RET_OK; }
/*int get_value_snmp(double *result,char *result_str,DB_ITEM *item,char *error, int max_error_len)*/ int get_value_snmp(DB_ITEM *item, AGENT_RESULT *value) { #define NEW_APPROACH struct snmp_session session, *ss; struct snmp_pdu *pdu; struct snmp_pdu *response; #ifdef NEW_APPROACH char temp[MAX_STRING_LEN]; #endif oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; struct variable_list *vars; int status; char *p, *c; double dbl; unsigned char *ip; char error[MAX_STRING_LEN]; int ret=SUCCEED; zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP()"); init_result(value); /* assert((item->type == ITEM_TYPE_SNMPv1)||(item->type == ITEM_TYPE_SNMPv2c)); */ assert((item->type == ITEM_TYPE_SNMPv1)||(item->type == ITEM_TYPE_SNMPv2c)||(item->type == ITEM_TYPE_SNMPv3)); snmp_sess_init( &session ); /* session.version = version;*/ if(item->type == ITEM_TYPE_SNMPv1) { session.version = SNMP_VERSION_1; } else if(item->type == ITEM_TYPE_SNMPv2c) { session.version = SNMP_VERSION_2c; } else if(item->type == ITEM_TYPE_SNMPv3) { session.version = SNMP_VERSION_3; } else { zbx_snprintf(error,sizeof(error),"Error in get_value_SNMP. Wrong item type [%d]. Must be SNMP.", item->type); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); return NOTSUPPORTED; } if(item->useip == 1) { #ifdef NEW_APPROACH zbx_snprintf(temp,sizeof(temp),"%s:%d", item->host_ip, item->snmp_port); session.peername = temp; session.remote_port = item->snmp_port; #else session.peername = item->host_ip; session.remote_port = item->snmp_port; #endif } else { #ifdef NEW_APPROACH zbx_snprintf(temp, sizeof(temp), "%s:%d", item->host_dns, item->snmp_port); session.peername = temp; session.remote_port = item->snmp_port; #else session.peername = item->host_dns; session.remote_port = item->snmp_port; #endif } if( (session.version == SNMP_VERSION_1) || (item->type == ITEM_TYPE_SNMPv2c)) { session.community = (u_char *)item->snmp_community; session.community_len = strlen((void *)session.community); zabbix_log( LOG_LEVEL_DEBUG, "SNMP [%s@%s:%d]", session.community, session.peername, session.remote_port); } else if(session.version == SNMP_VERSION_3) { /* set the SNMPv3 user name */ session.securityName = item->snmpv3_securityname; session.securityNameLen = strlen(session.securityName); /* set the security level to authenticated, but not encrypted */ if(item->snmpv3_securitylevel == ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV) { session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; } else if(item->snmpv3_securitylevel == ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV) { session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; /* set the authentication method to MD5 */ session.securityAuthProto = usmHMACMD5AuthProtocol; session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; session.securityAuthKeyLen = USM_AUTH_KU_LEN; if (generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) item->snmpv3_authpassphrase, strlen(item->snmpv3_authpassphrase), session.securityAuthKey, &session.securityAuthKeyLen) != SNMPERR_SUCCESS) { zbx_snprintf(error,sizeof(error),"Error generating Ku from authentication pass phrase."); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); return NOTSUPPORTED; } } else if(item->snmpv3_securitylevel == ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV) { session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; /* set the authentication method to MD5 */ session.securityAuthProto = usmHMACMD5AuthProtocol; session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; session.securityAuthKeyLen = USM_AUTH_KU_LEN; if (generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) item->snmpv3_authpassphrase, strlen(item->snmpv3_authpassphrase), session.securityAuthKey, &session.securityAuthKeyLen) != SNMPERR_SUCCESS) { zbx_snprintf(error,sizeof(error),"Error generating Ku from authentication pass phrase."); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); return NOTSUPPORTED; } /* set the private method to DES */ session.securityPrivProto = usmDESPrivProtocol; session.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; session.securityPrivKeyLen = USM_PRIV_KU_LEN; if (generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) item->snmpv3_privpassphrase, strlen(item->snmpv3_privpassphrase), session.securityPrivKey, &session.securityPrivKeyLen) != SNMPERR_SUCCESS) { zbx_snprintf(error,sizeof(error),"Error generating Ku from priv pass phrase."); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); return NOTSUPPORTED; } } zabbix_log( LOG_LEVEL_DEBUG, "SNMPv3 [%s@%s:%d]", session.securityName, session.peername, session.remote_port); } else { zbx_snprintf(error,sizeof(error),"Error in get_value_SNMP. Unsupported session.version [%d]", (int)session.version); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); return NOTSUPPORTED; } zabbix_log( LOG_LEVEL_DEBUG, "OID [%s]", item->snmp_oid); SOCK_STARTUP; ss = snmp_open(&session); if(ss == NULL) { SOCK_CLEANUP; zbx_snprintf(error,sizeof(error),"Error doing snmp_open()"); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); return NOTSUPPORTED; } zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 0.2"); pdu = snmp_pdu_create(SNMP_MSG_GET); /* Changed to snmp_parse_oid */ /* read_objid(item->snmp_oid, anOID, &anOID_len);*/ snmp_parse_oid(item->snmp_oid, anOID, &anOID_len); #if OTHER_METHODS get_node("sysDescr.0", anOID, &anOID_len); read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len); read_objid("system.sysDescr.0", anOID, &anOID_len); #endif snmp_add_null_var(pdu, anOID, anOID_len); zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 0.3"); status = snmp_synch_response(ss, pdu, &response); zabbix_log( LOG_LEVEL_DEBUG, "Status send [%d]", status); zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 0.4"); zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 1"); if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { zabbix_log( LOG_LEVEL_DEBUG, "In get_value_SNMP() 2"); /* for(vars = response->variables; vars; vars = vars->next_variable) { print_variable(vars->name, vars->name_length, vars); }*/ for(vars = response->variables; vars; vars = vars->next_variable) { int count=1; zabbix_log( LOG_LEVEL_DEBUG, "AV loop(%d)", vars->type); /* if( (vars->type == ASN_INTEGER) ||*/ if( (vars->type == ASN_UINTEGER)|| (vars->type == ASN_COUNTER) || #ifdef OPAQUE_SPECIAL_TYPES (vars->type == ASN_UNSIGNED64) || #endif (vars->type == ASN_TIMETICKS) || (vars->type == ASN_GAUGE) ) { /* *result=(long)*vars->val.integer;*/ /* * This solves situation when large numbers are stored as negative values * http://sourceforge.net/tracker/index.php?func=detail&aid=700145&group_id=23494&atid=378683 */ /*zbx_snprintf(result_str,sizeof(result_str),"%ld",(long)*vars->val.integer);*/ /* zbx_snprintf(result_str,sizeof(result_str),"%lu",(long)*vars->val.integer);*/ /* Not correct. Returns huge values. */ /* SET_UI64_RESULT(value, (zbx_uint64_t)*vars->val.integer);*/ if (vars->type == ASN_GAUGE && *vars->val.integer >= 4294967294) { SET_UI64_RESULT(value, (unsigned long)0); } else { SET_UI64_RESULT(value, (unsigned long)*vars->val.integer); } zabbix_log( LOG_LEVEL_DEBUG, "OID [%s] Type [%d] UI64[" ZBX_FS_UI64 "]", item->snmp_oid, vars->type, (zbx_uint64_t)*vars->val.integer); zabbix_log( LOG_LEVEL_DEBUG, "OID [%s] Type [%d] ULONG[%lu]", item->snmp_oid, vars->type, (zbx_uint64_t)(unsigned long)*vars->val.integer); } else if(vars->type == ASN_COUNTER64) { /* Incorrect code for 32 bit platforms */ /* SET_UI64_RESULT(value, ((vars->val.counter64->high)<<32)+(vars->val.counter64->low));*/ SET_UI64_RESULT(value, (((zbx_uint64_t)vars->val.counter64->high)<<32)+((zbx_uint64_t)vars->val.counter64->low)); } else if(vars->type == ASN_INTEGER #define ASN_FLOAT (ASN_APPLICATION | 8) #define ASN_DOUBLE (ASN_APPLICATION | 9) #ifdef OPAQUE_SPECIAL_TYPES || (vars->type == ASN_INTEGER64) #endif ) { /* Negative integer values are converted to double */ if(*vars->val.integer<0) { SET_DBL_RESULT(value, (double)*vars->val.integer); } else { SET_UI64_RESULT(value, (zbx_uint64_t)*vars->val.integer); } } #ifdef OPAQUE_SPECIAL_TYPES else if(vars->type == ASN_FLOAT) { SET_DBL_RESULT(value, *vars->val.floatVal); } else if(vars->type == ASN_DOUBLE) { SET_DBL_RESULT(value, *vars->val.doubleVal); } #endif else if(vars->type == ASN_OCTET_STR) { if(item->value_type == ITEM_VALUE_TYPE_FLOAT) { p = malloc(vars->val_len+1); if(p) { memcpy(p, vars->val.string, vars->val_len); p[vars->val_len] = '\0'; dbl = strtod(p, NULL); SET_DBL_RESULT(value, dbl); } else { zbx_snprintf(error,sizeof(error),"Cannot allocate required memory"); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); } } else if(item->value_type != ITEM_VALUE_TYPE_STR) { zbx_snprintf(error,sizeof(error),"Cannot store SNMP string value (ASN_OCTET_STR) in item having numeric type"); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); ret = NOTSUPPORTED; } else { zabbix_log( LOG_LEVEL_DEBUG, "ASN_OCTET_STR [%s]", vars->val.string); zabbix_log( LOG_LEVEL_DEBUG, "ASN_OCTET_STR [%d]", vars->val_len); p = malloc(1024); if(p) { memset(p,0,1024); snprint_value(p, 1023, vars->name, vars->name_length, vars); /* Skip STRING: and STRING_HEX: */ c=strchr(p,':'); if(c==NULL) { SET_STR_RESULT(value, strdup(p)); } else { SET_STR_RESULT(value, strdup(c+1)); } zabbix_log( LOG_LEVEL_DEBUG, "ASN_OCTET_STR [%s]", p); free(p); } else { zbx_snprintf(error,MAX_STRING_LEN-1,"Cannot allocate required memory"); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); } /* p = malloc(vars->val_len+1); if(p) { zabbix_log( LOG_LEVEL_WARNING, "Result [%s] len [%d]",vars->val.string,vars->val_len); memcpy(p, vars->val.string, vars->val_len); p[vars->val_len] = '\0'; SET_STR_RESULT(value, p); } else { zbx_snprintf(error,sizeof(error),"Cannot allocate required memory"); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); }*/ } } else if(vars->type == ASN_IPADDRESS) { /* ip = vars->val.string; zbx_snprintf(result_str,sizeof(result_str),"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);*/ /* if(item->type == 0) { ret = NOTSUPPORTED; }*/ if(item->value_type != ITEM_VALUE_TYPE_STR) { zbx_snprintf(error,sizeof(error),"Cannot store SNMP string value (ASN_IPADDRESS) in item having numeric type"); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); ret = NOTSUPPORTED; } else { p = malloc(MAX_STRING_LEN); if(p) { ip = vars->val.string; zbx_snprintf(p,MAX_STRING_LEN-1,"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); SET_STR_RESULT(value, p); } else { zbx_snprintf(error,MAX_STRING_LEN-1,"Cannot allocate required memory"); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); } } } else { /* count is not really used. Has to be removed */ count++; zbx_snprintf(error,sizeof(error),"OID [%s] value #%d has unknow type [%X]", item->snmp_oid, count, vars->type); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); ret = NOTSUPPORTED; } } } else { if (status == STAT_SUCCESS) { zabbix_log( LOG_LEVEL_WARNING, "SNMP error in packet. Reason: %s\n", snmp_errstring(response->errstat)); if(response->errstat == SNMP_ERR_NOSUCHNAME) { zbx_snprintf(error,sizeof(error),"SNMP error [%s]", snmp_errstring(response->errstat)); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); ret=NOTSUPPORTED; } else { zbx_snprintf(error,sizeof(error),"SNMP error [%s]", snmp_errstring(response->errstat)); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); ret=NOTSUPPORTED; } } else if(status == STAT_TIMEOUT) { zbx_snprintf(error,sizeof(error),"Timeout while connecting to [%s]", session.peername); /* snmp_sess_perror("snmpget", ss);*/ zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); ret = NETWORK_ERROR; } else { zbx_snprintf(error,sizeof(error),"SNMP error [%d]", status); zabbix_log( LOG_LEVEL_ERR, "%s", error); SET_MSG_RESULT(value, strdup(error)); ret=NOTSUPPORTED; } } if (response) { snmp_free_pdu(response); } snmp_close(ss); SOCK_CLEANUP; return ret; }