diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2013-06-30 16:05:48 +0200 |
---|---|---|
committer | Holger Weiss <holger@zedat.fu-berlin.de> | 2013-06-30 16:05:48 +0200 |
commit | 9dad98f33efe2519b67c76dbc4ce00e4201c8009 (patch) | |
tree | 1e1634dcb0d409343258c7fb352debf6209c0ebf | |
parent | 1eb879e3feefac3221efc636be50effb5ac5547d (diff) | |
download | monitoring-plugins-9dad98f33efe2519b67c76dbc4ce00e4201c8009.tar.gz |
check_ntp_peer: Verify type of response packets
The check_ntp_peer plugin now ignores response packets with an
unexpected "Operation Code" and/or "Sequence" number (cf. RFC 1305,
Appendix B). This fixes an issue where the check_ntp_peer requests got
duplicated on their way to the server (due to some network switch bug),
and the server therefore sent multiple responses per request.
Thanks to Marc Haber for reporting the issue.
-rw-r--r-- | plugins/check_ntp_peer.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index b59c056d..76152e17 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c | |||
@@ -241,15 +241,19 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji | |||
241 | DBG(printf("sending READSTAT request")); | 241 | DBG(printf("sending READSTAT request")); |
242 | write(conn, &req, SIZEOF_NTPCM(req)); | 242 | write(conn, &req, SIZEOF_NTPCM(req)); |
243 | DBG(print_ntp_control_message(&req)); | 243 | DBG(print_ntp_control_message(&req)); |
244 | /* Attempt to read the largest size packet possible */ | 244 | |
245 | req.count=htons(MAX_CM_SIZE); | 245 | do { |
246 | DBG(printf("recieving READSTAT response")) | 246 | /* Attempt to read the largest size packet possible */ |
247 | if(read(conn, &req, SIZEOF_NTPCM(req)) == -1) | 247 | req.count=htons(MAX_CM_SIZE); |
248 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); | 248 | DBG(printf("recieving READSTAT response")) |
249 | DBG(print_ntp_control_message(&req)); | 249 | if(read(conn, &req, SIZEOF_NTPCM(req)) == -1) |
250 | /* discard obviously invalid packets */ | 250 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); |
251 | if (ntohs(req.count) > MAX_CM_SIZE) | 251 | DBG(print_ntp_control_message(&req)); |
252 | die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); | 252 | /* discard obviously invalid packets */ |
253 | if (ntohs(req.count) > MAX_CM_SIZE) | ||
254 | die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); | ||
255 | } while (!(req.op&OP_READSTAT && ntohs(req.seq) == 1)); | ||
256 | |||
253 | if (LI(req.flags) == LI_ALARM) li_alarm = 1; | 257 | if (LI(req.flags) == LI_ALARM) li_alarm = 1; |
254 | /* Each peer identifier is 4 bytes in the data section, which | 258 | /* Each peer identifier is 4 bytes in the data section, which |
255 | * we represent as a ntp_assoc_status_pair datatype. | 259 | * we represent as a ntp_assoc_status_pair datatype. |
@@ -312,10 +316,12 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji | |||
312 | write(conn, &req, SIZEOF_NTPCM(req)); | 316 | write(conn, &req, SIZEOF_NTPCM(req)); |
313 | DBG(print_ntp_control_message(&req)); | 317 | DBG(print_ntp_control_message(&req)); |
314 | 318 | ||
315 | req.count = htons(MAX_CM_SIZE); | 319 | do { |
316 | DBG(printf("receiving READVAR response...\n")); | 320 | req.count = htons(MAX_CM_SIZE); |
317 | read(conn, &req, SIZEOF_NTPCM(req)); | 321 | DBG(printf("receiving READVAR response...\n")); |
318 | DBG(print_ntp_control_message(&req)); | 322 | read(conn, &req, SIZEOF_NTPCM(req)); |
323 | DBG(print_ntp_control_message(&req)); | ||
324 | } while (!(req.op&OP_READVAR && ntohs(req.seq) == 2)); | ||
319 | 325 | ||
320 | if(!(req.op&REM_ERROR)) | 326 | if(!(req.op&REM_ERROR)) |
321 | xasprintf(&data, "%s%s", data, req.data); | 327 | xasprintf(&data, "%s%s", data, req.data); |