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){ |
