diff options
author | Thomas Guyot-Sionnest <dermoth@users.sourceforge.net> | 2007-11-10 21:22:58 +0000 |
---|---|---|
committer | Thomas Guyot-Sionnest <dermoth@users.sourceforge.net> | 2007-11-10 21:22:58 +0000 |
commit | 6ea43dd18e4f10a30ece7aa824547b5e3d6658d4 (patch) | |
tree | d0ec2c8b7f5cf2f64a8336c5aa2b4abcd9ad0737 | |
parent | a22c1454b6ff2a943a69d9985651469b2631f635 (diff) | |
download | monitoring-plugins-6ea43dd18e4f10a30ece7aa824547b5e3d6658d4.tar.gz |
More cleanups, some fixes
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/branches/dermoth_ntp_rework@1824 f882894a-f735-0410-b71e-b25c423dba1c
-rw-r--r-- | plugins/check_ntpd.c | 90 |
1 files changed, 7 insertions, 83 deletions
diff --git a/plugins/check_ntpd.c b/plugins/check_ntpd.c index 61c678c0..2ac2a553 100644 --- a/plugins/check_ntpd.c +++ b/plugins/check_ntpd.c | |||
@@ -68,21 +68,6 @@ void print_usage (void); | |||
68 | /* max size of control message data */ | 68 | /* max size of control message data */ |
69 | #define MAX_CM_SIZE 468 | 69 | #define MAX_CM_SIZE 468 |
70 | 70 | ||
71 | /* this structure holds everything in an ntp request/response as per rfc1305 */ | ||
72 | typedef struct { | ||
73 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | ||
74 | uint8_t stratum; /* clock stratum */ | ||
75 | int8_t poll; /* polling interval */ | ||
76 | int8_t precision; /* precision of the local clock */ | ||
77 | int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */ | ||
78 | uint32_t rtdisp; /* like above, but for max err to primary src */ | ||
79 | uint32_t refid; /* ref clock identifier */ | ||
80 | uint64_t refts; /* reference timestamp. local time local clock */ | ||
81 | uint64_t origts; /* time at which request departed client */ | ||
82 | uint64_t rxts; /* time at which request arrived at server */ | ||
83 | uint64_t txts; /* time at which request departed server */ | ||
84 | } ntp_message; | ||
85 | |||
86 | /* this structure holds everything in an ntp control message as per rfc1305 */ | 71 | /* this structure holds everything in an ntp control message as per rfc1305 */ |
87 | typedef struct { | 72 | typedef struct { |
88 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | 73 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ |
@@ -138,57 +123,6 @@ typedef struct { | |||
138 | #define PEER_INCLUDED 0x04 | 123 | #define PEER_INCLUDED 0x04 |
139 | #define PEER_SYNCSOURCE 0x06 | 124 | #define PEER_SYNCSOURCE 0x06 |
140 | 125 | ||
141 | /** | ||
142 | ** a note about the 32-bit "fixed point" numbers: | ||
143 | ** | ||
144 | they are divided into halves, each being a 16-bit int in network byte order: | ||
145 | - the first 16 bits are an int on the left side of a decimal point. | ||
146 | - the second 16 bits represent a fraction n/(2^16) | ||
147 | likewise for the 64-bit "fixed point" numbers with everything doubled :) | ||
148 | **/ | ||
149 | |||
150 | /* macros to access the left/right 16 bits of a 32-bit ntp "fixed point" | ||
151 | number. note that these can be used as lvalues too */ | ||
152 | #define L16(x) (((uint16_t*)&x)[0]) | ||
153 | #define R16(x) (((uint16_t*)&x)[1]) | ||
154 | /* macros to access the left/right 32 bits of a 64-bit ntp "fixed point" | ||
155 | number. these too can be used as lvalues */ | ||
156 | #define L32(x) (((uint32_t*)&x)[0]) | ||
157 | #define R32(x) (((uint32_t*)&x)[1]) | ||
158 | |||
159 | /* ntp wants seconds since 1/1/00, epoch is 1/1/70. this is the difference */ | ||
160 | #define EPOCHDIFF 0x83aa7e80UL | ||
161 | |||
162 | /* extract a 32-bit ntp fixed point number into a double */ | ||
163 | #define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x))/65536.0) | ||
164 | |||
165 | /* likewise for a 64-bit ntp fp number */ | ||
166 | #define NTP64asDOUBLE(n) (double)(((uint64_t)n)?\ | ||
167 | (ntohl(L32(n))-EPOCHDIFF) + \ | ||
168 | (.00000001*(0.5+(double)(ntohl(R32(n))/42.94967296))):\ | ||
169 | 0) | ||
170 | |||
171 | /* convert a struct timeval to a double */ | ||
172 | #define TVasDOUBLE(x) (double)(x.tv_sec+(0.000001*x.tv_usec)) | ||
173 | |||
174 | /* convert an ntp 64-bit fp number to a struct timeval */ | ||
175 | #define NTP64toTV(n,t) \ | ||
176 | do{ if(!n) t.tv_sec = t.tv_usec = 0; \ | ||
177 | else { \ | ||
178 | t.tv_sec=ntohl(L32(n))-EPOCHDIFF; \ | ||
179 | t.tv_usec=(int)(0.5+(double)(ntohl(R32(n))/4294.967296)); \ | ||
180 | } \ | ||
181 | }while(0) | ||
182 | |||
183 | /* convert a struct timeval to an ntp 64-bit fp number */ | ||
184 | #define TVtoNTP64(t,n) \ | ||
185 | do{ if(!t.tv_usec && !t.tv_sec) n=0x0UL; \ | ||
186 | else { \ | ||
187 | L32(n)=htonl(t.tv_sec + EPOCHDIFF); \ | ||
188 | R32(n)=htonl((uint64_t)((4294.967296*t.tv_usec)+.5)); \ | ||
189 | } \ | ||
190 | } while(0) | ||
191 | |||
192 | /* NTP control message header is 12 bytes, plus any data in the data | 126 | /* NTP control message header is 12 bytes, plus any data in the data |
193 | * field, plus null padding to the nearest 32-bit boundary per rfc. | 127 | * field, plus null padding to the nearest 32-bit boundary per rfc. |
194 | */ | 128 | */ |
@@ -201,16 +135,6 @@ typedef struct { | |||
201 | printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\ | 135 | printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\ |
202 | }while(0); | 136 | }while(0); |
203 | 137 | ||
204 | /* calculate the offset of the local clock */ | ||
205 | static inline double calc_offset(const ntp_message *m, const struct timeval *t){ | ||
206 | double client_tx, peer_rx, peer_tx, client_rx; | ||
207 | client_tx = NTP64asDOUBLE(m->origts); | ||
208 | peer_rx = NTP64asDOUBLE(m->rxts); | ||
209 | peer_tx = NTP64asDOUBLE(m->txts); | ||
210 | client_rx=TVasDOUBLE((*t)); | ||
211 | return (.5*((peer_tx-client_rx)+(peer_rx-client_tx))); | ||
212 | } | ||
213 | |||
214 | void print_ntp_control_message(const ntp_control_message *p){ | 138 | void print_ntp_control_message(const ntp_control_message *p){ |
215 | int i=0, numpeers=0; | 139 | int i=0, numpeers=0; |
216 | const ntp_assoc_status_pair *peer=NULL; | 140 | const ntp_assoc_status_pair *peer=NULL; |
@@ -246,8 +170,8 @@ void print_ntp_control_message(const ntp_control_message *p){ | |||
246 | } | 170 | } |
247 | } | 171 | } |
248 | } | 172 | } |
249 | char * | 173 | |
250 | extract_value(const char *varlist, const char *name){ | 174 | char *extract_value(const char *varlist, const char *name){ |
251 | char *tmpvarlist=NULL, *tmpkey=NULL, *value=NULL; | 175 | char *tmpvarlist=NULL, *tmpkey=NULL, *value=NULL; |
252 | int last=0; | 176 | int last=0; |
253 | 177 | ||
@@ -291,7 +215,8 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji | |||
291 | *jitter = *stratum = -1; | 215 | *jitter = *stratum = -1; |
292 | 216 | ||
293 | /* Long-winded explanation: | 217 | /* Long-winded explanation: |
294 | * Getting the offset, jitter and stratum requires a number of steps: | 218 | * Getting the sync peer offset, jitter and stratum requires a number of |
219 | * steps: | ||
295 | * 1) Send a READSTAT request. | 220 | * 1) Send a READSTAT request. |
296 | * 2) Interpret the READSTAT reply | 221 | * 2) Interpret the READSTAT reply |
297 | * a) The data section contains a list of peer identifiers (16 bits) | 222 | * a) The data section contains a list of peer identifiers (16 bits) |
@@ -378,10 +303,11 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji | |||
378 | if(req.op&REM_ERROR && strstr(getvar, "jitter")) { | 303 | if(req.op&REM_ERROR && strstr(getvar, "jitter")) { |
379 | if(verbose) printf("The 'jitter' command failed (old ntp server?)\nRestarting with 'dispersion'...\n"); | 304 | if(verbose) printf("The 'jitter' command failed (old ntp server?)\nRestarting with 'dispersion'...\n"); |
380 | getvar = "stratum,offset,dispersion"; | 305 | getvar = "stratum,offset,dispersion"; |
306 | i--; | ||
381 | continue; | 307 | continue; |
382 | } | 308 | } |
383 | 309 | ||
384 | if(verbose) | 310 | if(verbose > 1) |
385 | printf("Server responded: >>>%s<<<\n", req.data); | 311 | printf("Server responded: >>>%s<<<\n", req.data); |
386 | 312 | ||
387 | /* get the offset */ | 313 | /* get the offset */ |
@@ -389,7 +315,6 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji | |||
389 | printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc)); | 315 | printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc)); |
390 | 316 | ||
391 | value = extract_value(req.data, "offset"); | 317 | value = extract_value(req.data, "offset"); |
392 | //value = extract_value(req.data, "jitter="); | ||
393 | if(value != NULL) | 318 | if(value != NULL) |
394 | *offset = strtod(value, &nptr) / 1000; | 319 | *offset = strtod(value, &nptr) / 1000; |
395 | if(value == NULL || value==nptr){ | 320 | if(value == NULL || value==nptr){ |
@@ -406,8 +331,7 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji | |||
406 | if(verbose) { | 331 | if(verbose) { |
407 | printf("parsing jitter from peer %.2x: ", ntohs(peers[i].assoc)); | 332 | printf("parsing jitter from peer %.2x: ", ntohs(peers[i].assoc)); |
408 | } | 333 | } |
409 | //*value = extract_value(req.data, strstr(getvar, "dispersion") ? "dispersion=" : "jitter="); | 334 | value = extract_value(req.data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter"); |
410 | value = extract_value(req.data, "jitter"); | ||
411 | if(value != NULL) | 335 | if(value != NULL) |
412 | *jitter = strtod(value, &nptr); | 336 | *jitter = strtod(value, &nptr); |
413 | if(value == NULL || value==nptr){ | 337 | if(value == NULL || value==nptr){ |