No subject
Fri Jan 15 15:06:42 UTC 2010
--- 2a00:1450:8001::1234 ping statistics ---
3 packets transmitted, 0 received, +2 errors, 100% packet loss, time 2003ms
when you try to use check_ping v1991 (nagios-plugins 1.4.12) you get
% ./check_ping -H 2a00:1450:8001::1234 -w 5000,100% -c 5000,100% -p 1
/bin/ping6 -n -U -w 10 -c 1 2a00:1450:8001::1234
CRITICAL - Could not interpret output from ping command
Now, if you apply the patch ping-sscanf.diff from
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=514588
you will get the correct answer:
% ./check_ping -H 2a00:1450:8001::1234 -w 5000,100% -c 5000,100% -p 1
PING CRITICAL - Packet loss = 100%|rta=5000.000000ms;5000.000000;5000.000000;0.000000 pl=100%;100;100;0
(note that in our real world case we actually had a flaky network
and the IPv6 address was right, but the output format was the same,
only we did not have 100% lost but less etc -- but we couldn't get
that data from check_ping plugin as it couldn't interpret the output).
The problematic code lies in check_ping.c around line 455:
455 if(sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss",&pl)==1 ||
456 sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss", &pl) == 1 ||
457 sscanf(buf,"%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss", &pl) == 1 ||
458 sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% packet loss",&pl)==1 ||
459 sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% loss, time",&pl)==1 ||
460 sscanf(buf,"%*d packets transmitted, %*d received, %d%% loss, time", &pl)==1 ||
461 sscanf(buf,"%*d packets transmitted, %*d received, %d%% packet loss, time", &pl)==1 ||
462 sscanf(buf,"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss", &pl) == 1 ||
463 sscanf(buf,"%*d packets transmitted %*d received, +%*d errors, %d%% packet loss", &pl) == 1
As you can see, our summary line from ping6
"3 packets transmitted, 0 received, +2 errors, 100% packet loss, time 2003ms"
should have matched at line 462, at:
sscanf(buf,"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss", &pl) == 1
as that is the only line with string that would match, right ?
unfortunately, it will actually match at line 460, at
sscanf(buf,"%*d packets transmitted, %*d received, %d%% loss, time", &pl)==1
which is completely wrong, as that is not our string at all!
Careful reading of sscanf(3) reveals the problem -- the sscanf(3)
does not at all work like perl or similar languages. The return value
of sscanf(3) is instead number of arguments matched, and *not* the
claim that the *whole* string matched. That is, any and all text
after last "%d" is completely ignored (that is, no matter if they
match or not, the sscanf will return the same value - number of %
arguments matched so far: 1 in our case).
So line 460 might as well be written as:
sscanf(buf,"%*d packets transmitted, %*d received, %d", &pl)==1
which shows more clearly why it breaks.
Now the patch might look like it changes a lot but that is only
because diff is line oriented -- we're actually just adding "%n" at
the end of each line (and &match variable to store it) to be sure
*the whole* line matched, not just a part up to last "%d".
I hope this gives you enough info to check and validate the patch.
Thanks,
Matija Nalis
More information about the Pkg-nagios-devel
mailing list