int WEB_PAGE_GET(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char hostname[MAX_STRING_LEN]; char path[MAX_STRING_LEN]; char port_str[8]; char buffer[MAX_BUFFER_LEN]; if (num_param(param) > 3) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, hostname, sizeof(hostname))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, path, sizeof(path))) *path = '\0'; if (0 != get_param(param, 3, port_str, sizeof(port_str)) || '\0' == *port_str) zbx_snprintf(port_str, sizeof(port_str), "%d", ZBX_DEFAULT_HTTP_PORT); else if (FAIL == is_uint(port_str)) return SYSINFO_RET_FAIL; if (SYSINFO_RET_OK == get_http_page(hostname, path, (unsigned short)atoi(port_str), buffer, sizeof(buffer))) { zbx_rtrim(buffer, "\r\n"); SET_TEXT_RESULT(result, strdup(buffer)); } else SET_TEXT_RESULT(result, strdup("EOF")); return SYSINFO_RET_OK; }
int EXECUTE_STR(const char *command, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; char *cmd_result = NULL, error[MAX_STRING_LEN]; assert(result); init_result(result); if (SUCCEED != zbx_execute(command, &cmd_result, error, sizeof(error), CONFIG_TIMEOUT)) { SET_MSG_RESULT(result, zbx_strdup(NULL, error)); goto lbl_exit; } zbx_rtrim(cmd_result, ZBX_WHITESPACE); zabbix_log(LOG_LEVEL_DEBUG, "Run remote command [%s] Result [%d] [%.20s]...", command, strlen(cmd_result), cmd_result); if ('\0' == *cmd_result) /* we got whitespace only */ goto lbl_exit; SET_TEXT_RESULT(result, zbx_strdup(NULL, cmd_result)); ret = SYSINFO_RET_OK; lbl_exit: zbx_free(cmd_result); return ret; }
int EXECUTE_USER_PARAMETER(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret; char *command; if (1 != request->nparam) return SYSINFO_RET_FAIL; command = get_rparam(request, 0); ret = EXECUTE_STR(command, result); if (SYSINFO_RET_FAIL == ret && 0 == result->type) { /* only whitespace */ SET_TEXT_RESULT(result, zbx_strdup(NULL, "")); ret = SYSINFO_RET_OK; } return ret; }
int SYSTEM_HW_CPU(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL, filter, cpu, cur_cpu = -1, offset = 0; zbx_uint64_t maxfreq = FAIL, curfreq = FAIL; char line[MAX_STRING_LEN], name[MAX_STRING_LEN], tmp[MAX_STRING_LEN], buffer[MAX_BUFFER_LEN]; FILE *f; if (2 < num_param(param)) return ret; if (0 != get_param(param, 1, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "all")) cpu = HW_CPU_ALL_CPUS; /* show all CPUs by default */ else if (FAIL == is_uint(tmp)) return ret; else cpu = atoi(tmp); if (0 != get_param(param, 2, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "full")) filter = HW_CPU_SHOW_ALL; /* show full info by default */ else if (0 == strcmp(tmp, "maxfreq")) filter = HW_CPU_SHOW_MAXFREQ; else if (0 == strcmp(tmp, "vendor")) filter = HW_CPU_SHOW_VENDOR; else if (0 == strcmp(tmp, "model")) filter = HW_CPU_SHOW_MODEL; else if (0 == strcmp(tmp, "curfreq")) filter = HW_CPU_SHOW_CURFREQ; else return ret; if (NULL == (f = fopen(HW_CPU_INFO_FILE, "r"))) return ret; *buffer = '\0'; while (NULL != fgets(line, sizeof(line), f)) { if (2 != sscanf(line, "%[^:]: %[^\n]", name, tmp)) continue; if (0 == strncmp(name, "processor", 9)) { if (-1 != cur_cpu && (HW_CPU_ALL_CPUS == cpu || cpu == cur_cpu)) /* print info about the previous cpu */ offset += print_freq(buffer + offset, sizeof(buffer) - offset, filter, cpu, maxfreq, curfreq); curfreq = FAIL; cur_cpu = atoi(tmp); if (HW_CPU_ALL_CPUS != cpu && cpu != cur_cpu) continue; if (HW_CPU_ALL_CPUS == cpu || HW_CPU_SHOW_ALL == filter) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\nprocessor %d:", cur_cpu); if ((HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_MAXFREQ == filter) && FAIL != (maxfreq = get_cpu_max_freq(cur_cpu))) { ret = SYSINFO_RET_OK; } } if (HW_CPU_ALL_CPUS != cpu && cpu != cur_cpu) continue; if (0 == strncmp(name, "vendor_id", 9) && (HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_VENDOR == filter)) { ret = SYSINFO_RET_OK; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", tmp); } else if (0 == strncmp(name, "model name", 10) && (HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_MODEL == filter)) { ret = SYSINFO_RET_OK; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", tmp); } else if (0 == strncmp(name, "cpu MHz", 7) && (HW_CPU_SHOW_ALL == filter || HW_CPU_SHOW_CURFREQ == filter)) { ret = SYSINFO_RET_OK; ZBX_STR2UINT64(curfreq, tmp); } } zbx_fclose(f); if (SYSINFO_RET_OK == ret) { if (-1 != cur_cpu && (HW_CPU_ALL_CPUS == cpu || cpu == cur_cpu)) /* print info about the last cpu */ offset += print_freq(buffer + offset, sizeof(buffer) - offset, filter, cpu, maxfreq, curfreq); SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer + 1)); /* buf has a leading space or '\n' */ } return ret; }
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; }
static int dns_query(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result, int short_answer) { #if defined(HAVE_RES_QUERY) || defined(_WINDOWS) size_t offset = 0; int res, type, retrans, retry, i, ret = SYSINFO_RET_FAIL; char ip[MAX_STRING_LEN], zone[MAX_STRING_LEN], tmp[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; struct in_addr inaddr; #ifndef _WINDOWS int saved_nscount, saved_retrans, saved_retry; struct sockaddr_in saved_ns; #endif typedef struct { char *name; int type; } resolv_querytype_t; static const resolv_querytype_t qt[] = { {"ANY", T_ANY}, {"A", T_A}, {"NS", T_NS}, {"MD", T_MD}, {"MF", T_MF}, {"CNAME", T_CNAME}, {"SOA", T_SOA}, {"MB", T_MB}, {"MG", T_MG}, {"MR", T_MR}, {"NULL", T_NULL}, #ifndef _WINDOWS {"WKS", T_WKS}, #endif {"PTR", T_PTR}, {"HINFO", T_HINFO}, {"MINFO", T_MINFO}, {"MX", T_MX}, {"TXT", T_TXT}, {"SRV", T_SRV}, {NULL} }; #ifdef _WINDOWS PDNS_RECORD pQueryResults, pDnsRecord; LPTSTR wzone; char tmp2[MAX_STRING_LEN]; #else char *name; unsigned char *msg_end, *msg_ptr, *p; int num_answers, num_query, q_type, q_class, q_len, value, c, n; struct servent *s; HEADER *hp; struct protoent *pr; #if PACKETSZ > 1024 unsigned char buf[PACKETSZ]; #else unsigned char buf[1024]; #endif typedef union { HEADER h; #if defined(NS_PACKETSZ) unsigned char buffer[NS_PACKETSZ]; #elif defined(PACKETSZ) unsigned char buffer[PACKETSZ]; #else unsigned char buffer[512]; #endif } answer_t; answer_t answer; #endif /* _WINDOWS */ *buffer = '\0'; if (5 < num_param(param)) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, ip, sizeof(ip))) *ip = '\0'; if (0 != get_param(param, 2, zone, sizeof(zone)) || '\0' == *zone) strscpy(zone, "zabbix.com"); if (0 != get_param(param, 3, tmp, sizeof(tmp)) || '\0' == *tmp) type = T_SOA; else { for (i = 0; NULL != qt[i].name; i++) { #ifdef _WINDOWS if (0 == lstrcmpiA(qt[i].name, tmp)) #else if (0 == strcasecmp(qt[i].name, tmp)) #endif { type = qt[i].type; break; } } if (NULL == qt[i].name) return SYSINFO_RET_FAIL; } if (0 != get_param(param, 4, tmp, sizeof(tmp)) || '\0' == *tmp) retrans = 1; else retrans = atoi(tmp); if (0 != get_param(param, 5, tmp, sizeof(tmp)) || '\0' == *tmp) retry = 2; else retry = atoi(tmp); #ifdef _WINDOWS wzone = zbx_utf8_to_unicode(zone); res = DnsQuery(wzone, type, DNS_QUERY_STANDARD, NULL, &pQueryResults, NULL); zbx_free(wzone); if (1 == short_answer) { SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1); ret = SYSINFO_RET_OK; goto clean; } if (DNS_RCODE_NOERROR != res) return SYSINFO_RET_FAIL; pDnsRecord = pQueryResults; while (NULL != pDnsRecord) { if (DnsSectionAnswer != pDnsRecord->Flags.S.Section) { pDnsRecord = pDnsRecord->pNext; continue; } if (NULL == pDnsRecord->pName) goto clean; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp))); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(pDnsRecord->wType)); switch (pDnsRecord->wType) { case T_A: inaddr.s_addr = pDnsRecord->Data.A.IpAddress; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; case T_NS: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp))); break; case T_MD: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp))); break; case T_MF: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp))); break; case T_CNAME: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp))); break; case T_SOA: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu", zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)), pDnsRecord->Data.SOA.dwSerialNo, pDnsRecord->Data.SOA.dwRefresh, pDnsRecord->Data.SOA.dwRetry, pDnsRecord->Data.SOA.dwExpire, pDnsRecord->Data.SOA.dwDefaultTtl); break; case T_MB: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp))); break; case T_MG: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp))); break; case T_MR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp))); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu", pDnsRecord->Data.Null.dwByteCount); break; case T_PTR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp))); break; case T_HINFO: for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"", zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp))); break; case T_MINFO: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2))); break; case T_MX: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s", pDnsRecord->Data.MX.wPreference, zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp))); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ", zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp))); if (0 < i) offset -= 1; /* remove the trailing space */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s", pDnsRecord->Data.SRV.wPriority, pDnsRecord->Data.SRV.wWeight, pDnsRecord->Data.SRV.wPort, zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp))); break; default: break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); pDnsRecord = pDnsRecord->pNext; } #else /* not _WINDOWS */ if (-1 == res_init()) /* initialize always, settings might have changed */ return SYSINFO_RET_FAIL; if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) return SYSINFO_RET_FAIL; if ('\0' != *ip) { if (0 == inet_aton(ip, &inaddr)) return SYSINFO_RET_FAIL; memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; _res.nsaddr_list[0].sin_addr = inaddr; _res.nsaddr_list[0].sin_family = AF_INET; _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); _res.nscount = 1; } saved_retrans = _res.retrans; saved_retry = _res.retry; _res.retrans = retrans; _res.retry = retry; res = res_send(buf, res, answer.buffer, sizeof(answer.buffer)); _res.retrans = saved_retrans; _res.retry = saved_retry; if ('\0' != *ip) { memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in)); _res.nscount = saved_nscount; } hp = (HEADER *)answer.buffer; if (1 == short_answer) { SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1); return SYSINFO_RET_OK; } if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res) return SYSINFO_RET_FAIL; msg_end = answer.buffer + res; num_answers = ntohs(answer.h.ancount); num_query = ntohs(answer.h.qdcount); msg_ptr = answer.buffer + HFIXEDSZ; /* skipping query records */ for (; 0 < num_query && msg_ptr < msg_end; num_query--) msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ; for (; 0 < num_answers && msg_ptr < msg_end; num_answers--) { if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name); GETSHORT(q_type, msg_ptr); GETSHORT(q_class, msg_ptr); msg_ptr += INT32SZ; /* skipping TTL */ GETSHORT(q_len, msg_ptr); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type)); switch (q_type) { case T_A: switch (q_class) { case C_IN: case C_HS: memcpy(&inaddr, msg_ptr, INADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; default: ; } msg_ptr += q_len; break; case T_NS: case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_PTR: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_MX: GETSHORT(value, msg_ptr); /* preference */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* exchange */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_SOA: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* source host */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* administrator */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); GETLONG(value, msg_ptr); /* serial number */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* refresh time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* retry time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* expire time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* minimum TTL */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len); msg_ptr += q_len; break; case T_WKS: if (INT32SZ + 1 > q_len) return SYSINFO_RET_FAIL; p = msg_ptr + q_len; memcpy(&inaddr, msg_ptr, INADDRSZ); msg_ptr += INT32SZ; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); if (NULL != (pr = getprotobynumber(*msg_ptr))) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr); msg_ptr++; n = 0; while (msg_ptr < p) { c = *msg_ptr++; do { if (0 != (c & 0200)) { s = getservbyport((int)htons(n), pr ? pr->p_name : NULL); if (NULL != s) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n); } c <<= 1; } while (0 != (++n & 07)); } break; case T_HINFO: p = msg_ptr + q_len; c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } if (msg_ptr < p) { c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } } break; case T_MINFO: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox responsible for mailing lists */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox for error messages */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); p = msg_ptr + q_len; while (msg_ptr < p) { for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++); } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: GETSHORT(value, msg_ptr); /* priority */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* weight */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* port */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* target */ return SYSINFO_RET_FAIL; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; default: msg_ptr += q_len; break; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); } #endif /* _WINDOWS */ if (0 != offset) buffer[--offset] = '\0'; SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); ret = SYSINFO_RET_OK; #ifdef _WINDOWS clean: if (DNS_RCODE_NOERROR == res) DnsRecordListFree(pQueryResults, DnsFreeRecordList); #endif return ret; #else /* both HAVE_RES_QUERY and _WINDOWS not defined */ return SYSINFO_RET_FAIL; #endif /* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */ }
int NET_IF_LIST(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { DWORD dwSize, dwRetVal, i, j; char *buf = NULL; size_t buf_alloc = 512, buf_offset = 0; int ret = SYSINFO_RET_FAIL; /* variables used for GetIfTable and GetIfEntry */ MIB_IFTABLE *pIfTable = NULL; MIB_IFROW pIfRow; /* variables used for GetIpAddrTable */ MIB_IPADDRTABLE *pIPAddrTable = NULL; IN_ADDR in_addr; /* Allocate memory for our pointers. */ dwSize = sizeof(MIB_IPADDRTABLE); pIPAddrTable = (MIB_IPADDRTABLE *)zbx_malloc(pIPAddrTable, sizeof(MIB_IPADDRTABLE)); /* Make an initial call to GetIpAddrTable to get the necessary size into the dwSize variable */ if (ERROR_INSUFFICIENT_BUFFER == GetIpAddrTable(pIPAddrTable, &dwSize, 0)) pIPAddrTable = (MIB_IPADDRTABLE *)zbx_realloc(pIPAddrTable, dwSize); /* Make a second call to GetIpAddrTable to get the actual data we want */ if (NO_ERROR != (dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0))) { zabbix_log(LOG_LEVEL_DEBUG, "GetIpAddrTable failed with error: %s", strerror_from_system(dwRetVal)); goto clean; } /* Allocate memory for our pointers. */ dwSize = sizeof(MIB_IFTABLE); pIfTable = (MIB_IFTABLE *)zbx_malloc(pIfTable, dwSize); /* Before calling GetIfEntry, we call GetIfTable to make sure there are entries to get and retrieve the interface index. Make an initial call to GetIfTable to get the necessary size into dwSize */ if (ERROR_INSUFFICIENT_BUFFER == GetIfTable(pIfTable, &dwSize, 0)) pIfTable = (MIB_IFTABLE *)zbx_realloc(pIfTable, dwSize); /* Make a second call to GetIfTable to get the actual data we want. */ if (NO_ERROR != (dwRetVal = GetIfTable(pIfTable, &dwSize, 0))) { zabbix_log(LOG_LEVEL_DEBUG, "GetIfTable failed with error: %s", strerror_from_system(dwRetVal)); goto clean; } buf = (char *)zbx_malloc(buf, sizeof(char) * buf_alloc); if (pIfTable->dwNumEntries > 0) { for (i = 0; i < (int)pIfTable->dwNumEntries; i++) { LPTSTR wdescr; LPSTR utf8_descr; pIfRow.dwIndex = pIfTable->table[i].dwIndex; if (NO_ERROR != (dwRetVal = GetIfEntry(&pIfRow))) { zabbix_log(LOG_LEVEL_DEBUG, "GetIfEntry failed with error: %s", strerror_from_system(dwRetVal)); continue; } zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset, "%-25s", get_if_type_string(pIfRow.dwType)); zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset, " %-8s", get_if_adminstatus_string(pIfRow.dwAdminStatus)); for (j = 0; j < pIPAddrTable->dwNumEntries; j++) if (pIPAddrTable->table[j].dwIndex == pIfRow.dwIndex) { in_addr.S_un.S_addr = pIPAddrTable->table[j].dwAddr; zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset, " %-15s", inet_ntoa(in_addr)); break; } if (j == pIPAddrTable->dwNumEntries) zbx_strcpy_alloc(&buf, &buf_alloc, &buf_offset, " -"); wdescr = zbx_acp_to_unicode(pIfRow.bDescr); utf8_descr = zbx_unicode_to_utf8(wdescr); zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset, " %s\n", utf8_descr); zbx_free(utf8_descr); zbx_free(wdescr); } } SET_TEXT_RESULT(result, buf); ret = SYSINFO_RET_OK; clean: zbx_free(pIfTable); zbx_free(pIPAddrTable); return ret; }
static int dns_query(AGENT_REQUEST *request, AGENT_RESULT *result, int short_answer) { #if defined(HAVE_RES_QUERY) || defined(_WINDOWS) size_t offset = 0; int res, type, retrans, retry, use_tcp, i, ret = SYSINFO_RET_FAIL, ip_type = AF_INET; char *ip, zone[MAX_STRING_LEN], buffer[MAX_STRING_LEN], *zone_str, *param, tmp[MAX_STRING_LEN]; struct in_addr inaddr; struct in6_addr in6addr; #ifndef _WINDOWS #if defined(HAVE_RES_NINIT) && !defined(_AIX) /* It seems that on some AIX systems with no updates installed res_ninit() can */ /* corrupt stack (see ZBX-14559). Use res_init() on AIX. */ struct __res_state res_state_local; #else /* thread-unsafe resolver API */ int saved_retrans, saved_retry, saved_nscount = 0; unsigned long saved_options; struct sockaddr_in saved_ns; # if defined(HAVE_RES_U_EXT) /* thread-unsafe resolver API /Linux/ */ int save_nssocks, saved_nscount6; # endif #endif #if defined(HAVE_RES_EXT_EXT) /* AIX */ union res_sockaddr_union saved_ns6; #elif defined(HAVE_RES_U_EXT_EXT) /* BSD */ struct sockaddr_in6 saved_ns6; #else struct sockaddr_in6 *saved_ns6; #endif struct sockaddr_in6 sockaddrin6; struct addrinfo hint, *hres = NULL; #endif typedef struct { const char *name; int type; } resolv_querytype_t; static const resolv_querytype_t qt[] = { {"ANY", T_ANY}, {"A", T_A}, {"AAAA", T_AAAA}, {"NS", T_NS}, {"MD", T_MD}, {"MF", T_MF}, {"CNAME", T_CNAME}, {"SOA", T_SOA}, {"MB", T_MB}, {"MG", T_MG}, {"MR", T_MR}, {"NULL", T_NULL}, #ifndef _WINDOWS {"WKS", T_WKS}, #endif {"PTR", T_PTR}, {"HINFO", T_HINFO}, {"MINFO", T_MINFO}, {"MX", T_MX}, {"TXT", T_TXT}, {"SRV", T_SRV}, {NULL} }; #ifdef _WINDOWS PDNS_RECORD pQueryResults, pDnsRecord; wchar_t *wzone; char tmp2[MAX_STRING_LEN]; DWORD options; #else char *name; unsigned char *msg_end, *msg_ptr, *p; int num_answers, num_query, q_type, q_class, q_len, value, c, n; struct servent *s; HEADER *hp; struct protoent *pr; #if PACKETSZ > 1024 unsigned char buf[PACKETSZ]; #else unsigned char buf[1024]; #endif typedef union { HEADER h; #if defined(NS_PACKETSZ) unsigned char buffer[NS_PACKETSZ]; #elif defined(PACKETSZ) unsigned char buffer[PACKETSZ]; #else unsigned char buffer[512]; #endif } answer_t; answer_t answer; #endif /* _WINDOWS */ zbx_vector_str_t answers; *buffer = '\0'; if (6 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } ip = get_rparam(request, 0); zone_str = get_rparam(request, 1); #ifndef _WINDOWS memset(&hint, '\0', sizeof(hint)); hint.ai_family = PF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; if (NULL != ip && '\0' != *ip && 0 == getaddrinfo(ip, NULL, &hint, &hres) && AF_INET6 == hres->ai_family) ip_type = hres->ai_family; if (NULL != hres) freeaddrinfo(hres); #endif if (NULL == zone_str || '\0' == *zone_str) strscpy(zone, "zabbix.com"); else strscpy(zone, zone_str); param = get_rparam(request, 2); if (NULL == param || '\0' == *param) type = T_SOA; else { for (i = 0; NULL != qt[i].name; i++) { if (0 == strcasecmp(qt[i].name, param)) { type = qt[i].type; break; } } if (NULL == qt[i].name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } } param = get_rparam(request, 3); if (NULL == param || '\0' == *param) retrans = 1; else if (SUCCEED != is_uint31(param, &retrans) || 0 == retrans) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter.")); return SYSINFO_RET_FAIL; } param = get_rparam(request, 4); if (NULL == param || '\0' == *param) retry = 2; else if (SUCCEED != is_uint31(param, &retry) || 0 == retry) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter.")); return SYSINFO_RET_FAIL; } param = get_rparam(request, 5); if (NULL == param || '\0' == *param || 0 == strcmp(param, "udp")) use_tcp = 0; else if (0 == strcmp(param, "tcp")) use_tcp = 1; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid sixth parameter.")); return SYSINFO_RET_FAIL; } #ifdef _WINDOWS options = DNS_QUERY_STANDARD | DNS_QUERY_BYPASS_CACHE; if (0 != use_tcp) options |= DNS_QUERY_USE_TCP_ONLY; wzone = zbx_utf8_to_unicode(zone); res = DnsQuery(wzone, type, options, NULL, &pQueryResults, NULL); zbx_free(wzone); if (1 == short_answer) { SET_UI64_RESULT(result, DNS_RCODE_NOERROR != res ? 0 : 1); ret = SYSINFO_RET_OK; goto clean_dns; } if (DNS_RCODE_NOERROR != res) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot perform DNS query: [%d]", res)); return SYSINFO_RET_FAIL; } pDnsRecord = pQueryResults; zbx_vector_str_create(&answers); while (NULL != pDnsRecord) { if (DnsSectionAnswer != pDnsRecord->Flags.S.Section) { pDnsRecord = pDnsRecord->pNext; continue; } if (NULL == pDnsRecord->pName) goto clean; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", zbx_unicode_to_utf8_static(pDnsRecord->pName, tmp, sizeof(tmp))); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(pDnsRecord->wType)); switch (pDnsRecord->wType) { case T_A: inaddr.s_addr = pDnsRecord->Data.A.IpAddress; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; case T_AAAA: memcpy(&in6addr.s6_addr, &(pDnsRecord->Data.AAAA.Ip6Address), sizeof(in6addr.s6_addr)); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_inet_ntop(AF_INET6, &in6addr, tmp, sizeof(tmp))); break; case T_NS: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.NS.pNameHost, tmp, sizeof(tmp))); break; case T_MD: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MD.pNameHost, tmp, sizeof(tmp))); break; case T_MF: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MF.pNameHost, tmp, sizeof(tmp))); break; case T_CNAME: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.CNAME.pNameHost, tmp, sizeof(tmp))); break; case T_SOA: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s %lu %lu %lu %lu %lu", zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNamePrimaryServer, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.SOA.pNameAdministrator, tmp2, sizeof(tmp2)), pDnsRecord->Data.SOA.dwSerialNo, pDnsRecord->Data.SOA.dwRefresh, pDnsRecord->Data.SOA.dwRetry, pDnsRecord->Data.SOA.dwExpire, pDnsRecord->Data.SOA.dwDefaultTtl); break; case T_MB: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MB.pNameHost, tmp, sizeof(tmp))); break; case T_MG: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MG.pNameHost, tmp, sizeof(tmp))); break; case T_MR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MR.pNameHost, tmp, sizeof(tmp))); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%lu", pDnsRecord->Data.Null.dwByteCount); break; case T_PTR: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.PTR.pNameHost, tmp, sizeof(tmp))); break; case T_HINFO: for (i = 0; i < (int)(pDnsRecord->Data.HINFO.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%s\"", zbx_unicode_to_utf8_static(pDnsRecord->Data.HINFO.pStringArray[i], tmp, sizeof(tmp))); break; case T_MINFO: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s %s", zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameMailbox, tmp, sizeof(tmp)), zbx_unicode_to_utf8_static(pDnsRecord->Data.MINFO.pNameErrorsMailbox, tmp2, sizeof(tmp2))); break; case T_MX: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %s", pDnsRecord->Data.MX.wPreference, zbx_unicode_to_utf8_static(pDnsRecord->Data.MX.pNameExchange, tmp, sizeof(tmp))); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); for (i = 0; i < (int)(pDnsRecord->Data.TXT.dwStringCount); i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s ", zbx_unicode_to_utf8_static(pDnsRecord->Data.TXT.pStringArray[i], tmp, sizeof(tmp))); if (0 < i) offset -= 1; /* remove the trailing space */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %hu %hu %hu %s", pDnsRecord->Data.SRV.wPriority, pDnsRecord->Data.SRV.wWeight, pDnsRecord->Data.SRV.wPort, zbx_unicode_to_utf8_static(pDnsRecord->Data.SRV.pNameTarget, tmp, sizeof(tmp))); break; default: break; } zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); pDnsRecord = pDnsRecord->pNext; zbx_vector_str_append(&answers, zbx_strdup(NULL, buffer)); offset = 0; *buffer = '\0'; } #else /* not _WINDOWS */ #if defined(HAVE_RES_NINIT) && !defined(_AIX) memset(&res_state_local, 0, sizeof(res_state_local)); if (-1 == res_ninit(&res_state_local)) /* initialize always, settings might have changed */ #else if (-1 == res_init()) /* initialize always, settings might have changed */ #endif { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot initialize DNS subsystem: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } #if defined(HAVE_RES_NINIT) && !defined(_AIX) if (-1 == (res = res_nmkquery(&res_state_local, QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) #else if (-1 == (res = res_mkquery(QUERY, zone, C_IN, type, NULL, 0, NULL, buf, sizeof(buf)))) #endif { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot create DNS query: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } if (NULL != ip && '\0' != *ip && AF_INET == ip_type) { if (0 == inet_aton(ip, &inaddr)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid IP address.")); return SYSINFO_RET_FAIL; } #if defined(HAVE_RES_NINIT) && !defined(_AIX) res_state_local.nsaddr_list[0].sin_addr = inaddr; res_state_local.nsaddr_list[0].sin_family = AF_INET; res_state_local.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); res_state_local.nscount = 1; #else /* thread-unsafe resolver API */ memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; _res.nsaddr_list[0].sin_addr = inaddr; _res.nsaddr_list[0].sin_family = AF_INET; _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); _res.nscount = 1; #endif } else if (NULL != ip && '\0' != *ip && AF_INET6 == ip_type) { if (0 == inet_pton(ip_type, ip, &in6addr)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid IPv6 address.")); return SYSINFO_RET_FAIL; } memset(&sockaddrin6, '\0', sizeof(sockaddrin6)); #if defined(HAVE_RES_SIN6_LEN) sockaddrin6.sin6_len = sizeof(sockaddrin6); #endif sockaddrin6.sin6_family = AF_INET6; sockaddrin6.sin6_addr = in6addr; sockaddrin6.sin6_port = htons(ZBX_DEFAULT_DNS_PORT); #if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT)) memset(&res_state_local.nsaddr_list[0], '\0', sizeof(res_state_local.nsaddr_list[0])); # ifdef HAVE_RES_U_EXT /* Linux */ saved_ns6 = res_state_local._u._ext.nsaddrs[0]; res_state_local._u._ext.nsaddrs[0] = &sockaddrin6; res_state_local._u._ext.nssocks[0] = -1; res_state_local._u._ext.nscount6 = 1; /* CentOS */ # elif HAVE_RES_U_EXT_EXT /* BSD */ if (NULL != res_state_local._u._ext.ext) memcpy(res_state_local._u._ext.ext, &sockaddrin6, sizeof(sockaddrin6)); res_state_local.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); # endif res_state_local.nscount = 1; #else memcpy(&saved_ns, &(_res.nsaddr_list[0]), sizeof(struct sockaddr_in)); saved_nscount = _res.nscount; # if defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT) || defined(HAVE_RES_EXT_EXT) memset(&_res.nsaddr_list[0], '\0', sizeof(_res.nsaddr_list[0])); _res.nscount = 1; # endif # if defined(HAVE_RES_U_EXT) /* thread-unsafe resolver API /Linux/ */ saved_nscount6 = _res._u._ext.nscount6; saved_ns6 = _res._u._ext.nsaddrs[0]; save_nssocks = _res._u._ext.nssocks[0]; _res._u._ext.nsaddrs[0] = &sockaddrin6; _res._u._ext.nssocks[0] = -1; _res._u._ext.nscount6 = 1; # elif defined(HAVE_RES_U_EXT_EXT) /* thread-unsafe resolver API /BSD/ */ memcpy(&saved_ns6, _res._u._ext.ext, sizeof(saved_ns6)); _res.nsaddr_list[0].sin_port = htons(ZBX_DEFAULT_DNS_PORT); if (NULL != _res._u._ext.ext) memcpy(_res._u._ext.ext, &sockaddrin6, sizeof(sockaddrin6)); # elif defined(HAVE_RES_EXT_EXT) /* thread-unsafe resolver API /AIX/ */ memcpy(&saved_ns6, &(_res._ext.ext.nsaddrs[0]), sizeof(saved_ns6)); memcpy(&_res._ext.ext.nsaddrs[0], &sockaddrin6, sizeof(sockaddrin6)); # endif /* #if defined(HAVE_RES_U_EXT) */ #endif /* #if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT)) */ } #if defined(HAVE_RES_NINIT) && !defined(_AIX) && (defined(HAVE_RES_U_EXT) || defined(HAVE_RES_U_EXT_EXT)) if (0 != use_tcp) res_state_local.options |= RES_USEVC; res_state_local.retrans = retrans; res_state_local.retry = retry; res = res_nsend(&res_state_local, buf, res, answer.buffer, sizeof(answer.buffer)); # ifdef HAVE_RES_U_EXT /* Linux */ if (NULL != ip && '\0' != *ip && AF_INET6 == ip_type) res_state_local._u._ext.nsaddrs[0] = saved_ns6; # endif # ifdef HAVE_RES_NDESTROY res_ndestroy(&res_state_local); # else res_nclose(&res_state_local); # endif #else /* thread-unsafe resolver API */ saved_options = _res.options; saved_retrans = _res.retrans; saved_retry = _res.retry; if (0 != use_tcp) _res.options |= RES_USEVC; _res.retrans = retrans; _res.retry = retry; res = res_send(buf, res, answer.buffer, sizeof(answer.buffer)); _res.options = saved_options; _res.retrans = saved_retrans; _res.retry = saved_retry; if (NULL != ip && '\0' != *ip) { if (AF_INET6 == ip_type) { # if defined(HAVE_RES_U_EXT) /* Linux */ _res._u._ext.nsaddrs[0] = saved_ns6; _res._u._ext.nssocks[0] = save_nssocks; _res._u._ext.nscount6 = saved_nscount6; # elif defined(HAVE_RES_U_EXT_EXT) /* BSD */ if (NULL != _res._u._ext.ext) memcpy(_res._u._ext.ext, &saved_ns6, sizeof(saved_ns6)); # elif defined(HAVE_RES_EXT_EXT) /* AIX */ memcpy(&_res._ext.ext.nsaddrs[0], &saved_ns6, sizeof(saved_ns6)); # endif } memcpy(&(_res.nsaddr_list[0]), &saved_ns, sizeof(struct sockaddr_in)); _res.nscount = saved_nscount; } #endif hp = (HEADER *)answer.buffer; if (1 == short_answer) { SET_UI64_RESULT(result, NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res ? 0 : 1); return SYSINFO_RET_OK; } if (NOERROR != hp->rcode || 0 == ntohs(hp->ancount) || -1 == res) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot perform DNS query.")); return SYSINFO_RET_FAIL; } msg_end = answer.buffer + res; num_answers = ntohs(answer.h.ancount); num_query = ntohs(answer.h.qdcount); msg_ptr = answer.buffer + HFIXEDSZ; zbx_vector_str_create(&answers); /* skipping query records */ for (; 0 < num_query && msg_ptr < msg_end; num_query--) msg_ptr += dn_skipname(msg_ptr, msg_end) + QFIXEDSZ; for (; 0 < num_answers && msg_ptr < msg_end; num_answers--) { if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); ret = SYSINFO_RET_FAIL; goto clean; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%-20s", name); GETSHORT(q_type, msg_ptr); GETSHORT(q_class, msg_ptr); msg_ptr += INT32SZ; /* skipping TTL */ GETSHORT(q_len, msg_ptr); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %-8s", decode_type(q_type)); switch (q_type) { case T_A: switch (q_class) { case C_IN: case C_HS: memcpy(&inaddr, msg_ptr, INADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); break; default: ; } msg_ptr += q_len; break; case T_AAAA: switch (q_class) { case C_IN: case C_HS: memcpy(&in6addr, msg_ptr, IN6ADDRSZ); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntop(AF_INET6, &in6addr, tmp, sizeof(tmp))); break; default: ; } msg_ptr += q_len; break; case T_NS: case T_CNAME: case T_MB: case T_MD: case T_MF: case T_MG: case T_MR: case T_PTR: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_MX: GETSHORT(value, msg_ptr); /* preference */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* exchange */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_SOA: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* source host */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* administrator */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); GETLONG(value, msg_ptr); /* serial number */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* refresh time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* retry time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* expire time */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETLONG(value, msg_ptr); /* minimum TTL */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); break; case T_NULL: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " len:%d", q_len); msg_ptr += q_len; break; case T_WKS: if (INT32SZ + 1 > q_len) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } p = msg_ptr + q_len; memcpy(&inaddr, msg_ptr, INADDRSZ); msg_ptr += INT32SZ; offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", inet_ntoa(inaddr)); if (NULL != (pr = getprotobynumber(*msg_ptr))) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", pr->p_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", (int)*msg_ptr); msg_ptr++; n = 0; while (msg_ptr < p) { c = *msg_ptr++; do { if (0 != (c & 0200)) { s = getservbyport((int)htons(n), pr ? pr->p_name : NULL); if (NULL != s) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", s->s_name); else offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " #%d", n); } c <<= 1; } while (0 != (++n & 07)); } break; case T_HINFO: p = msg_ptr + q_len; c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } if (msg_ptr < p) { c = *msg_ptr++; if (0 != c) { offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \"%.*s\"", c, msg_ptr); msg_ptr += c; } } break; case T_MINFO: if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox responsible for mailing lists */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* mailbox for error messages */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; case T_TXT: offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " \""); p = msg_ptr + q_len; while (msg_ptr < p) { for (c = *msg_ptr++; 0 < c && msg_ptr < p; c--) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%c", *msg_ptr++); } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\""); break; case T_SRV: GETSHORT(value, msg_ptr); /* priority */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* weight */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); GETSHORT(value, msg_ptr); /* port */ offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %d", value); if (NULL == (name = get_name(answer.buffer, msg_end, &msg_ptr))) /* target */ { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot decode DNS response.")); return SYSINFO_RET_FAIL; } offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, " %s", name); break; default: msg_ptr += q_len; break; } zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); zbx_vector_str_append(&answers, zbx_strdup(NULL, buffer)); offset = 0; *buffer = '\0'; } #endif /* _WINDOWS */ zbx_vector_str_sort(&answers, ZBX_DEFAULT_STR_COMPARE_FUNC); for (i = 0; i < answers.values_num; i++) offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "%s", answers.values[i]); if (0 != offset) buffer[--offset] = '\0'; SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); ret = SYSINFO_RET_OK; clean: zbx_vector_str_clear_ext(&answers, zbx_str_free); zbx_vector_str_destroy(&answers); #ifdef _WINDOWS clean_dns: if (DNS_RCODE_NOERROR == res) DnsRecordListFree(pQueryResults, DnsFreeRecordList); #endif return ret; #else /* both HAVE_RES_QUERY and _WINDOWS not defined */ return SYSINFO_RET_FAIL; #endif /* defined(HAVE_RES_QUERY) || defined(_WINDOWS) */ }
int set_result_type(AGENT_RESULT *result, int value_type, int data_type, char *c) { int ret = FAIL; zbx_uint64_t value_uint64; double value_double; assert(result); switch (value_type) { case ITEM_VALUE_TYPE_UINT64: zbx_rtrim(c, " \""); zbx_ltrim(c, " \"+"); del_zeroes(c); switch (data_type) { case ITEM_DATA_TYPE_BOOLEAN: if (SUCCEED == is_boolean(c, &value_uint64)) { SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; case ITEM_DATA_TYPE_OCTAL: if (SUCCEED == is_uoct(c)) { ZBX_OCT2UINT64(value_uint64, c); SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; case ITEM_DATA_TYPE_DECIMAL: if (SUCCEED == is_uint64(c, &value_uint64)) { SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; case ITEM_DATA_TYPE_HEXADECIMAL: if (SUCCEED == is_uhex(c)) { ZBX_HEX2UINT64(value_uint64, c); SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } else if (SUCCEED == is_hex_string(c)) { zbx_remove_whitespace(c); ZBX_HEX2UINT64(value_uint64, c); SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; default: THIS_SHOULD_NEVER_HAPPEN; break; } break; case ITEM_VALUE_TYPE_FLOAT: zbx_rtrim(c, " \""); zbx_ltrim(c, " \"+"); if (SUCCEED != is_double(c)) break; value_double = atof(c); SET_DBL_RESULT(result, value_double); ret = SUCCEED; break; case ITEM_VALUE_TYPE_STR: zbx_replace_invalid_utf8(c); SET_STR_RESULT(result, zbx_strdup(NULL, c)); ret = SUCCEED; break; case ITEM_VALUE_TYPE_TEXT: zbx_replace_invalid_utf8(c); SET_TEXT_RESULT(result, zbx_strdup(NULL, c)); ret = SUCCEED; break; case ITEM_VALUE_TYPE_LOG: zbx_replace_invalid_utf8(c); add_log_result(result, c); ret = SUCCEED; break; } if (SUCCEED != ret) { char *error = NULL; zbx_remove_chars(c, "\r\n"); zbx_replace_invalid_utf8(c); if (ITEM_VALUE_TYPE_UINT64 == value_type) error = zbx_dsprintf(error, "Received value [%s] is not suitable for value type [%s] and data type [%s]", c, zbx_item_value_type_string(value_type), zbx_item_data_type_string(data_type)); else error = zbx_dsprintf(error, "Received value [%s] is not suitable for value type [%s]", c, zbx_item_value_type_string(value_type)); SET_MSG_RESULT(result, error); } return ret; }
int SYSTEM_SW_PACKAGES(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { size_t offset = 0; int ret = SYSINFO_RET_FAIL, show_pm, i, j; char buffer[MAX_BUFFER_LEN], regex[MAX_STRING_LEN], manager[MAX_STRING_LEN], tmp[MAX_STRING_LEN], *buf = NULL, *package; zbx_vector_str_t packages; ZBX_PACKAGE_MANAGER *mng; if (3 < num_param(param)) return ret; if (0 != get_param(param, 1, regex, sizeof(regex)) || 0 == strcmp(regex, "all")) *regex = '\0'; if (0 != get_param(param, 2, manager, sizeof(manager)) || 0 == strcmp(manager, "all")) *manager = '\0'; if (0 != get_param(param, 3, tmp, sizeof(tmp)) || '\0' == *tmp || 0 == strcmp(tmp, "full")) show_pm = 1; /* show package managers' names */ else if (0 == strcmp(tmp, "short")) show_pm = 0; else return ret; *buffer = '\0'; zbx_vector_str_create(&packages); for (i = 0; NULL != package_managers[i].name; i++) { mng = &package_managers[i]; if ('\0' != *manager && 0 != strcmp(manager, mng->name)) continue; if (SUCCEED == zbx_execute(mng->test_cmd, &buf, tmp, sizeof(tmp), CONFIG_TIMEOUT) && '\0' != *buf) /* consider PMS present, if test_cmd outputs anything to stdout */ { if (SUCCEED != zbx_execute(mng->list_cmd, &buf, tmp, sizeof(tmp), CONFIG_TIMEOUT)) continue; ret = SYSINFO_RET_OK; package = strtok(buf, "\n"); while (NULL != package) { if (NULL != mng->parser) /* check if the package name needs to be parsed */ { if (SUCCEED == mng->parser(package, tmp, sizeof(tmp))) package = tmp; else goto next; } if ('\0' != *regex && NULL == zbx_regexp_match(package, regex, NULL)) goto next; zbx_vector_str_append(&packages, zbx_strdup(NULL, package)); next: package = strtok(NULL, "\n"); } if (1 == show_pm) { offset += print_packages(buffer + offset, sizeof(buffer) - offset, &packages, mng->name); offset += zbx_snprintf(buffer + offset, sizeof(buffer) - offset, "\n"); /* deallocate memory used for string vector elements */ for (j = 0; j < packages.values_num; j++) zbx_free(packages.values[j]); packages.values_num = 0; } } } zbx_free(buf); if (0 == show_pm) { offset += print_packages(buffer + offset, sizeof(buffer) - offset, &packages, NULL); /* deallocate memory used for string vector elements */ for (j = 0; j < packages.values_num; j++) zbx_free(packages.values[j]); packages.values_num = 0; } else if (0 != offset) buffer[--offset] = '\0'; zbx_vector_str_destroy(&packages); if (SYSINFO_RET_OK == ret) SET_TEXT_RESULT(result, zbx_strdup(NULL, buffer)); return ret; }
int EXECUTE_STR(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(_WINDOWS) STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; SECURITY_ATTRIBUTES sa; HANDLE hWrite=NULL, hRead=NULL; #else /* not _WINDOWS */ FILE *hRead = NULL; #endif /* _WINDOWS */ int ret = SYSINFO_RET_FAIL; char stat_buf[128]; char *cmd_result=NULL; char *command=NULL; int len; assert(result); init_result(result); cmd_result = zbx_dsprintf(cmd_result,""); memset(stat_buf, 0, sizeof(stat_buf)); #if defined(_WINDOWS) /* Set the bInheritHandle flag so pipe handles are inherited */ sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; /* Create a pipe for the child process's STDOUT */ if (! CreatePipe(&hRead, &hWrite, &sa, sizeof(cmd_result))) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to create pipe [%s]", strerror_from_system(GetLastError())); ret = SYSINFO_RET_FAIL; goto lbl_exit; } /* Fill in process startup info structure */ memset(&si,0,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput = hWrite; si.hStdError = hWrite; command = zbx_dsprintf(command, "cmd /C \"%s\"", param); /* Create new process */ if (!CreateProcess(NULL,command,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to create process: '%s' [%s]", command, strerror_from_system(GetLastError())); ret = SYSINFO_RET_FAIL; goto lbl_exit; } CloseHandle(hWrite); hWrite = NULL; /* Read process output */ while( ReadFile(hRead, stat_buf, sizeof(stat_buf)-1, &len, NULL) && len > 0 ) { cmd_result = zbx_strdcat(cmd_result, stat_buf); memset(stat_buf, 0, sizeof(stat_buf)); } /* Don't wait child process exiting. */ /* WaitForSingleObject( pi.hProcess, INFINITE ); */ /* Terminate child process */ /* TerminateProcess(pi.hProcess, 0); */ CloseHandle(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(hRead); hRead = NULL; #else /* not _WINDOWS */ command = zbx_dsprintf(command, "%s", param); if(0 == (hRead = popen(command,"r"))) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } ; /* Read process output */ while( (len = fread(stat_buf, 1, sizeof(stat_buf)-1, hRead)) > 0 ) { cmd_result = zbx_strdcat(cmd_result, stat_buf); memset(stat_buf, 0, sizeof(stat_buf)); } if(0 != ferror(hRead)) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } if(pclose(hRead) == -1) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } hRead = NULL; #endif /* _WINDOWS */ zabbix_log(LOG_LEVEL_DEBUG, "Before"); zbx_rtrim(cmd_result,"\n\r\0"); /* We got EOL only */ if(cmd_result[0] == '\0') { ret = SYSINFO_RET_FAIL; goto lbl_exit; } zabbix_log(LOG_LEVEL_DEBUG, "Run remote command [%s] Result [%d] [%.20s]...", command, strlen(cmd_result), cmd_result); SET_TEXT_RESULT(result, strdup(cmd_result)); ret = SYSINFO_RET_OK; lbl_exit: #if defined(_WINDOWS) if ( hWrite ) { CloseHandle(hWrite); hWrite = NULL; } if ( hRead) { CloseHandle(hRead); hRead = NULL; } #else /* not _WINDOWS */ if ( hRead ) { pclose(hRead); hRead = NULL; } #endif /* _WINDOWS */ zbx_free(command) zbx_free(cmd_result); return ret; }
int SERVICE_INFO(AGENT_REQUEST *request, AGENT_RESULT *result) { QUERY_SERVICE_CONFIG *qsc = NULL; SERVICE_DESCRIPTION *scd = NULL; SERVICE_STATUS status; SC_HANDLE h_mgr, h_srv; DWORD sz = 0; int param_type, i; char *name, *param; wchar_t *wname, service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; if (2 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } name = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL == name || '\0' == *name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == param || '\0' == *param || 0 == strcmp(param, "state")) /* default second parameter */ param_type = ZBX_SRV_PARAM_STATE; else if (0 == strcmp(param, "displayname")) param_type = ZBX_SRV_PARAM_DISPLAYNAME; else if (0 == strcmp(param, "path")) param_type = ZBX_SRV_PARAM_PATH; else if (0 == strcmp(param, "user")) param_type = ZBX_SRV_PARAM_USER; else if (0 == strcmp(param, "startup")) param_type = ZBX_SRV_PARAM_STARTUP; else if (0 == strcmp(param, "description")) param_type = ZBX_SRV_PARAM_DESCRIPTION; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information.")); return SYSINFO_RET_FAIL; } wname = zbx_utf8_to_unicode(name); h_srv = OpenService(h_mgr, wname, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); if (NULL == h_srv && 0 != GetServiceKeyName(h_mgr, wname, service_name, &max_len_name)) h_srv = OpenService(h_mgr, service_name, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); zbx_free(wname); if (NULL == h_srv) { int ret; if (ZBX_SRV_PARAM_STATE == param_type) { SET_UI64_RESULT(result, 255); ret = SYSINFO_RET_OK; } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot find the specified service.")); ret = SYSINFO_RET_FAIL; } CloseServiceHandle(h_mgr); return ret; } if (ZBX_SRV_PARAM_STATE == param_type) { if (0 != QueryServiceStatus(h_srv, &status)) { for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++) ; SET_UI64_RESULT(result, i); } else SET_UI64_RESULT(result, 7); } else if (ZBX_SRV_PARAM_DESCRIPTION == param_type) { QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } scd = (SERVICE_DESCRIPTION *)zbx_malloc(scd, sz); if (0 == QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)scd, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); zbx_free(scd); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } if (NULL == scd->lpDescription) SET_TEXT_RESULT(result, zbx_strdup(NULL, "")); else SET_TEXT_RESULT(result, zbx_unicode_to_utf8(scd->lpDescription)); zbx_free(scd); } else { QueryServiceConfig(h_srv, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc(qsc, sz); if (0 == QueryServiceConfig(h_srv, qsc, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); zbx_free(qsc); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } switch (param_type) { case ZBX_SRV_PARAM_DISPLAYNAME: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpDisplayName)); break; case ZBX_SRV_PARAM_PATH: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpBinaryPathName)); break; case ZBX_SRV_PARAM_USER: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpServiceStartName)); break; case ZBX_SRV_PARAM_STARTUP: if (SERVICE_AUTO_START == qsc->dwStartType) { if (SUCCEED == check_delayed_start(h_srv)) SET_UI64_RESULT(result, 1); else SET_UI64_RESULT(result, 0); } else { for (i = 2; i < ARRSIZE(start_types) && qsc->dwStartType != start_types[i]; i++) ; SET_UI64_RESULT(result, i); } break; } zbx_free(qsc); } CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_OK; }
extern "C" int WMI_GET(AGENT_REQUEST *request, AGENT_RESULT *result) { char *wmi_namespace, *wmi_query; VARIANT vtProp; HRESULT hres; int ret = SYSINFO_RET_FAIL; if (2 != request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); return SYSINFO_RET_FAIL; } wmi_namespace = get_rparam(request, 0); wmi_query = get_rparam(request, 1); VariantInit(&vtProp); if (SUCCEED != zbx_co_initialize()) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot initialize COM library.")); return SYSINFO_RET_FAIL; } if (SYSINFO_RET_FAIL == zbx_wmi_get_variant(wmi_namespace, wmi_query, &vtProp)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot get WMI result"); goto out; } if (0 != (vtProp.vt & VT_ARRAY)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot convert WMI array result"); goto out; } switch (vtProp.vt) { case VT_EMPTY: case VT_NULL: goto out; case VT_I8: case VT_I4: case VT_UI1: case VT_I2: case VT_I1: case VT_UI2: case VT_UI4: case VT_UI8: case VT_INT: case VT_UINT: hres = VariantChangeType(&vtProp, &vtProp, 0, VT_I8); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot convert WMI result of type %d to VT_I8", vtProp.vt); goto out; } SET_UI64_RESULT(result, vtProp.llVal); ret = SYSINFO_RET_OK; break; case VT_R4: case VT_R8: hres = VariantChangeType(&vtProp, &vtProp, 0, VT_R8); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot convert WMI result of type %d to VT_R8", vtProp.vt); goto out; } SET_DBL_RESULT(result, vtProp.dblVal); ret = SYSINFO_RET_OK; break; default: hres = VariantChangeType(&vtProp, &vtProp, VARIANT_ALPHABOOL, VT_BSTR); if (FAILED(hres)) { zabbix_log(LOG_LEVEL_DEBUG, "cannot convert WMI result of type %d to VT_BSTR", vtProp.vt); goto out; } SET_TEXT_RESULT(result, zbx_unicode_to_utf8((wchar_t *)_bstr_t(vtProp.bstrVal))); ret = SYSINFO_RET_OK; break; } out: VariantClear(&vtProp); if (SYSINFO_RET_FAIL == ret) SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain WMI information.")); return ret; }