static void open_sockets(char *cachefilename) { int cachefile; unsigned int buffer[3]; int bytesread = -1; unsigned int nr_sockets = 0; cachefile = open(cachefilename, O_RDONLY); if (cachefile < 0) return; while (bytesread != 0) { unsigned int family, type, protocol; bytesread = read(cachefile, buffer, sizeof(int) * 3); if (bytesread == 0) break; family = buffer[0]; type = buffer[1]; protocol = buffer[2]; printf("family:%s type:%s protocol:%s (%u)\n", get_family_name(family), decode_type(type), get_proto_name(family, protocol), protocol); nr_sockets++; } printf("%u entries in socket cachefile.\n", nr_sockets); close(cachefile); }
SMASI_PDU *smasi_pdu_unpack(Octstr *data_without_len) { SMASI_PDU *pdu; char *type_name; Octstr *temp; long pos; unsigned long type = 0; /* extract the PDU type identifier */ temp = decode_type(data_without_len); type_name = (temp ? octstr_get_cstr(temp) : ""); if (strcmp(type_name, "dummy") == 0) type = 0; #define NONTERMINATED(name) p = *(&p); #define COMATERMINATED(name) p = *(&p); #define PDU(name, id, fields) \ else if (strcmp(type_name, #name) == 0) type = id; #include "smasi_pdu.def" else warning(0, "unknown SMASI PDU type"); pdu = smasi_pdu_create(type); if (pdu == NULL) return NULL; pos = 0; skip_until_after_colon(data_without_len, &pos); switch (type) { #define NONTERMINATED(name) p = *(&p); #define COMATERMINATED(name) \ if (octstr_str_compare(field_name, #name) == 0 && field_value != NULL) \ p->name = octstr_duplicate(field_value); #define PDU(name, id, fields) \ case id: { \ Octstr * field_name = NULL; \ Octstr * field_value = NULL; \ struct name *p = &pdu->u.name; \ while (pos < octstr_len(data_without_len)) { \ field_name = copy_until_assign(data_without_len, &pos); \ if (field_name == NULL) break; \ field_value = copy_until_coma(data_without_len, &pos); \ if (field_value == NULL) continue; \ fields \ octstr_destroy(field_name); \ octstr_destroy(field_value); \ } \ } break; #include "smasi_pdu.def" default: warning(0, "Unknown SMASI_PDU type, internal error while unpacking."); } octstr_destroy(temp); return pdu; }
std::string to_string(std::vector<Constant> const& pool) const { switch (type) { case EMPTY: return "<! empty !>"; case STRING: return encode(value.string); case INTEGER: return std::to_string(value.integer); case FLOAT: return std::to_string(value.float_); case LONG: return std::to_string(value.long_); case DOUBLE: return std::to_string(value.double_); case CLASS_REFERENCE: return decode_class_name(pool[value.reference].to_string(pool)); case STRING_REFERENCE: return pool[value.reference].to_string(pool); case FIELD_REFERENCE: return "field \"" + pool[value.pair_reference.second].to_string(pool) + "\" of class " + pool[value.pair_reference.first].to_string(pool); case METHOD_REFERENCE: return "method \"" + pool[value.pair_reference.second].to_string(pool) + "\" of class " + pool[value.pair_reference.first].to_string(pool); case INTERFACE_METHOD_REFERENCE: return "interface method \"" + pool[value.pair_reference.second].to_string(pool) + "\" of class " + pool[value.pair_reference.first].to_string(pool); case NAME_TYPE_DESCRIPTOR: return decode_type(pool[value.pair_reference.second].value.string).to_string(pool[value.pair_reference.first].value.string); case METHOD_HANDLE: return "<! method handle !>"; case METHOD_TYPE: return "<! method type !>"; case INVOKE_DYNAMIC: return "<! INVOKE_DYNAMIC !>"; default: return "<! invalid type !>"; } }
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) */ }
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) */ }
static int get_command(struct command_s *command) { char *next; again: printf("command: "); if (!fgets(cbuf, COMMAND_MAX_LEN, stdin)) return -1; next = strtok(cbuf, " \n"); if (!next) goto again; if (decode_type(command, next)) { fprintf(stderr, "Invalid command type \"%s\"\n", next); goto again; } if (command->c_type == HELP) return 0; next = strtok(NULL, " "); if (!next) { fprintf(stderr, "invalid input!\n"); goto again; } switch (command->c_type) { case REGISTER: case UNREGISTER: if (decode_domain(command, next)) { fprintf(stderr, "Invalid domain \"%s\"\n", next); goto again; } break; case LOCK: case TRYLOCK: if (decode_level(command, next)) { fprintf(stderr, "Invalid lock level \"%s\"\n", next); goto again; } next = strtok(NULL, " "); if (!next) { fprintf(stderr, "invalid input!\n"); goto again; } /* fall through */ case SETLVB: case GETLVB: case UNLOCK: if (decode_lock(command, next)) { fprintf(stderr, "Invalid lock \"%s\"\n", next); goto again; } if (command->c_type == SETLVB) { /* for setlvb we want to get a pointer to the * start of the string to stuff */ next = strtok(NULL, "\n"); if (!next) { fprintf(stderr, "invalid input!\n"); goto again; } kill_return(next); command->c_lvb = next; } break; default: fprintf(stderr, "whoa, can't parse this\n"); } return 0; }
/* * Takes a WMO format product which is a * SAO, SYNOP, SHIP, METAR, or SPECI message, splits it into * individual observations. The observations are each encapsulated in a * new product which inherits most of its description from the * original product. * The new product pkey is derived from the observation type * and has the following form: * * SAO - "sao tt ccc ddhhmm" * where: * tt is SA, SP or RS * ccc is the station ID like SFO, LXV, etc * ddhhmm is the time stamp. * * SYNOP - "aaxx nnnnn ddhhmm" * where: * nnnnn is the WMO station id (5 digit number) * * SHIP - "bbxx c* ddhhmm" * where: * c* is the call sign * * METAR - "metar cccc ddhhmm" * where: * cccc is the call sign * * SPECI - "speci cccc ddhhmm" * * The new product sequence number is original sequence number times 1000 * plus the sequence of the individual observation within the product. * * 'doit' is called on each of the new products. It is presumed * this function return zero upon success. * * Returns the number of successful calls to 'doit', eg, the * number of splits. Returns -1 on error. */ int surf_split(const prod_info *infop, const void *datap, int (*doit)(const prod_info *, const void *)) { wmo_header_t hdr; message_type_t mtype; dtime dt; xbuf buf[1]; static unsigned char* dbuf = NULL; static size_t dbufSize = 0; char header[50]; int nsplit = 0; enum { SURFACE_BOGUS , AAXX, US_AAXX, BBXX, SAO, sMETAR, sSPECI } subtype = SURFACE_BOGUS; hdr.time = &dt; if(infop->sz > dbufSize || dbuf == NULL) { size_t size = infop->sz != 0 ? infop->sz : 1; if (dbuf != NULL) free(dbuf); dbuf = malloc(size); if (dbuf == NULL) { serror("surf_split(): Couldn't allocate %lu-byte buffer", (unsigned long)size); dbufSize = 0; return -1; } dbufSize = size; } memcpy(dbuf, datap, infop->sz); if( cbuftoxbuf(buf, dbuf, infop->sz) == NULL) return -1; skipline(buf, 4); /* SOH */ skipline(buf, 12); /* start */ /* inspect header as a string to see if to use PIL processing or not */ if(infop->sz > 48 ) { memcpy( header, datap, 48 ); header[48] = '\0'; } else { memcpy( header, datap, infop->sz ); header[infop->sz] = '\0'; } if( strstr( header, "METAR\r" ) || strstr( header, "SPECI\r" ) || strstr( header, "MTR" ) || strstr( header, "METAR \r" ) || strstr( header, "SPECI \r" ) || strstr( header, "BOYC" )) { usePil = 1; } else { usePil = 0; } if( get_wmo_header(buf, &hdr) == NULL) { uerror("get_wmo_header: hdr: %s\n", hdr); return -1; } usePil = 1; #if DEBUG fputs("\t", stderr); fprint_wmo_header(stderr, &hdr); fputs("\n", stderr); #endif mtype = decode_type(hdr.TT,hdr.AA,hdr.PIL); /* #### */ { char cbuf[8]; int digit; dtime time; wind_units_t wind_units = WIND_UNAVAIL; time = *hdr.time; /* default the ob time to the time in the header */ /* delve into section 0 */ switch(mtype) { case SYNOP : if(get_wstr(buf, cbuf, 1) < 0 ) return -1; if(cbuf[0] == 'A') { subtype = AAXX; if(get_str(buf, &cbuf[1], 3) < 0 ) return -1; if( cbuf[3] != 'X' ) { /* punt */ uerror("surface_split: Unknown SYNOP type: %s\n", cbuf); return 0; } if(get_yygg(buf, &time) < 0 ) return -1; /* YYGG */ if(dget_num(buf, &digit, 1) < 0 ) return -1; /* isubw */ if(digit >= 0 && digit <= 4) wind_units = (wind_units_t)digit; } else if(isascii(cbuf[0]) && isdigit(cbuf[0])) /* US Stations 7NNNN */ { unnextc(buf,cbuf[0]); subtype = US_AAXX; /* * Some US reports leave off AAXX YYGGisubw, so we use the * time from the wmo header. */ wind_units = KNOTS; } else { unnextc(buf,cbuf[0]); return 0; /* ?? */ } break; case SHIP : if (hdr.PIL[0] != '\0' && whasSTR(buf, "BOYC")) { skipline(buf, 4); } if(get_wstr(buf, cbuf, 4) < 0 ) return -1; if(cbuf[0] == 'B') { if( cbuf[3] != 'X' ) { /* punt */ uerror("surface_split: Unknown SHIP type: %s\n", cbuf); return 0; } subtype = BBXX; /* get time below */ } else { unnextc(buf,cbuf[0]); return 0; } break; case METAR : if( hdr.PIL[0] != '\0' && (! strstr(hdr.PIL, "METAR") || !strstr(hdr.PIL, "MTR"))){ subtype = sMETAR; } else if(whasSTR(buf, "METAR")) { subtype = sMETAR; get_wyyggZ(buf, &time); } else if(whasSTR(buf, "SPECI")) { subtype = sSPECI; get_wyyggZ(buf, &time); } else { subtype = SAO; /* may actually be a METAR, check below */ } break; case SPECI : if(whasSTR(buf, "SPECI")) { subtype = sSPECI; get_wyyggZ(buf, &time); } break; default : uerror("surface_split: Can't handle %s", sMessage_type(mtype) ); uerror("HDR + PIL: %s%s %s", hdr.TT, hdr.AA, hdr.PIL ) ; return -1; } { /* while block */ static char newkey[KEYSIZE]; xbuf subbuf[1]; prod_info newinfo = *infop; #define MAX_SURF_LEN 511 #undef MIN #define MIN(a,b) ((a) <= (b) ? (a) : (b)) char pbuf[MAX_SURF_LEN + 1]; int l1, l2; static char ident[CALL_SIGN_LEN+1]; static char type[4]; char *stype; u_int subseq = infop->seqno * 1000; unsigned char *pp; while( get_weqxbuf(buf, subbuf) > 0 ) { (void)memset(newkey,0,KEYSIZE); (void)memset(pbuf,0,MAX_SURF_LEN + 1); (void)memset(ident,0,CALL_SIGN_LEN+1); pp = subbuf->base; switch(subtype) { case AAXX : case US_AAXX : strcpy(newkey, "aaxx "); strcpy(pbuf, "AAXX"); sprintf(&pbuf[strlen(pbuf)], " %02d%02d%1d\r\r\n", time.mday, time.hour, (int)wind_units); /* WMO station no. */ if(get_wstr(subbuf, ident, 5) < 0) continue; strcat(newkey, ident); break; case BBXX : strcpy(newkey, "bbxx "); strcpy(pbuf, "BBXX\r\r\n"); /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; strcat(newkey, ident); if(get_yygg(subbuf, &time) < 0) continue; /* YYGG */ break; case sSPECI : /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; stype = "SPECI"; if(strcmp(ident, "METAR") == 0 || strcmp(ident, "SPECI") == 0) { if( strcmp(ident, "METAR") == 0) { stype = "METAR"; } /* They package each ob with a tag */ pp = (subbuf->get +1); if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; } if(!whas_yyggZ(subbuf)) { /* Have to insert the date */ sprintf(pbuf, "%s\r\r\n%s %02d%02dZ ", stype, ident, time.hour, time.min); pp = subbuf->get; } else { strcpy(pbuf, stype); strcat(pbuf, "\r\r\n"); } if(strcmp(stype, "METAR") == 0 ) { strcpy(newkey, "metar "); } else { strcpy(newkey, "speci "); } strcat(newkey, ident); break; case sMETAR : if(has_NIL(subbuf)) continue; /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) { continue; } stype = "METAR"; if(strcmp(ident, "METAR") == 0 || strcmp(ident, "SPECI") == 0) { if( strcmp(ident, "SPECI") == 0) { stype = "SPECI"; } /* They package each ob with a tag */ pp = (subbuf->get +1); if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; } if(!whas_yyggZ(subbuf)) { /* Have to insert the date */ sprintf(pbuf, "%s\r\r\n%s %02d%02dZ ", stype, ident, time.hour, time.min); pp = subbuf->get; } else { strcpy(pbuf, stype); strcat(pbuf, "\r\r\n"); } if(strcmp(stype, "METAR") == 0 ) { strcpy(newkey, "metar "); } else { strcpy(newkey, "speci "); } strcat(newkey, ident); break; case SAO : /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; if(hdr.AA[0] == 'U' && hdr.AA[1] == 'S' && strlen(ident) == 6) { /* skip 6 char US "AFOS code" */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; } /* SA, SP, RS, USP or XP */ if(get_wstr(subbuf, type, 3) < 0) continue; if((type[0] == 'S' && (type[1] == 'A' || type[1] == 'P')) || (type[0] == 'R' && type[1] == 'S') || (type[0] == 'U' && type[1] == 'S' && type[2] == 'P') || (type[0] == 'X' && type[1] == 'P') || (type[0] == 'T' && (type[1] == 'A' || type[1] == 'S')) ) { strcpy(newkey, "sao "); strcat(newkey, type); strcat(newkey, " "); strcat(newkey, ident); } else if(isdigit(type[0]) && isdigit(type[1])) { /* it is a METAR really */ subtype = sMETAR; strcpy(newkey, "metar "); strcat(newkey, ident); strcpy(pbuf, "METAR\r\r\n"); } else continue; /* don't know what it is, "NIL=" */ break; } /* safety net */ if(strlen(ident) == 0) { continue; } /* else */ sprintf(&newkey[strlen(newkey)], " %02d%02d%02d", time.mday, time.hour, time.min); if(hdr.retransmit != ORIGINAL) sprintf(&newkey[strlen(newkey)], " %s", sRetransmit(&hdr)); newinfo.ident = newkey; newinfo.seqno = ++subseq; l1 = strlen(pbuf); l2 = MIN(MAX_SURF_LEN - l1 - 4, subbuf->bufsiz - (pp - subbuf->base)); /* N.B.: silent truncation */ strncat(pbuf, (char *)pp, l2 ); strcat(pbuf,"=\r\r\n"); newinfo.sz = l1 + l2 + 4; #if DEBUG fprintf(stderr,"\t\t%s\n", newinfo.ident); #endif #if PRINT { char *cp = pbuf; char *end = &cp[newinfo.sz]; while(cp < end) { putc(*cp, stderr); cp++; } } putc('\n', stderr); #endif MD5Init(md5ctxp); MD5Update(md5ctxp, (const unsigned char *)pbuf, newinfo.sz); MD5Final((unsigned char*)newinfo.signature, md5ctxp); /* * process the single ob in the requested fashion */ if((*doit)(&newinfo, pbuf) == 0) nsplit++; } /* end while */ #if PRINT putc('\n', stderr); #endif } /* end while block */ } /* end #### block */ return nsplit; }
/** * Sets the specified attribute of an MDS instance. * * \param mds the mds. * \param attribute a pointer to an attribute of an MDS instance. */ void mds_set_attribute(MDS *mds, AVA_Type *attribute) { int error = 0; intu8 *value = attribute->attribute_value.value; intu16 length = attribute->attribute_value.length; switch (attribute->attribute_id) { case MDC_ATTR_ID_HANDLE: break; case MDC_ATTR_SYS_TYPE: { TYPE s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_type(stream, &s, &error); if (!error) { del_type(&mds->system_type); mds->system_type = s; } free(stream); } break; case MDC_ATTR_ID_MODEL: { SystemModel s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_systemmodel(stream, &s, &error); if (!error) { del_systemmodel(&mds->system_model); mds->system_model = s; } free(stream); } break; case MDC_ATTR_SYS_ID: { octet_string s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_octet_string(stream, &s, &error); if (! error) { del_octet_string(&mds->system_id); mds->system_id = s; } free(stream); } break; case MDC_ATTR_DEV_CONFIG_ID: { ConfigId s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_configid(stream, &s, &error); if (! error) { del_configid(&mds->dev_configuration_id); mds->dev_configuration_id = s; } free(stream); } break; case MDC_ATTR_ATTRIBUTE_VAL_MAP: { AttrValMap s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_attrvalmap(stream, &s, &error); if (! error) { del_attrvalmap(&mds->attribute_value_map); mds->attribute_value_map = s; } free(stream); } break; case MDC_ATTR_ID_PROD_SPECN: { ProductionSpec s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_productionspec(stream, &s, &error); if (! error) { del_productionspec(&mds->production_specification); mds->production_specification = s; } free(stream); } break; case MDC_ATTR_MDS_TIME_INFO: { MdsTimeInfo s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_mdstimeinfo(stream, &s, &error); if (! error) { del_mdstimeinfo(&mds->mds_time_info); mds->mds_time_info = s; } free(stream); } break; case MDC_ATTR_TIME_ABS: { AbsoluteTime s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_absolutetime(stream, &s, &error); if (! error) { del_absolutetime(&mds->date_and_time); mds->date_and_time = s; } free(stream); } break; case MDC_ATTR_TIME_REL: { RelativeTime s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); s = read_intu32(stream, &error); if (! error) { // del_relative_time not needed mds->relative_time = s; } free(stream); } break; case MDC_ATTR_TIME_REL_HI_RES: { HighResRelativeTime s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_highresrelativetime(stream, &s, &error); if (! error) { del_highresrelativetime(&mds->hires_relative_time); mds->hires_relative_time = s; } free(stream); } break; case MDC_ATTR_TIME_ABS_ADJUST: { AbsoluteTimeAdjust s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_absolutetimeadjust(stream, &s, &error); if (! error) { del_absolutetimeadjust(&mds->date_and_time_adjustment); mds->date_and_time_adjustment = s; } free(stream); } break; case MDC_ATTR_POWER_STAT: { PowerStatus s; // del not needed ByteStreamReader *stream = byte_stream_reader_instance(value, length); s = read_intu16(stream, &error); if (! error) { mds->power_status = s; } free(stream); } break; case MDC_ATTR_VAL_BATT_CHARGE: { intu16 s; // del not needed ByteStreamReader *stream = byte_stream_reader_instance(value, length); s = read_intu16(stream, &error); if (! error) { mds->battery_level = s; } free(stream); } break; case MDC_ATTR_TIME_BATT_REMAIN: { BatMeasure s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_batmeasure(stream, &s, &error); if (! error) { del_batmeasure(&mds->remaining_battery_time); mds->remaining_battery_time = s; } free(stream); } break; case MDC_ATTR_REG_CERT_DATA_LIST: { RegCertDataList s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_regcertdatalist(stream, &s, &error); if (! error) { del_regcertdatalist(&mds->reg_cert_data_list); mds->reg_cert_data_list = s; } free(stream); } break; case MDC_ATTR_SYS_TYPE_SPEC_LIST: { TypeVerList s; ByteStreamReader *stream = byte_stream_reader_instance(value, length); decode_typeverlist(stream, &s, &error); if (! error) { del_typeverlist(&mds->system_type_spec_list); mds->system_type_spec_list = s; } free(stream); } break; case MDC_ATTR_CONFIRM_TIMEOUT: { RelativeTime s; // del not needed ByteStreamReader *stream = byte_stream_reader_instance(value, length); s = read_intu32(stream, &error); if (! error) mds->confirm_timeout = s; free(stream); } break; default: DEBUG("MDS attribute unknown: %d", attribute->attribute_id); } }
/** * Initializes a given Metric attribute from stream content. * * \param metric the Metric. * \param attr_id the Metric's attribute ID. * \param stream the value of Metric's attribute. * \param data_entry output parameter to describe data value. * * \return \b 1, if the Metric's attribute is properly modified; \b 0 otherwise. * */ int dimutil_fill_metric_attr(struct Metric *metric, OID_Type attr_id, ByteStreamReader *stream, DataEntry *data_entry) { int result = 1; int error = 0; switch (attr_id) { case MDC_ATTR_ID_HANDLE: metric->handle = read_intu16(stream, &error); if (error) { result = 0; break; } data_set_handle(data_entry, "Handle", &metric->handle); break; case MDC_ATTR_ID_TYPE: del_type(&(metric->type)); decode_type(stream, &(metric->type), &error); if (error) { result = 0; break; } data_set_type(data_entry, "Type", &metric->type); break; case MDC_ATTR_SUPPLEMENTAL_TYPES: del_supplementaltypelist(&metric->supplemental_types); decode_supplementaltypelist(stream, &(metric->supplemental_types), &error); if (error) { result = 0; break; } data_set_attribute_supplemental_types(data_entry, "Supplemental-Types", &metric->supplemental_types); break; case MDC_ATTR_METRIC_SPEC_SMALL: del_metricspecsmall(&metric->metric_spec_small); decode_metricspecsmall(stream, &(metric->metric_spec_small), &error); if (error) { result = 0; break; } data_set_attribute_metric_spec_small(data_entry, "Metric-Spec-Small", &metric->metric_spec_small); break; case MDC_ATTR_METRIC_STRUCT_SMALL: del_metricstructuresmall(&(metric->metric_structure_small)); decode_metricstructuresmall(stream, &(metric->metric_structure_small), &error); if (error) { result = 0; break; } data_set_attribute_metric_structure_small(data_entry, "Metric-Structure-Small", &metric->metric_structure_small); break; case MDC_ATTR_MSMT_STAT: metric->measurement_status = read_intu16(stream, &error); if (error) { result = 0; break; } data_set_intu16(data_entry, "Measurement-Status", &metric->measurement_status); break; case MDC_ATTR_ID_PHYSIO: metric->metric_id = read_intu16(stream, &error); if (error) { result = 0; break; } metric->use_metric_id_field = 1; // TRUE data_set_oid_type(data_entry, "Metric-Id", &metric->metric_id); break; case MDC_ATTR_ID_PHYSIO_LIST: del_metricidlist(&metric->metric_id_list); decode_metricidlist(stream, &metric->metric_id_list, &error); if (error) { result = 0; break; } data_set_metric_id_list(data_entry, "Metric-Id-List", &metric->metric_id_list); break; case MDC_ATTR_METRIC_ID_PART: metric->metric_id_partition = read_intu16(stream, &error); if (error) { result = 0; break; } metric->use_metric_id_partition_field = 1; // TRUE data_set_intu16(data_entry, "Metric-Id-Partition", &metric->metric_id_partition); break; case MDC_ATTR_UNIT_CODE: metric->unit_code = read_intu16(stream, &error); if (error) { result = 0; break; } data_set_oid_type(data_entry, "Unit-Code", &metric->unit_code); break; case MDC_ATTR_ATTRIBUTE_VAL_MAP: del_attrvalmap(&metric->attribute_value_map); decode_attrvalmap(stream, &(metric->attribute_value_map), &error); if (error) { result = 0; break; } data_set_attribute_value_map(data_entry, "Attribute-Value-Map", &metric->attribute_value_map); break; case MDC_ATTR_SOURCE_HANDLE_REF: metric->source_handle_reference = read_intu16(stream, &error); if (error) { result = 0; break; } data_set_handle(data_entry, "Source-Handle-Reference", &metric->source_handle_reference); break; case MDC_ATTR_ID_LABEL_STRING: del_octet_string(&metric->label_string); decode_octet_string(stream, &(metric->label_string), &error); if (error) { result = 0; break; } data_set_label_string(data_entry, "Label-String", &metric->label_string); break; case MDC_ATTR_UNIT_LABEL_STRING: del_octet_string(&metric->unit_label_string); decode_octet_string(stream, &(metric->unit_label_string), &error); if (error) { result = 0; break; } data_set_label_string(data_entry, "Unit-LabelString", &metric->unit_label_string); break; case MDC_ATTR_TIME_STAMP_ABS: del_absolutetime(&metric->absolute_time_stamp); decode_absolutetime(stream, &(metric->absolute_time_stamp), &error); if (error) { result = 0; break; } data_set_absolute_time(data_entry, "Absolute-Time-Stamp", &metric->absolute_time_stamp); break; case MDC_ATTR_TIME_STAMP_REL: metric->relative_time_stamp = read_intu32(stream, &error); if (error) { result = 0; break; } data_set_intu32(data_entry, "Relative-Time-Stamp", &metric->relative_time_stamp); break; case MDC_ATTR_TIME_STAMP_REL_HI_RES: del_highresrelativetime(&metric->hi_res_time_stamp); decode_highresrelativetime(stream, &(metric->hi_res_time_stamp), &error); if (error) { result = 0; break; } data_set_high_res_relative_time(data_entry, "HiRes-Time-Stamp", &metric->hi_res_time_stamp); break; case MDC_ATTR_TIME_PD_MSMT_ACTIVE: metric->measure_active_period = read_float(stream, &error); if (error) { result = 0; break; } data_set_float(data_entry, "Measure-Active-Period", &metric->measure_active_period); break; default: DEBUG("Unrecognized metric attribute-id %d", attr_id); break; } return result; }