summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Guyot-Sionnest <dermoth@users.sourceforge.net>2007-11-10 21:22:58 +0000
committerThomas Guyot-Sionnest <dermoth@users.sourceforge.net>2007-11-10 21:22:58 +0000
commit6ea43dd18e4f10a30ece7aa824547b5e3d6658d4 (patch)
treed0ec2c8b7f5cf2f64a8336c5aa2b4abcd9ad0737
parenta22c1454b6ff2a943a69d9985651469b2631f635 (diff)
downloadmonitoring-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.c90
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 */
72typedef 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 */
87typedef struct { 72typedef 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 */
205static 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
214void print_ntp_control_message(const ntp_control_message *p){ 138void 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}
249char * 173
250extract_value(const char *varlist, const char *name){ 174char *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){