diff options
Diffstat (limited to 'src/zabbix_server/discoverer/discoverer.c')
-rw-r--r-- | src/zabbix_server/discoverer/discoverer.c | 312 |
1 files changed, 139 insertions, 173 deletions
diff --git a/src/zabbix_server/discoverer/discoverer.c b/src/zabbix_server/discoverer/discoverer.c index ecddea49ce6..d2e9dbe5f00 100644 --- a/src/zabbix_server/discoverer/discoverer.c +++ b/src/zabbix_server/discoverer/discoverer.c @@ -45,8 +45,6 @@ extern int server_num, process_num; * * * Parameters: service - service info * * * - * Author: Alexander Vladishev * - * * ******************************************************************************/ static void proxy_update_service(DB_DRULE *drule, DB_DCHECK *dcheck, const char *ip, const char *dns, int port, int status, const char *value, int now) @@ -77,8 +75,6 @@ static void proxy_update_service(DB_DRULE *drule, DB_DCHECK *dcheck, const char * * * Parameters: service - service info * * * - * Author: Alexander Vladishev * - * * ******************************************************************************/ static void proxy_update_host(DB_DRULE *drule, const char *ip, const char *dns, int status, int now) { @@ -103,10 +99,8 @@ static void proxy_update_host(DB_DRULE *drule, const char *ip, const char *dns, * * * Parameters: service type, ip address, port number * * * - * Author: Alexei Vladishev * - * * ******************************************************************************/ -static int discover_service(DB_DCHECK *dcheck, char *ip, int port, char *value) +static int discover_service(DB_DCHECK *dcheck, char *ip, int port, char **value, size_t *value_alloc) { const char *__function_name = "discover_service"; int ret = SUCCEED; @@ -115,11 +109,13 @@ static int discover_service(DB_DCHECK *dcheck, char *ip, int port, char *value) AGENT_RESULT result; DC_ITEM item; ZBX_FPING_HOST host; + size_t value_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); init_result(&result); - *value = '\0'; + + **value = '\0'; switch (dcheck->type) { @@ -228,7 +224,7 @@ static int discover_service(DB_DCHECK *dcheck, char *ip, int port, char *value) if (SVC_AGENT == dcheck->type) { if (SUCCEED == get_value_agent(&item, &result) && NULL != GET_STR_RESULT(&result)) - zbx_strlcpy(value, result.str, DSERVICE_VALUE_LEN_MAX); + zbx_strcpy_alloc(value, value_alloc, &value_offset, result.str); else ret = FAIL; } @@ -267,7 +263,7 @@ static int discover_service(DB_DCHECK *dcheck, char *ip, int port, char *value) } if (SUCCEED == get_value_snmp(&item, &result) && NULL != GET_STR_RESULT(&result)) - zbx_strlcpy(value, result.str, DSERVICE_VALUE_LEN_MAX); + zbx_strcpy_alloc(value, value_alloc, &value_offset, result.str); else ret = FAIL; @@ -322,46 +318,42 @@ static int discover_service(DB_DCHECK *dcheck, char *ip, int port, char *value) * * * Parameters: service - service info * * * - * Author: Eugene Grigorjev * - * * ******************************************************************************/ -static void process_check(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, - int *host_status, char *ip, const char *dns, int now) +static void process_check(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, int *host_status, char *ip, + const char *dns, int now) { const char *__function_name = "process_check"; int port, first, last; - char *curr_range, *next_range, *last_port; + char *start, *comma, *last_port; int status; - char value[DSERVICE_VALUE_LEN_MAX]; + char *value = NULL; + size_t value_alloc = 128; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); - for (curr_range = dcheck->ports; curr_range; curr_range = next_range) + value = zbx_malloc(value, value_alloc); + + for (start = dcheck->ports; '\0' != *start;) { - if (NULL != (next_range = strchr(curr_range, ','))) - *next_range = '\0'; + if (NULL != (comma = strchr(start, ','))) + *comma = '\0'; - if (NULL != (last_port = strchr(curr_range, '-'))) + if (NULL != (last_port = strchr(start, '-'))) { *last_port = '\0'; - first = atoi(curr_range); + first = atoi(start); last = atoi(last_port + 1); *last_port = '-'; } else - first = last = atoi(curr_range); - - if (NULL != next_range) - { - *next_range = ','; - next_range++; - } + first = last = atoi(start); for (port = first; port <= last; port++) { zabbix_log(LOG_LEVEL_DEBUG, "%s() port:%d", __function_name, port); - status = (SUCCEED == discover_service(dcheck, ip, port, value)) ? DOBJECT_STATUS_UP : DOBJECT_STATUS_DOWN; + status = (SUCCEED == discover_service(dcheck, ip, port, &value, &value_alloc) ? + DOBJECT_STATUS_UP : DOBJECT_STATUS_DOWN); /* update host status */ if (-1 == *host_status || DOBJECT_STATUS_UP == status) @@ -376,8 +368,18 @@ static void process_check(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, DBcommit(); } + + if (NULL != comma) + { + *comma = ','; + start = comma + 1; + } + else + break; } + zbx_free(value); + zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); } @@ -385,8 +387,6 @@ static void process_check(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, * * * Function: process_checks * * * - * Author: Alexander Vladishev * - * * ******************************************************************************/ static void process_checks(DB_DRULE *drule, DB_DHOST *dhost, int *host_status, char *ip, const char *dns, int unique, int now) @@ -443,176 +443,124 @@ static void process_checks(DB_DRULE *drule, DB_DHOST *dhost, int *host_status, * * * Purpose: process single discovery rule * * * - * Author: Eugene Grigorjev * - * * ******************************************************************************/ static void process_rule(DB_DRULE *drule) { const char *__function_name = "process_rule"; + DB_DHOST dhost; int host_status, now; - unsigned int j[9], i, first, last, mask, network, broadcast; - char ip[INTERFACE_IP_LEN_MAX], *curr_range, *next_range, - *dash, *slash, dns[INTERFACE_DNS_LEN_MAX]; + unsigned short j[9]; + unsigned int i, first, last, ip_dig; + char ip[INTERFACE_IP_LEN_MAX], *start, *comma, *dash, *slash, dns[INTERFACE_DNS_LEN_MAX]; + int invalid_range; +#ifdef HAVE_IPV6 int ipv6; +#endif zabbix_log(LOG_LEVEL_DEBUG, "In %s() rule:'%s' range:'%s'", __function_name, drule->name, drule->iprange); - for (curr_range = drule->iprange; curr_range; curr_range = next_range) + for (start = drule->iprange; '\0' != *start;) { - if (NULL != (next_range = strchr(curr_range, ','))) - *next_range = '\0'; + invalid_range = 0; - zabbix_log(LOG_LEVEL_DEBUG, "%s() '%s'", __function_name, curr_range); + if (NULL != (comma = strchr(start, ','))) + *comma = '\0'; - if (NULL != (dash = strchr(curr_range, '-'))) - *dash = '\0'; + zabbix_log(LOG_LEVEL_DEBUG, "%s() range:'%s'", __function_name, start); - if (NULL != (slash = strchr(curr_range, '/'))) + if (NULL != (dash = strchr(start, '-'))) + *dash = '\0'; + else if (NULL != (slash = strchr(start, '/'))) *slash = '\0'; - first = last = 0; - - if (SUCCEED == expand_ipv6(curr_range, ip, sizeof(ip))) + if (SUCCEED == ip6_str2dig(start, j)) { - ipv6 = 1; #ifdef HAVE_IPV6 - if (8 == sscanf(ip, "%x:%x:%x:%x:%x:%x:%x:%x", &j[0], &j[1], &j[2], &j[3], &j[4], &j[5], &j[6], &j[7])) - { - first = (j[6] << 16) + j[7]; + ipv6 = 1; - if (NULL != dash) + if (NULL != dash) + { + if (1 != sscanf(dash + 1, "%hx", &j[8])) { - if (1 == sscanf(dash + 1, "%x", &j[8])) - last = (j[6] << 16) + j[8]; + invalid_range = 1; + goto next; } - else if (NULL != slash) + + first = j[7]; + last = j[8]; + } + else if (NULL != slash) + { + unsigned short mask; + + if (1 != sscanf(slash + 1, "%hu", &j[8]) || 112 > j[8] || j[8] > 128) { - if (1 == sscanf(slash + 1, "%d", &j[8]) && j[8] >= 112 && j[8] <= 128) - { - j[8] -= 96; - - mask = (32 == j[8]) ? 0xffffffff : ~(0xffffffff >> j[8]); - network = first & mask; - broadcast = network + ~mask; - first = network + 1; - - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 CIDR:%u", __function_name, j[8] + 96); - zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x", - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - (mask & 0xffff0000) >> 16, (mask & 0x0000ffff)); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 Netmask:'%s'", - __function_name, collapse_ipv6(ip, sizeof(ip))); - zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x", - j[0], j[1], j[2], j[3], j[4], j[5], - (network & 0xffff0000) >> 16, (network & 0x0000ffff)); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 Network:'%s'", - __function_name, collapse_ipv6(ip, sizeof(ip))); - zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x", - j[0], j[1], j[2], j[3], j[4], j[5], - (broadcast & 0xffff0000) >> 16, (broadcast & 0x0000ffff)); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 Broadcast:'%s'", - __function_name, collapse_ipv6(ip, sizeof(ip))); - - if (j[8] <= 30) - last = broadcast - 1; - } + invalid_range = 1; + goto next; } - else - last = first; - - zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x", - j[0], j[1], j[2], j[3], j[4], j[5], - (first & 0xffff0000) >> 16, (first & 0x0000ffff)); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 From:'%s'", - __function_name, collapse_ipv6(ip, sizeof(ip))); - zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x", - j[0], j[1], j[2], j[3], j[4], j[5], - (last & 0xffff0000) >> 16, (last & 0x0000ffff)); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv6 To:'%s'", - __function_name, collapse_ipv6(ip, sizeof(ip))); + + mask = 0xffff << (128 - j[8]); + first = j[7] & mask; + last = 0xffff & (j[7] | ~mask); + } + else + { + first = j[7]; + last = j[7]; } +#else + invalid_range = 2; + goto next; #endif } - else + else if (SUCCEED == ip4_str2dig(start, &ip_dig)) { +#ifdef HAVE_IPV6 ipv6 = 0; - if (4 == sscanf(curr_range, "%u.%u.%u.%u", &j[0], &j[1], &j[2], &j[3]) && - j[0] <= 255 && j[1] <= 255 && j[2] <= 255 && j[3] <= 255) +#endif + if (NULL != dash) { - first = (j[0] << 24) + (j[1] << 16) + (j[2] << 8) + j[3]; - - if (NULL != dash) + if (1 != sscanf(dash + 1, "%hu", &j[4]) || 255 < j[4]) { - if (1 == sscanf(dash + 1, "%u", &j[4]) && j[4] <= 255) - last = (j[0] << 24) + (j[1] << 16) + (j[2] << 8) + j[4]; + invalid_range = 1; + goto next; } - else if (NULL != slash) + + first = ip_dig; + last = (ip_dig & 0xffffff00) + j[4]; + } + else if (NULL != slash) + { + unsigned int mask; + + if (1 != sscanf(slash + 1, "%hu", &j[4]) || 16 > j[4] || j[4] > 30) { - if (1 == sscanf(slash + 1, "%u", &j[4]) && j[4] >= 16 && j[4] <= 32) - { - mask = (32 == j[4]) ? 0xffffffff : ~(0xffffffff >> j[4]); - network = first & mask; - broadcast = network + ~mask; - first = network + 1; - - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv4 CIDR:%u", __function_name, j[4]); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv4 Netmask:'%u.%u.%u.%u'", __function_name, - (mask & 0xff000000) >> 24, (mask & 0x00ff0000) >> 16, - (mask & 0x0000ff00) >> 8, (mask & 0x000000ff)); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv4 Network:'%u.%u.%u.%u'", __function_name, - (network & 0xff000000) >> 24, (network & 0x00ff0000) >> 16, - (network & 0x0000ff00) >> 8, (network & 0x000000ff)); - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv4 Broadcast:'%u.%u.%u.%u'", __function_name, - (broadcast & 0xff000000) >> 24, (broadcast & 0x00ff0000) >> 16, - (broadcast & 0x0000ff00) >> 8, (broadcast & 0x000000ff)); - - if (j[4] <= 30) - last = broadcast - 1; - } + invalid_range = 1; + goto next; } - else - last = first; - zabbix_log(LOG_LEVEL_DEBUG, "%s() IPv4 Range:'%u.%u.%u.%u' - '%u.%u.%u.%u'", __function_name, - (first & 0xff000000) >> 24, (first & 0x00ff0000) >> 16, - (first & 0x0000ff00) >> 8, (first & 0x000000ff), - (last & 0xff000000) >> 24, (last & 0x00ff0000) >> 16, - (last & 0x0000ff00) >> 8, (last & 0x000000ff)); + mask = 0xffffffff << (32 - j[4]); + first = (ip_dig & mask) + 1; + last = (ip_dig | ~mask) - 1; + } + else + { + first = ip_dig; + last = ip_dig; } } - - if (NULL != dash) + else { - *dash = '-'; - dash = NULL; + invalid_range = 1; + goto next; } - if (NULL != slash) + if (first > last) { - *slash = '/'; - slash = NULL; - } - - if (NULL != next_range) - { - *next_range = ','; - next_range ++; - } -#ifndef HAVE_IPV6 - if (1 == ipv6) - { - zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": encountered IP range \"%s\"," - " but IPv6 support not compiled in", drule->name, curr_range); - continue; - } -#endif - if (0 == first || 0 == last || first > last) - { - zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": wrong format of IP range \"%s\"", - drule->name, curr_range); - continue; + invalid_range = 1; + goto next; } for (i = first; i <= last; i++) @@ -621,29 +569,23 @@ static void process_rule(DB_DRULE *drule) host_status = -1; now = time(NULL); - #ifdef HAVE_IPV6 switch (ipv6) { case 0: #endif zbx_snprintf(ip, sizeof(ip), "%u.%u.%u.%u", - (i & 0xff000000) >> 24, - (i & 0x00ff0000) >> 16, - (i & 0x0000ff00) >> 8, - (i & 0x000000ff)); + (i & 0xff000000) >> 24, (i & 0x00ff0000) >> 16, + (i & 0x0000ff00) >> 8, i & 0x000000ff); #ifdef HAVE_IPV6 break; case 1: - zbx_snprintf(ip, sizeof(ip), "%x:%x:%x:%x:%x:%x:%x:%x", - j[0], j[1], j[2], j[3], j[4], j[5], - (i & 0xffff0000) >> 16, (i & 0x0000ffff)); - collapse_ipv6(ip, sizeof(ip)); + j[7] = i; + ip6_dig2str(j, ip, sizeof(ip)); break; } #endif - - zabbix_log(LOG_LEVEL_DEBUG, "%s() IP:'%s'", __function_name, ip); + zabbix_log(LOG_LEVEL_DEBUG, "%s() ip:'%s'", __function_name, ip); alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(ip, dns, sizeof(dns)); @@ -661,7 +603,33 @@ static void process_rule(DB_DRULE *drule) proxy_update_host(drule, ip, dns, host_status, now); DBcommit(); + + } +next: + if (NULL != dash) + *dash = '-'; + else if (NULL != slash) + *slash = '/'; + + switch (invalid_range) + { + case 1: + zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": wrong format of IP range \"%s\"", + drule->name, start); + break; + case 2: + zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": encountered IP range \"%s\"," + " but IPv6 support not compiled in", drule->name, start); + break; + } + + if (NULL != comma) + { + *comma = ','; + start = comma + 1; } + else + break; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); @@ -860,8 +828,6 @@ static int get_minnextcheck(int now) * * * Purpose: periodically try to find new hosts and services * * * - * Author: Alexei Vladishev * - * * * Comments: executes once per 30 seconds (hardcoded) * * * ******************************************************************************/ |