Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--include/zbxicmpping.h8
-rw-r--r--src/libs/zbxicmpping/icmpping.c61
3 files changed, 53 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index c2bb482bb59..fe8393ff13e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -21,6 +21,7 @@ New features:
A.F....... [ZBX-1357] updated American English, French, Hungarian, Italian, Japanese, Russian, Slovak and Turkish translations; thanks to Zabbix translators (Richlv)
Bug fixes:
+.......PS. [ZBX-7576] when pinging a broadcast address ignore responses from other addresses (wiper)
..F....... [ZBX-7632] allow to add favourite graph from disable host (Eduard)
..F....... [ZBX-7634] removed sid from trigger URL in Monitoring->Triggers (Oleg)
...GI..PS. [ZBX-5526] removed checking for PosgreSQL server version and disabled nonstandard use of escape strings in order to support versions newer than 8.1 (igors)
diff --git a/include/zbxicmpping.h b/include/zbxicmpping.h
index 6358962dde9..9e4ba3bf028 100644
--- a/include/zbxicmpping.h
+++ b/include/zbxicmpping.h
@@ -23,8 +23,12 @@
typedef struct
{
char *addr;
- double min, avg, max;
- int rcv, cnt;
+ double min;
+ double avg;
+ double max;
+ int rcv;
+ int cnt;
+ char *status; /* array of individual response statuses: 1 - valid, 0 - timeout */
}
ZBX_FPING_HOST;
diff --git a/src/libs/zbxicmpping/icmpping.c b/src/libs/zbxicmpping/icmpping.c
index 27c1af13a9d..e8b07ff771c 100644
--- a/src/libs/zbxicmpping/icmpping.c
+++ b/src/libs/zbxicmpping/icmpping.c
@@ -78,12 +78,12 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int i
const char *__function_name = "process_ping";
FILE *f;
- char *c, *c2, params[64];
+ char *c, params[64];
char filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN];
size_t offset;
ZBX_FPING_HOST *host;
double sec;
- int i, ret = NOTSUPPORTED;
+ int i, ret = NOTSUPPORTED, index;
#ifdef HAVE_IPV6
int family;
@@ -137,7 +137,7 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int i
fping_existence |= FPING6_EXISTS;
#endif /* HAVE_IPV6 */
- offset = zbx_snprintf(params, sizeof(params), "-q -C%d", count);
+ offset = zbx_snprintf(params, sizeof(params), "-C%d", count);
if (0 != interval)
offset += zbx_snprintf(params + offset, sizeof(params) - offset, " -p%d", interval);
if (0 != size)
@@ -258,6 +258,12 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int i
}
else
{
+ for (i = 0; i < hosts_count; i++)
+ {
+ hosts[i].status = zbx_malloc(NULL, count);
+ memset(hosts[i].status, 0, count);
+ }
+
do
{
zbx_rtrim(tmp, "\n");
@@ -291,33 +297,58 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int i
c += 3;
- do
+ /* The were two issues with processing only the fping's final status line: */
+ /* 1) pinging broadcast addresses could have resulted in responses from */
+ /* different hosts, which were counted as the target host responses; */
+ /* 2) there is a bug in fping (v3.8 at least) where pinging broadcast */
+ /* address will result in no individual responses, but the final */
+ /* status line might contain a bogus value. */
+ /* Because of the above issues we must monitor the individual responses */
+ /* and mark the valid ones. */
+ if ('[' == *c)
{
- if (NULL != (c2 = strchr(c, ' ')))
- *c2 = '\0';
+ /* Fping appends response source address in format '[<- 10.3.0.10]' */
+ /* if it does not match the target address. Ignore such responses. */
+ if (NULL != strstr(c + 1, "[<-"))
+ continue;
+
+ /* get the index of individual ping response */
+ index = atoi(c + 1);
+
+ if (0 > index || index >= count)
+ continue;
+
+ host->status[index] = 1;
+
+ continue;
+ }
- if (0 != strcmp(c, "-"))
+ /* process status line for a host */
+ index = 0;
+ do
+ {
+ if (1 == host->status[index])
{
sec = atof(c) / 1000; /* convert ms to seconds */
- if (host->rcv == 0 || host->min > sec)
+ if (0 == host->rcv || host->min > sec)
host->min = sec;
- if (host->rcv == 0 || host->max < sec)
+ if (0 == host->rcv || host->max < sec)
host->max = sec;
host->avg = (host->avg * host->rcv + sec) / (host->rcv + 1);
host->rcv++;
}
-
- host->cnt++;
-
- if (NULL != c2)
- *c2++ = ' ';
}
- while (NULL != (c = c2));
+ while (++index < count && NULL != (c = strchr(c + 1, ' ')));
+
+ host->cnt = count;
ret = SUCCEED;
}
while (NULL != fgets(tmp, sizeof(tmp), f));
+
+ for (i = 0; i < hosts_count; i++)
+ zbx_free(hosts[i].status);
}
pclose(f);