diff options
Diffstat (limited to 'plugins/check_ntp.c')
| -rw-r--r-- | plugins/check_ntp.c | 756 |
1 files changed, 401 insertions, 355 deletions
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c index d33f8786..b22cc3c1 100644 --- a/plugins/check_ntp.c +++ b/plugins/check_ntp.c | |||
| @@ -1,34 +1,34 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring check_ntp plugin | 3 | * Monitoring check_ntp plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 2006 Sean Finney <seanius@seanius.net> | 6 | * Copyright (c) 2006 Sean Finney <seanius@seanius.net> |
| 7 | * Copyright (c) 2006-2024 Monitoring Plugins Development Team | 7 | * Copyright (c) 2006-2024 Monitoring Plugins Development Team |
| 8 | * | 8 | * |
| 9 | * Description: | 9 | * Description: |
| 10 | * | 10 | * |
| 11 | * This file contains the check_ntp plugin | 11 | * This file contains the check_ntp plugin |
| 12 | * | 12 | * |
| 13 | * This plugin to check ntp servers independent of any commandline | 13 | * This plugin to check ntp servers independent of any commandline |
| 14 | * programs or external libraries. | 14 | * programs or external libraries. |
| 15 | * | 15 | * |
| 16 | * | 16 | * |
| 17 | * This program is free software: you can redistribute it and/or modify | 17 | * This program is free software: you can redistribute it and/or modify |
| 18 | * it under the terms of the GNU General Public License as published by | 18 | * it under the terms of the GNU General Public License as published by |
| 19 | * the Free Software Foundation, either version 3 of the License, or | 19 | * the Free Software Foundation, either version 3 of the License, or |
| 20 | * (at your option) any later version. | 20 | * (at your option) any later version. |
| 21 | * | 21 | * |
| 22 | * This program is distributed in the hope that it will be useful, | 22 | * This program is distributed in the hope that it will be useful, |
| 23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 25 | * GNU General Public License for more details. | 25 | * GNU General Public License for more details. |
| 26 | * | 26 | * |
| 27 | * You should have received a copy of the GNU General Public License | 27 | * You should have received a copy of the GNU General Public License |
| 28 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 28 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 29 | * | 29 | * |
| 30 | * | 30 | * |
| 31 | *****************************************************************************/ | 31 | *****************************************************************************/ |
| 32 | 32 | ||
| 33 | const char *progname = "check_ntp"; | 33 | const char *progname = "check_ntp"; |
| 34 | const char *copyright = "2006-2024"; | 34 | const char *copyright = "2006-2024"; |
| @@ -38,24 +38,24 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 38 | #include "netutils.h" | 38 | #include "netutils.h" |
| 39 | #include "utils.h" | 39 | #include "utils.h" |
| 40 | 40 | ||
| 41 | static char *server_address=NULL; | 41 | static char *server_address = NULL; |
| 42 | static int verbose=0; | 42 | static int verbose = 0; |
| 43 | static bool do_offset = false; | 43 | static bool do_offset = false; |
| 44 | static char *owarn="60"; | 44 | static char *owarn = "60"; |
| 45 | static char *ocrit="120"; | 45 | static char *ocrit = "120"; |
| 46 | static bool do_jitter = false; | 46 | static bool do_jitter = false; |
| 47 | static char *jwarn="5000"; | 47 | static char *jwarn = "5000"; |
| 48 | static char *jcrit="10000"; | 48 | static char *jcrit = "10000"; |
| 49 | 49 | ||
| 50 | static int process_arguments (int /*argc*/, char ** /*argv*/); | 50 | static int process_arguments(int /*argc*/, char ** /*argv*/); |
| 51 | static thresholds *offset_thresholds = NULL; | 51 | static thresholds *offset_thresholds = NULL; |
| 52 | static thresholds *jitter_thresholds = NULL; | 52 | static thresholds *jitter_thresholds = NULL; |
| 53 | static void print_help (void); | 53 | static void print_help(void); |
| 54 | void print_usage (void); | 54 | void print_usage(void); |
| 55 | 55 | ||
| 56 | /* number of times to perform each request to get a good average. */ | 56 | /* number of times to perform each request to get a good average. */ |
| 57 | #ifndef AVG_NUM | 57 | #ifndef AVG_NUM |
| 58 | #define AVG_NUM 4 | 58 | # define AVG_NUM 4 |
| 59 | #endif | 59 | #endif |
| 60 | 60 | ||
| 61 | /* max size of control message data */ | 61 | /* max size of control message data */ |
| @@ -63,17 +63,17 @@ void print_usage (void); | |||
| 63 | 63 | ||
| 64 | /* this structure holds everything in an ntp request/response as per rfc1305 */ | 64 | /* this structure holds everything in an ntp request/response as per rfc1305 */ |
| 65 | typedef struct { | 65 | typedef struct { |
| 66 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | 66 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ |
| 67 | uint8_t stratum; /* clock stratum */ | 67 | uint8_t stratum; /* clock stratum */ |
| 68 | int8_t poll; /* polling interval */ | 68 | int8_t poll; /* polling interval */ |
| 69 | int8_t precision; /* precision of the local clock */ | 69 | int8_t precision; /* precision of the local clock */ |
| 70 | int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */ | 70 | int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */ |
| 71 | uint32_t rtdisp; /* like above, but for max err to primary src */ | 71 | uint32_t rtdisp; /* like above, but for max err to primary src */ |
| 72 | uint32_t refid; /* ref clock identifier */ | 72 | uint32_t refid; /* ref clock identifier */ |
| 73 | uint64_t refts; /* reference timestamp. local time local clock */ | 73 | uint64_t refts; /* reference timestamp. local time local clock */ |
| 74 | uint64_t origts; /* time at which request departed client */ | 74 | uint64_t origts; /* time at which request departed client */ |
| 75 | uint64_t rxts; /* time at which request arrived at server */ | 75 | uint64_t rxts; /* time at which request arrived at server */ |
| 76 | uint64_t txts; /* time at which request departed server */ | 76 | uint64_t txts; /* time at which request departed server */ |
| 77 | } ntp_message; | 77 | } ntp_message; |
| 78 | 78 | ||
| 79 | /* this structure holds data about results from querying offset from a peer */ | 79 | /* this structure holds data about results from querying offset from a peer */ |
| @@ -84,20 +84,20 @@ typedef struct { | |||
| 84 | double rtdelay; /* converted from the ntp_message */ | 84 | double rtdelay; /* converted from the ntp_message */ |
| 85 | double rtdisp; /* converted from the ntp_message */ | 85 | double rtdisp; /* converted from the ntp_message */ |
| 86 | double offset[AVG_NUM]; /* offsets from each response */ | 86 | double offset[AVG_NUM]; /* offsets from each response */ |
| 87 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | 87 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ |
| 88 | } ntp_server_results; | 88 | } ntp_server_results; |
| 89 | 89 | ||
| 90 | /* this structure holds everything in an ntp control message as per rfc1305 */ | 90 | /* this structure holds everything in an ntp control message as per rfc1305 */ |
| 91 | typedef struct { | 91 | typedef struct { |
| 92 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | 92 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ |
| 93 | uint8_t op; /* R,E,M bits and Opcode */ | 93 | uint8_t op; /* R,E,M bits and Opcode */ |
| 94 | uint16_t seq; /* Packet sequence */ | 94 | uint16_t seq; /* Packet sequence */ |
| 95 | uint16_t status; /* Clock status */ | 95 | uint16_t status; /* Clock status */ |
| 96 | uint16_t assoc; /* Association */ | 96 | uint16_t assoc; /* Association */ |
| 97 | uint16_t offset; /* Similar to TCP sequence # */ | 97 | uint16_t offset; /* Similar to TCP sequence # */ |
| 98 | uint16_t count; /* # bytes of data */ | 98 | uint16_t count; /* # bytes of data */ |
| 99 | char data[MAX_CM_SIZE]; /* ASCII data of the request */ | 99 | char data[MAX_CM_SIZE]; /* ASCII data of the request */ |
| 100 | /* NB: not necessarily NULL terminated! */ | 100 | /* NB: not necessarily NULL terminated! */ |
| 101 | } ntp_control_message; | 101 | } ntp_control_message; |
| 102 | 102 | ||
| 103 | /* this is an association/status-word pair found in control packet responses */ | 103 | /* this is an association/status-word pair found in control packet responses */ |
| @@ -108,38 +108,50 @@ typedef struct { | |||
| 108 | 108 | ||
| 109 | /* bits 1,2 are the leap indicator */ | 109 | /* bits 1,2 are the leap indicator */ |
| 110 | #define LI_MASK 0xc0 | 110 | #define LI_MASK 0xc0 |
| 111 | #define LI(x) ((x&LI_MASK)>>6) | 111 | #define LI(x) ((x & LI_MASK) >> 6) |
| 112 | #define LI_SET(x,y) do{ x |= ((y<<6)&LI_MASK); }while(0) | 112 | #define LI_SET(x, y) \ |
| 113 | do { \ | ||
| 114 | x |= ((y << 6) & LI_MASK); \ | ||
| 115 | } while (0) | ||
| 113 | /* and these are the values of the leap indicator */ | 116 | /* and these are the values of the leap indicator */ |
| 114 | #define LI_NOWARNING 0x00 | 117 | #define LI_NOWARNING 0x00 |
| 115 | #define LI_EXTRASEC 0x01 | 118 | #define LI_EXTRASEC 0x01 |
| 116 | #define LI_MISSINGSEC 0x02 | 119 | #define LI_MISSINGSEC 0x02 |
| 117 | #define LI_ALARM 0x03 | 120 | #define LI_ALARM 0x03 |
| 118 | /* bits 3,4,5 are the ntp version */ | 121 | /* bits 3,4,5 are the ntp version */ |
| 119 | #define VN_MASK 0x38 | 122 | #define VN_MASK 0x38 |
| 120 | #define VN(x) ((x&VN_MASK)>>3) | 123 | #define VN(x) ((x & VN_MASK) >> 3) |
| 121 | #define VN_SET(x,y) do{ x |= ((y<<3)&VN_MASK); }while(0) | 124 | #define VN_SET(x, y) \ |
| 125 | do { \ | ||
| 126 | x |= ((y << 3) & VN_MASK); \ | ||
| 127 | } while (0) | ||
| 122 | #define VN_RESERVED 0x02 | 128 | #define VN_RESERVED 0x02 |
| 123 | /* bits 6,7,8 are the ntp mode */ | 129 | /* bits 6,7,8 are the ntp mode */ |
| 124 | #define MODE_MASK 0x07 | 130 | #define MODE_MASK 0x07 |
| 125 | #define MODE(x) (x&MODE_MASK) | 131 | #define MODE(x) (x & MODE_MASK) |
| 126 | #define MODE_SET(x,y) do{ x |= (y&MODE_MASK); }while(0) | 132 | #define MODE_SET(x, y) \ |
| 133 | do { \ | ||
| 134 | x |= (y & MODE_MASK); \ | ||
| 135 | } while (0) | ||
| 127 | /* here are some values */ | 136 | /* here are some values */ |
| 128 | #define MODE_CLIENT 0x03 | 137 | #define MODE_CLIENT 0x03 |
| 129 | #define MODE_CONTROLMSG 0x06 | 138 | #define MODE_CONTROLMSG 0x06 |
| 130 | /* In control message, bits 8-10 are R,E,M bits */ | 139 | /* In control message, bits 8-10 are R,E,M bits */ |
| 131 | #define REM_MASK 0xe0 | 140 | #define REM_MASK 0xe0 |
| 132 | #define REM_RESP 0x80 | 141 | #define REM_RESP 0x80 |
| 133 | #define REM_ERROR 0x40 | 142 | #define REM_ERROR 0x40 |
| 134 | #define REM_MORE 0x20 | 143 | #define REM_MORE 0x20 |
| 135 | /* In control message, bits 11 - 15 are opcode */ | 144 | /* In control message, bits 11 - 15 are opcode */ |
| 136 | #define OP_MASK 0x1f | 145 | #define OP_MASK 0x1f |
| 137 | #define OP_SET(x,y) do{ x |= (y&OP_MASK); }while(0) | 146 | #define OP_SET(x, y) \ |
| 147 | do { \ | ||
| 148 | x |= (y & OP_MASK); \ | ||
| 149 | } while (0) | ||
| 138 | #define OP_READSTAT 0x01 | 150 | #define OP_READSTAT 0x01 |
| 139 | #define OP_READVAR 0x02 | 151 | #define OP_READVAR 0x02 |
| 140 | /* In peer status bytes, bits 6,7,8 determine clock selection status */ | 152 | /* In peer status bytes, bits 6,7,8 determine clock selection status */ |
| 141 | #define PEER_SEL(x) ((ntohs(x)>>8)&0x07) | 153 | #define PEER_SEL(x) ((ntohs(x) >> 8) & 0x07) |
| 142 | #define PEER_INCLUDED 0x04 | 154 | #define PEER_INCLUDED 0x04 |
| 143 | #define PEER_SYNCSOURCE 0x06 | 155 | #define PEER_SYNCSOURCE 0x06 |
| 144 | 156 | ||
| 145 | /** | 157 | /** |
| @@ -153,82 +165,92 @@ typedef struct { | |||
| 153 | 165 | ||
| 154 | /* macros to access the left/right 16 bits of a 32-bit ntp "fixed point" | 166 | /* macros to access the left/right 16 bits of a 32-bit ntp "fixed point" |
| 155 | number. note that these can be used as lvalues too */ | 167 | number. note that these can be used as lvalues too */ |
| 156 | #define L16(x) (((uint16_t*)&x)[0]) | 168 | #define L16(x) (((uint16_t *)&x)[0]) |
| 157 | #define R16(x) (((uint16_t*)&x)[1]) | 169 | #define R16(x) (((uint16_t *)&x)[1]) |
| 158 | /* macros to access the left/right 32 bits of a 64-bit ntp "fixed point" | 170 | /* macros to access the left/right 32 bits of a 64-bit ntp "fixed point" |
| 159 | number. these too can be used as lvalues */ | 171 | number. these too can be used as lvalues */ |
| 160 | #define L32(x) (((uint32_t*)&x)[0]) | 172 | #define L32(x) (((uint32_t *)&x)[0]) |
| 161 | #define R32(x) (((uint32_t*)&x)[1]) | 173 | #define R32(x) (((uint32_t *)&x)[1]) |
| 162 | 174 | ||
| 163 | /* ntp wants seconds since 1/1/00, epoch is 1/1/70. this is the difference */ | 175 | /* ntp wants seconds since 1/1/00, epoch is 1/1/70. this is the difference */ |
| 164 | #define EPOCHDIFF 0x83aa7e80UL | 176 | #define EPOCHDIFF 0x83aa7e80UL |
| 165 | 177 | ||
| 166 | /* extract a 32-bit ntp fixed point number into a double */ | 178 | /* extract a 32-bit ntp fixed point number into a double */ |
| 167 | #define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x))/65536.0) | 179 | #define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x)) / 65536.0) |
| 168 | 180 | ||
| 169 | /* likewise for a 64-bit ntp fp number */ | 181 | /* likewise for a 64-bit ntp fp number */ |
| 170 | #define NTP64asDOUBLE(n) (double)(((uint64_t)n)?\ | 182 | #define NTP64asDOUBLE(n) \ |
| 171 | (ntohl(L32(n))-EPOCHDIFF) + \ | 183 | (double)(((uint64_t)n) ? (ntohl(L32(n)) - EPOCHDIFF) + \ |
| 172 | (.00000001*(0.5+(double)(ntohl(R32(n))/42.94967296))):\ | 184 | (.00000001 * (0.5 + (double)(ntohl(R32(n)) / 42.94967296))) \ |
| 173 | 0) | 185 | : 0) |
| 174 | 186 | ||
| 175 | /* convert a struct timeval to a double */ | 187 | /* convert a struct timeval to a double */ |
| 176 | #define TVasDOUBLE(x) (double)(x.tv_sec+(0.000001*x.tv_usec)) | 188 | #define TVasDOUBLE(x) (double)(x.tv_sec + (0.000001 * x.tv_usec)) |
| 177 | 189 | ||
| 178 | /* convert an ntp 64-bit fp number to a struct timeval */ | 190 | /* convert an ntp 64-bit fp number to a struct timeval */ |
| 179 | #define NTP64toTV(n,t) \ | 191 | #define NTP64toTV(n, t) \ |
| 180 | do{ if(!n) t.tv_sec = t.tv_usec = 0; \ | 192 | do { \ |
| 181 | else { \ | 193 | if (!n) \ |
| 182 | t.tv_sec=ntohl(L32(n))-EPOCHDIFF; \ | 194 | t.tv_sec = t.tv_usec = 0; \ |
| 183 | t.tv_usec=(int)(0.5+(double)(ntohl(R32(n))/4294.967296)); \ | 195 | else { \ |
| 184 | } \ | 196 | t.tv_sec = ntohl(L32(n)) - EPOCHDIFF; \ |
| 185 | }while(0) | 197 | t.tv_usec = (int)(0.5 + (double)(ntohl(R32(n)) / 4294.967296)); \ |
| 198 | } \ | ||
| 199 | } while (0) | ||
| 186 | 200 | ||
| 187 | /* convert a struct timeval to an ntp 64-bit fp number */ | 201 | /* convert a struct timeval to an ntp 64-bit fp number */ |
| 188 | #define TVtoNTP64(t,n) \ | 202 | #define TVtoNTP64(t, n) \ |
| 189 | do{ if(!t.tv_usec && !t.tv_sec) n=0x0UL; \ | 203 | do { \ |
| 190 | else { \ | 204 | if (!t.tv_usec && !t.tv_sec) \ |
| 191 | L32(n)=htonl(t.tv_sec + EPOCHDIFF); \ | 205 | n = 0x0UL; \ |
| 192 | R32(n)=htonl((uint64_t)((4294.967296*t.tv_usec)+.5)); \ | 206 | else { \ |
| 193 | } \ | 207 | L32(n) = htonl(t.tv_sec + EPOCHDIFF); \ |
| 194 | } while(0) | 208 | R32(n) = htonl((uint64_t)((4294.967296 * t.tv_usec) + .5)); \ |
| 209 | } \ | ||
| 210 | } while (0) | ||
| 195 | 211 | ||
| 196 | /* NTP control message header is 12 bytes, plus any data in the data | 212 | /* NTP control message header is 12 bytes, plus any data in the data |
| 197 | * field, plus null padding to the nearest 32-bit boundary per rfc. | 213 | * field, plus null padding to the nearest 32-bit boundary per rfc. |
| 198 | */ | 214 | */ |
| 199 | #define SIZEOF_NTPCM(m) (12+ntohs(m.count)+((ntohs(m.count)%4)?4-(ntohs(m.count)%4):0)) | 215 | #define SIZEOF_NTPCM(m) \ |
| 216 | (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0)) | ||
| 200 | 217 | ||
| 201 | /* finally, a little helper or two for debugging: */ | 218 | /* finally, a little helper or two for debugging: */ |
| 202 | #define DBG(x) do{if(verbose>1){ x; }}while(0); | 219 | #define DBG(x) \ |
| 203 | #define PRINTSOCKADDR(x) \ | 220 | do { \ |
| 204 | do{ \ | 221 | if (verbose > 1) { \ |
| 205 | printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\ | 222 | x; \ |
| 206 | }while(0); | 223 | } \ |
| 224 | } while (0); | ||
| 225 | #define PRINTSOCKADDR(x) \ | ||
| 226 | do { \ | ||
| 227 | printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ | ||
| 228 | } while (0); | ||
| 207 | 229 | ||
| 208 | /* calculate the offset of the local clock */ | 230 | /* calculate the offset of the local clock */ |
| 209 | static inline double calc_offset(const ntp_message *m, const struct timeval *t){ | 231 | static inline double calc_offset(const ntp_message *m, const struct timeval *t) { |
| 210 | double client_tx, peer_rx, peer_tx, client_rx; | 232 | double client_tx, peer_rx, peer_tx, client_rx; |
| 211 | client_tx = NTP64asDOUBLE(m->origts); | 233 | client_tx = NTP64asDOUBLE(m->origts); |
| 212 | peer_rx = NTP64asDOUBLE(m->rxts); | 234 | peer_rx = NTP64asDOUBLE(m->rxts); |
| 213 | peer_tx = NTP64asDOUBLE(m->txts); | 235 | peer_tx = NTP64asDOUBLE(m->txts); |
| 214 | client_rx=TVasDOUBLE((*t)); | 236 | client_rx = TVasDOUBLE((*t)); |
| 215 | return (.5*((peer_tx-client_rx)+(peer_rx-client_tx))); | 237 | return (.5 * ((peer_tx - client_rx) + (peer_rx - client_tx))); |
| 216 | } | 238 | } |
| 217 | 239 | ||
| 218 | /* print out a ntp packet in human readable/debuggable format */ | 240 | /* print out a ntp packet in human readable/debuggable format */ |
| 219 | void print_ntp_message(const ntp_message *p){ | 241 | void print_ntp_message(const ntp_message *p) { |
| 220 | struct timeval ref, orig, rx, tx; | 242 | struct timeval ref, orig, rx, tx; |
| 221 | 243 | ||
| 222 | NTP64toTV(p->refts,ref); | 244 | NTP64toTV(p->refts, ref); |
| 223 | NTP64toTV(p->origts,orig); | 245 | NTP64toTV(p->origts, orig); |
| 224 | NTP64toTV(p->rxts,rx); | 246 | NTP64toTV(p->rxts, rx); |
| 225 | NTP64toTV(p->txts,tx); | 247 | NTP64toTV(p->txts, tx); |
| 226 | 248 | ||
| 227 | printf("packet contents:\n"); | 249 | printf("packet contents:\n"); |
| 228 | printf("\tflags: 0x%.2x\n", p->flags); | 250 | printf("\tflags: 0x%.2x\n", p->flags); |
| 229 | printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK); | 251 | printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); |
| 230 | printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK); | 252 | printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); |
| 231 | printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK); | 253 | printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); |
| 232 | printf("\tstratum = %d\n", p->stratum); | 254 | printf("\tstratum = %d\n", p->stratum); |
| 233 | printf("\tpoll = %g\n", pow(2, p->poll)); | 255 | printf("\tpoll = %g\n", pow(2, p->poll)); |
| 234 | printf("\tprecision = %g\n", pow(2, p->precision)); | 256 | printf("\tprecision = %g\n", pow(2, p->precision)); |
| @@ -241,32 +263,31 @@ void print_ntp_message(const ntp_message *p){ | |||
| 241 | printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); | 263 | printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); |
| 242 | } | 264 | } |
| 243 | 265 | ||
| 244 | void print_ntp_control_message(const ntp_control_message *p){ | 266 | void print_ntp_control_message(const ntp_control_message *p) { |
| 245 | int i=0, numpeers=0; | 267 | int i = 0, numpeers = 0; |
| 246 | const ntp_assoc_status_pair *peer=NULL; | 268 | const ntp_assoc_status_pair *peer = NULL; |
| 247 | 269 | ||
| 248 | printf("control packet contents:\n"); | 270 | printf("control packet contents:\n"); |
| 249 | printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op); | 271 | printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op); |
| 250 | printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK); | 272 | printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); |
| 251 | printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK); | 273 | printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); |
| 252 | printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK); | 274 | printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); |
| 253 | printf("\t response=%d (0x%.2x)\n", (p->op&REM_RESP)>0, p->op&REM_RESP); | 275 | printf("\t response=%d (0x%.2x)\n", (p->op & REM_RESP) > 0, p->op & REM_RESP); |
| 254 | printf("\t more=%d (0x%.2x)\n", (p->op&REM_MORE)>0, p->op&REM_MORE); | 276 | printf("\t more=%d (0x%.2x)\n", (p->op & REM_MORE) > 0, p->op & REM_MORE); |
| 255 | printf("\t error=%d (0x%.2x)\n", (p->op&REM_ERROR)>0, p->op&REM_ERROR); | 277 | printf("\t error=%d (0x%.2x)\n", (p->op & REM_ERROR) > 0, p->op & REM_ERROR); |
| 256 | printf("\t op=%d (0x%.2x)\n", p->op&OP_MASK, p->op&OP_MASK); | 278 | printf("\t op=%d (0x%.2x)\n", p->op & OP_MASK, p->op & OP_MASK); |
| 257 | printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq)); | 279 | printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq)); |
| 258 | printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status)); | 280 | printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status)); |
| 259 | printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc)); | 281 | printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc)); |
| 260 | printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset)); | 282 | printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset)); |
| 261 | printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count)); | 283 | printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count)); |
| 262 | numpeers=ntohs(p->count)/(sizeof(ntp_assoc_status_pair)); | 284 | numpeers = ntohs(p->count) / (sizeof(ntp_assoc_status_pair)); |
| 263 | if(p->op&REM_RESP && p->op&OP_READSTAT){ | 285 | if (p->op & REM_RESP && p->op & OP_READSTAT) { |
| 264 | peer=(ntp_assoc_status_pair*)p->data; | 286 | peer = (ntp_assoc_status_pair *)p->data; |
| 265 | for(i=0;i<numpeers;i++){ | 287 | for (i = 0; i < numpeers; i++) { |
| 266 | printf("\tpeer id %.2x status %.2x", | 288 | printf("\tpeer id %.2x status %.2x", ntohs(peer[i].assoc), ntohs(peer[i].status)); |
| 267 | ntohs(peer[i].assoc), ntohs(peer[i].status)); | 289 | if (PEER_SEL(peer[i].status) >= PEER_INCLUDED) { |
| 268 | if (PEER_SEL(peer[i].status) >= PEER_INCLUDED){ | 290 | if (PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE) { |
| 269 | if(PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE){ | ||
| 270 | printf(" <-- current sync source"); | 291 | printf(" <-- current sync source"); |
| 271 | } else { | 292 | } else { |
| 272 | printf(" <-- current sync candidate"); | 293 | printf(" <-- current sync candidate"); |
| @@ -277,41 +298,45 @@ void print_ntp_control_message(const ntp_control_message *p){ | |||
| 277 | } | 298 | } |
| 278 | } | 299 | } |
| 279 | 300 | ||
| 280 | void setup_request(ntp_message *p){ | 301 | void setup_request(ntp_message *p) { |
| 281 | struct timeval t; | 302 | struct timeval t; |
| 282 | 303 | ||
| 283 | memset(p, 0, sizeof(ntp_message)); | 304 | memset(p, 0, sizeof(ntp_message)); |
| 284 | LI_SET(p->flags, LI_ALARM); | 305 | LI_SET(p->flags, LI_ALARM); |
| 285 | VN_SET(p->flags, 4); | 306 | VN_SET(p->flags, 4); |
| 286 | MODE_SET(p->flags, MODE_CLIENT); | 307 | MODE_SET(p->flags, MODE_CLIENT); |
| 287 | p->poll=4; | 308 | p->poll = 4; |
| 288 | p->precision=(int8_t)0xfa; | 309 | p->precision = (int8_t)0xfa; |
| 289 | L16(p->rtdelay)=htons(1); | 310 | L16(p->rtdelay) = htons(1); |
| 290 | L16(p->rtdisp)=htons(1); | 311 | L16(p->rtdisp) = htons(1); |
| 291 | 312 | ||
| 292 | gettimeofday(&t, NULL); | 313 | gettimeofday(&t, NULL); |
| 293 | TVtoNTP64(t,p->txts); | 314 | TVtoNTP64(t, p->txts); |
| 294 | } | 315 | } |
| 295 | 316 | ||
| 296 | /* select the "best" server from a list of servers, and return its index. | 317 | /* select the "best" server from a list of servers, and return its index. |
| 297 | * this is done by filtering servers based on stratum, dispersion, and | 318 | * this is done by filtering servers based on stratum, dispersion, and |
| 298 | * finally round-trip delay. */ | 319 | * finally round-trip delay. */ |
| 299 | int best_offset_server(const ntp_server_results *slist, int nservers){ | 320 | int best_offset_server(const ntp_server_results *slist, int nservers) { |
| 300 | int cserver=0, best_server=-1; | 321 | int cserver = 0, best_server = -1; |
| 301 | 322 | ||
| 302 | /* for each server */ | 323 | /* for each server */ |
| 303 | for(cserver=0; cserver<nservers; cserver++){ | 324 | for (cserver = 0; cserver < nservers; cserver++) { |
| 304 | /* We don't want any servers that fails these tests */ | 325 | /* We don't want any servers that fails these tests */ |
| 305 | /* Sort out servers that didn't respond or responede with a 0 stratum; | 326 | /* Sort out servers that didn't respond or responede with a 0 stratum; |
| 306 | * stratum 0 is for reference clocks so no NTP server should ever report | 327 | * stratum 0 is for reference clocks so no NTP server should ever report |
| 307 | * a stratum 0 */ | 328 | * a stratum 0 */ |
| 308 | if ( slist[cserver].stratum == 0){ | 329 | if (slist[cserver].stratum == 0) { |
| 309 | if (verbose) printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum); | 330 | if (verbose) { |
| 331 | printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum); | ||
| 332 | } | ||
| 310 | continue; | 333 | continue; |
| 311 | } | 334 | } |
| 312 | /* Sort out servers with error flags */ | 335 | /* Sort out servers with error flags */ |
| 313 | if ( LI(slist[cserver].flags) == LI_ALARM ){ | 336 | if (LI(slist[cserver].flags) == LI_ALARM) { |
| 314 | if (verbose) printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags)); | 337 | if (verbose) { |
| 338 | printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags)); | ||
| 339 | } | ||
| 315 | continue; | 340 | continue; |
| 316 | } | 341 | } |
| 317 | 342 | ||
| @@ -325,13 +350,13 @@ int best_offset_server(const ntp_server_results *slist, int nservers){ | |||
| 325 | /* compare the server to the best one we've seen so far */ | 350 | /* compare the server to the best one we've seen so far */ |
| 326 | /* does it have an equal or better stratum? */ | 351 | /* does it have an equal or better stratum? */ |
| 327 | DBG(printf("comparing peer %d with peer %d\n", cserver, best_server)); | 352 | DBG(printf("comparing peer %d with peer %d\n", cserver, best_server)); |
| 328 | if(slist[cserver].stratum <= slist[best_server].stratum){ | 353 | if (slist[cserver].stratum <= slist[best_server].stratum) { |
| 329 | DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server)); | 354 | DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server)); |
| 330 | /* does it have an equal or better dispersion? */ | 355 | /* does it have an equal or better dispersion? */ |
| 331 | if(slist[cserver].rtdisp <= slist[best_server].rtdisp){ | 356 | if (slist[cserver].rtdisp <= slist[best_server].rtdisp) { |
| 332 | DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server)); | 357 | DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server)); |
| 333 | /* does it have a better rtdelay? */ | 358 | /* does it have a better rtdelay? */ |
| 334 | if(slist[cserver].rtdelay < slist[best_server].rtdelay){ | 359 | if (slist[cserver].rtdelay < slist[best_server].rtdelay) { |
| 335 | DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server)); | 360 | DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server)); |
| 336 | best_server = cserver; | 361 | best_server = cserver; |
| 337 | DBG(printf("peer %d is now our best candidate\n", best_server)); | 362 | DBG(printf("peer %d is now our best candidate\n", best_server)); |
| @@ -340,7 +365,7 @@ int best_offset_server(const ntp_server_results *slist, int nservers){ | |||
| 340 | } | 365 | } |
| 341 | } | 366 | } |
| 342 | 367 | ||
| 343 | if(best_server >= 0) { | 368 | if (best_server >= 0) { |
| 344 | DBG(printf("best server selected: peer %d\n", best_server)); | 369 | DBG(printf("best server selected: peer %d\n", best_server)); |
| 345 | return best_server; | 370 | return best_server; |
| 346 | } else { | 371 | } else { |
| @@ -354,16 +379,16 @@ int best_offset_server(const ntp_server_results *slist, int nservers){ | |||
| 354 | * we don't waste time sitting around waiting for single packets. | 379 | * we don't waste time sitting around waiting for single packets. |
| 355 | * - we also "manually" handle resolving host names and connecting, because | 380 | * - we also "manually" handle resolving host names and connecting, because |
| 356 | * we have to do it in a way that our lazy macros don't handle currently :( */ | 381 | * we have to do it in a way that our lazy macros don't handle currently :( */ |
| 357 | double offset_request(const char *host, int *status){ | 382 | double offset_request(const char *host, int *status) { |
| 358 | int i=0, ga_result=0, num_hosts=0, *socklist=NULL, respnum=0; | 383 | int i = 0, ga_result = 0, num_hosts = 0, *socklist = NULL, respnum = 0; |
| 359 | int servers_completed=0, one_read=0, servers_readable=0, best_index=-1; | 384 | int servers_completed = 0, one_read = 0, servers_readable = 0, best_index = -1; |
| 360 | time_t now_time=0, start_ts=0; | 385 | time_t now_time = 0, start_ts = 0; |
| 361 | ntp_message *req=NULL; | 386 | ntp_message *req = NULL; |
| 362 | double avg_offset=0.; | 387 | double avg_offset = 0.; |
| 363 | struct timeval recv_time; | 388 | struct timeval recv_time; |
| 364 | struct addrinfo *ai=NULL, *ai_tmp=NULL, hints; | 389 | struct addrinfo *ai = NULL, *ai_tmp = NULL, hints; |
| 365 | struct pollfd *ufds=NULL; | 390 | struct pollfd *ufds = NULL; |
| 366 | ntp_server_results *servers=NULL; | 391 | ntp_server_results *servers = NULL; |
| 367 | 392 | ||
| 368 | /* setup hints to only return results from getaddrinfo that we'd like */ | 393 | /* setup hints to only return results from getaddrinfo that we'd like */ |
| 369 | memset(&hints, 0, sizeof(struct addrinfo)); | 394 | memset(&hints, 0, sizeof(struct addrinfo)); |
| @@ -373,97 +398,112 @@ double offset_request(const char *host, int *status){ | |||
| 373 | 398 | ||
| 374 | /* fill in ai with the list of hosts resolved by the host name */ | 399 | /* fill in ai with the list of hosts resolved by the host name */ |
| 375 | ga_result = getaddrinfo(host, "123", &hints, &ai); | 400 | ga_result = getaddrinfo(host, "123", &hints, &ai); |
| 376 | if(ga_result!=0){ | 401 | if (ga_result != 0) { |
| 377 | die(STATE_UNKNOWN, "error getting address for %s: %s\n", | 402 | die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); |
| 378 | host, gai_strerror(ga_result)); | ||
| 379 | } | 403 | } |
| 380 | 404 | ||
| 381 | /* count the number of returned hosts, and allocate stuff accordingly */ | 405 | /* count the number of returned hosts, and allocate stuff accordingly */ |
| 382 | for(ai_tmp=ai; ai_tmp!=NULL; ai_tmp=ai_tmp->ai_next){ num_hosts++; } | 406 | for (ai_tmp = ai; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { |
| 383 | req=(ntp_message*)malloc(sizeof(ntp_message)*num_hosts); | 407 | num_hosts++; |
| 384 | if(req==NULL) die(STATE_UNKNOWN, "can not allocate ntp message array"); | 408 | } |
| 385 | socklist=(int*)malloc(sizeof(int)*num_hosts); | 409 | req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); |
| 386 | if(socklist==NULL) die(STATE_UNKNOWN, "can not allocate socket array"); | 410 | if (req == NULL) { |
| 387 | ufds=(struct pollfd*)malloc(sizeof(struct pollfd)*num_hosts); | 411 | die(STATE_UNKNOWN, "can not allocate ntp message array"); |
| 388 | if(ufds==NULL) die(STATE_UNKNOWN, "can not allocate socket array"); | 412 | } |
| 389 | servers=(ntp_server_results*)malloc(sizeof(ntp_server_results)*num_hosts); | 413 | socklist = (int *)malloc(sizeof(int) * num_hosts); |
| 390 | if(servers==NULL) die(STATE_UNKNOWN, "can not allocate server array"); | 414 | if (socklist == NULL) { |
| 391 | memset(servers, 0, sizeof(ntp_server_results)*num_hosts); | 415 | die(STATE_UNKNOWN, "can not allocate socket array"); |
| 416 | } | ||
| 417 | ufds = (struct pollfd *)malloc(sizeof(struct pollfd) * num_hosts); | ||
| 418 | if (ufds == NULL) { | ||
| 419 | die(STATE_UNKNOWN, "can not allocate socket array"); | ||
| 420 | } | ||
| 421 | servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); | ||
| 422 | if (servers == NULL) { | ||
| 423 | die(STATE_UNKNOWN, "can not allocate server array"); | ||
| 424 | } | ||
| 425 | memset(servers, 0, sizeof(ntp_server_results) * num_hosts); | ||
| 392 | DBG(printf("Found %d peers to check\n", num_hosts)); | 426 | DBG(printf("Found %d peers to check\n", num_hosts)); |
| 393 | 427 | ||
| 394 | /* setup each socket for writing, and the corresponding struct pollfd */ | 428 | /* setup each socket for writing, and the corresponding struct pollfd */ |
| 395 | ai_tmp=ai; | 429 | ai_tmp = ai; |
| 396 | for(i=0;ai_tmp;i++){ | 430 | for (i = 0; ai_tmp; i++) { |
| 397 | socklist[i]=socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); | 431 | socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); |
| 398 | if(socklist[i] == -1) { | 432 | if (socklist[i] == -1) { |
| 399 | perror(NULL); | 433 | perror(NULL); |
| 400 | die(STATE_UNKNOWN, "can not create new socket"); | 434 | die(STATE_UNKNOWN, "can not create new socket"); |
| 401 | } | 435 | } |
| 402 | if(connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)){ | 436 | if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) { |
| 403 | /* don't die here, because it is enough if there is one server | 437 | /* don't die here, because it is enough if there is one server |
| 404 | answering in time. This also would break for dual ipv4/6 stacked | 438 | answering in time. This also would break for dual ipv4/6 stacked |
| 405 | ntp servers when the client only supports on of them. | 439 | ntp servers when the client only supports on of them. |
| 406 | */ | 440 | */ |
| 407 | DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); | 441 | DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); |
| 408 | } else { | 442 | } else { |
| 409 | ufds[i].fd=socklist[i]; | 443 | ufds[i].fd = socklist[i]; |
| 410 | ufds[i].events=POLLIN; | 444 | ufds[i].events = POLLIN; |
| 411 | ufds[i].revents=0; | 445 | ufds[i].revents = 0; |
| 412 | } | 446 | } |
| 413 | ai_tmp = ai_tmp->ai_next; | 447 | ai_tmp = ai_tmp->ai_next; |
| 414 | } | 448 | } |
| 415 | 449 | ||
| 416 | /* now do AVG_NUM checks to each host. we stop before timeout/2 seconds | 450 | /* now do AVG_NUM checks to each host. we stop before timeout/2 seconds |
| 417 | * have passed in order to ensure post-processing and jitter time. */ | 451 | * have passed in order to ensure post-processing and jitter time. */ |
| 418 | now_time=start_ts=time(NULL); | 452 | now_time = start_ts = time(NULL); |
| 419 | while(servers_completed<num_hosts && now_time-start_ts <= socket_timeout/2){ | 453 | while (servers_completed < num_hosts && now_time - start_ts <= socket_timeout / 2) { |
| 420 | /* loop through each server and find each one which hasn't | 454 | /* loop through each server and find each one which hasn't |
| 421 | * been touched in the past second or so and is still lacking | 455 | * been touched in the past second or so and is still lacking |
| 422 | * some responses. for each of these servers, send a new request, | 456 | * some responses. for each of these servers, send a new request, |
| 423 | * and update the "waiting" timestamp with the current time. */ | 457 | * and update the "waiting" timestamp with the current time. */ |
| 424 | now_time=time(NULL); | 458 | now_time = time(NULL); |
| 425 | 459 | ||
| 426 | for(i=0; i<num_hosts; i++){ | 460 | for (i = 0; i < num_hosts; i++) { |
| 427 | if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){ | 461 | if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) { |
| 428 | if(verbose && servers[i].waiting != 0) printf("re-"); | 462 | if (verbose && servers[i].waiting != 0) { |
| 429 | if(verbose) printf("sending request to peer %d\n", i); | 463 | printf("re-"); |
| 464 | } | ||
| 465 | if (verbose) { | ||
| 466 | printf("sending request to peer %d\n", i); | ||
| 467 | } | ||
| 430 | setup_request(&req[i]); | 468 | setup_request(&req[i]); |
| 431 | write(socklist[i], &req[i], sizeof(ntp_message)); | 469 | write(socklist[i], &req[i], sizeof(ntp_message)); |
| 432 | servers[i].waiting=now_time; | 470 | servers[i].waiting = now_time; |
| 433 | break; | 471 | break; |
| 434 | } | 472 | } |
| 435 | } | 473 | } |
| 436 | 474 | ||
| 437 | /* quickly poll for any sockets with pending data */ | 475 | /* quickly poll for any sockets with pending data */ |
| 438 | servers_readable=poll(ufds, num_hosts, 100); | 476 | servers_readable = poll(ufds, num_hosts, 100); |
| 439 | if(servers_readable==-1){ | 477 | if (servers_readable == -1) { |
| 440 | perror("polling ntp sockets"); | 478 | perror("polling ntp sockets"); |
| 441 | die(STATE_UNKNOWN, "communication errors"); | 479 | die(STATE_UNKNOWN, "communication errors"); |
| 442 | } | 480 | } |
| 443 | 481 | ||
| 444 | /* read from any sockets with pending data */ | 482 | /* read from any sockets with pending data */ |
| 445 | for(i=0; servers_readable && i<num_hosts; i++){ | 483 | for (i = 0; servers_readable && i < num_hosts; i++) { |
| 446 | if(ufds[i].revents&POLLIN && servers[i].num_responses < AVG_NUM){ | 484 | if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) { |
| 447 | if(verbose) { | 485 | if (verbose) { |
| 448 | printf("response from peer %d: ", i); | 486 | printf("response from peer %d: ", i); |
| 449 | } | 487 | } |
| 450 | 488 | ||
| 451 | read(ufds[i].fd, &req[i], sizeof(ntp_message)); | 489 | read(ufds[i].fd, &req[i], sizeof(ntp_message)); |
| 452 | gettimeofday(&recv_time, NULL); | 490 | gettimeofday(&recv_time, NULL); |
| 453 | DBG(print_ntp_message(&req[i])); | 491 | DBG(print_ntp_message(&req[i])); |
| 454 | respnum=servers[i].num_responses++; | 492 | respnum = servers[i].num_responses++; |
| 455 | servers[i].offset[respnum]=calc_offset(&req[i], &recv_time); | 493 | servers[i].offset[respnum] = calc_offset(&req[i], &recv_time); |
| 456 | if(verbose) { | 494 | if (verbose) { |
| 457 | printf("offset %.10g\n", servers[i].offset[respnum]); | 495 | printf("offset %.10g\n", servers[i].offset[respnum]); |
| 458 | } | 496 | } |
| 459 | servers[i].stratum=req[i].stratum; | 497 | servers[i].stratum = req[i].stratum; |
| 460 | servers[i].rtdisp=NTP32asDOUBLE(req[i].rtdisp); | 498 | servers[i].rtdisp = NTP32asDOUBLE(req[i].rtdisp); |
| 461 | servers[i].rtdelay=NTP32asDOUBLE(req[i].rtdelay); | 499 | servers[i].rtdelay = NTP32asDOUBLE(req[i].rtdelay); |
| 462 | servers[i].waiting=0; | 500 | servers[i].waiting = 0; |
| 463 | servers[i].flags=req[i].flags; | 501 | servers[i].flags = req[i].flags; |
| 464 | servers_readable--; | 502 | servers_readable--; |
| 465 | one_read = 1; | 503 | one_read = 1; |
| 466 | if(servers[i].num_responses==AVG_NUM) servers_completed++; | 504 | if (servers[i].num_responses == AVG_NUM) { |
| 505 | servers_completed++; | ||
| 506 | } | ||
| 467 | } | 507 | } |
| 468 | } | 508 | } |
| 469 | /* lather, rinse, repeat. */ | 509 | /* lather, rinse, repeat. */ |
| @@ -474,15 +514,15 @@ double offset_request(const char *host, int *status){ | |||
| 474 | } | 514 | } |
| 475 | 515 | ||
| 476 | /* now, pick the best server from the list */ | 516 | /* now, pick the best server from the list */ |
| 477 | best_index=best_offset_server(servers, num_hosts); | 517 | best_index = best_offset_server(servers, num_hosts); |
| 478 | if(best_index < 0){ | 518 | if (best_index < 0) { |
| 479 | *status=STATE_UNKNOWN; | 519 | *status = STATE_UNKNOWN; |
| 480 | } else { | 520 | } else { |
| 481 | /* finally, calculate the average offset */ | 521 | /* finally, calculate the average offset */ |
| 482 | for(i=0; i<servers[best_index].num_responses;i++){ | 522 | for (i = 0; i < servers[best_index].num_responses; i++) { |
| 483 | avg_offset+=servers[best_index].offset[i]; | 523 | avg_offset += servers[best_index].offset[i]; |
| 484 | } | 524 | } |
| 485 | avg_offset/=servers[best_index].num_responses; | 525 | avg_offset /= servers[best_index].num_responses; |
| 486 | } | 526 | } |
| 487 | 527 | ||
| 488 | /* cleanup */ | 528 | /* cleanup */ |
| @@ -496,12 +536,13 @@ double offset_request(const char *host, int *status){ | |||
| 496 | free(req); | 536 | free(req); |
| 497 | freeaddrinfo(ai); | 537 | freeaddrinfo(ai); |
| 498 | 538 | ||
| 499 | if(verbose) printf("overall average offset: %.10g\n", avg_offset); | 539 | if (verbose) { |
| 540 | printf("overall average offset: %.10g\n", avg_offset); | ||
| 541 | } | ||
| 500 | return avg_offset; | 542 | return avg_offset; |
| 501 | } | 543 | } |
| 502 | 544 | ||
| 503 | void | 545 | void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) { |
| 504 | setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){ | ||
| 505 | memset(p, 0, sizeof(ntp_control_message)); | 546 | memset(p, 0, sizeof(ntp_control_message)); |
| 506 | LI_SET(p->flags, LI_NOWARNING); | 547 | LI_SET(p->flags, LI_NOWARNING); |
| 507 | VN_SET(p->flags, VN_RESERVED); | 548 | VN_SET(p->flags, VN_RESERVED); |
| @@ -512,16 +553,16 @@ setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){ | |||
| 512 | } | 553 | } |
| 513 | 554 | ||
| 514 | /* XXX handle responses with the error bit set */ | 555 | /* XXX handle responses with the error bit set */ |
| 515 | double jitter_request(int *status){ | 556 | double jitter_request(int *status) { |
| 516 | int conn=-1, i, npeers=0, num_candidates=0; | 557 | int conn = -1, i, npeers = 0, num_candidates = 0; |
| 517 | bool syncsource_found = false; | 558 | bool syncsource_found = false; |
| 518 | int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0; | 559 | int run = 0, min_peer_sel = PEER_INCLUDED, num_selected = 0, num_valid = 0; |
| 519 | int peers_size=0, peer_offset=0; | 560 | int peers_size = 0, peer_offset = 0; |
| 520 | ntp_assoc_status_pair *peers=NULL; | 561 | ntp_assoc_status_pair *peers = NULL; |
| 521 | ntp_control_message req; | 562 | ntp_control_message req; |
| 522 | const char *getvar = "jitter"; | 563 | const char *getvar = "jitter"; |
| 523 | double rval = 0.0, jitter = -1.0; | 564 | double rval = 0.0, jitter = -1.0; |
| 524 | char *startofvalue=NULL, *nptr=NULL; | 565 | char *startofvalue = NULL, *nptr = NULL; |
| 525 | void *tmp; | 566 | void *tmp; |
| 526 | 567 | ||
| 527 | /* Long-winded explanation: | 568 | /* Long-winded explanation: |
| @@ -542,54 +583,62 @@ double jitter_request(int *status){ | |||
| 542 | 583 | ||
| 543 | /* keep sending requests until the server stops setting the | 584 | /* keep sending requests until the server stops setting the |
| 544 | * REM_MORE bit, though usually this is only 1 packet. */ | 585 | * REM_MORE bit, though usually this is only 1 packet. */ |
| 545 | do{ | 586 | do { |
| 546 | setup_control_request(&req, OP_READSTAT, 1); | 587 | setup_control_request(&req, OP_READSTAT, 1); |
| 547 | DBG(printf("sending READSTAT request")); | 588 | DBG(printf("sending READSTAT request")); |
| 548 | write(conn, &req, SIZEOF_NTPCM(req)); | 589 | write(conn, &req, SIZEOF_NTPCM(req)); |
| 549 | DBG(print_ntp_control_message(&req)); | 590 | DBG(print_ntp_control_message(&req)); |
| 550 | /* Attempt to read the largest size packet possible */ | 591 | /* Attempt to read the largest size packet possible */ |
| 551 | req.count=htons(MAX_CM_SIZE); | 592 | req.count = htons(MAX_CM_SIZE); |
| 552 | DBG(printf("receiving READSTAT response")) | 593 | DBG(printf("receiving READSTAT response")) |
| 553 | read(conn, &req, SIZEOF_NTPCM(req)); | 594 | read(conn, &req, SIZEOF_NTPCM(req)); |
| 554 | DBG(print_ntp_control_message(&req)); | 595 | DBG(print_ntp_control_message(&req)); |
| 555 | /* Each peer identifier is 4 bytes in the data section, which | 596 | /* Each peer identifier is 4 bytes in the data section, which |
| 556 | * we represent as a ntp_assoc_status_pair datatype. | 597 | * we represent as a ntp_assoc_status_pair datatype. |
| 557 | */ | 598 | */ |
| 558 | peers_size+=ntohs(req.count); | 599 | peers_size += ntohs(req.count); |
| 559 | if((tmp=realloc(peers, peers_size)) == NULL) | 600 | if ((tmp = realloc(peers, peers_size)) == NULL) { |
| 560 | free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); | 601 | free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); |
| 561 | peers=tmp; | 602 | } |
| 562 | memcpy((void*)((ptrdiff_t)peers+peer_offset), (void*)req.data, ntohs(req.count)); | 603 | peers = tmp; |
| 563 | npeers=peers_size/sizeof(ntp_assoc_status_pair); | 604 | memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count)); |
| 564 | peer_offset+=ntohs(req.count); | 605 | npeers = peers_size / sizeof(ntp_assoc_status_pair); |
| 565 | } while(req.op&REM_MORE); | 606 | peer_offset += ntohs(req.count); |
| 607 | } while (req.op & REM_MORE); | ||
| 566 | 608 | ||
| 567 | /* first, let's find out if we have a sync source, or if there are | 609 | /* first, let's find out if we have a sync source, or if there are |
| 568 | * at least some candidates. in the case of the latter we'll issue | 610 | * at least some candidates. in the case of the latter we'll issue |
| 569 | * a warning but go ahead with the check on them. */ | 611 | * a warning but go ahead with the check on them. */ |
| 570 | for (i = 0; i < npeers; i++){ | 612 | for (i = 0; i < npeers; i++) { |
| 571 | if (PEER_SEL(peers[i].status) >= PEER_INCLUDED){ | 613 | if (PEER_SEL(peers[i].status) >= PEER_INCLUDED) { |
| 572 | num_candidates++; | 614 | num_candidates++; |
| 573 | if(PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE){ | 615 | if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) { |
| 574 | syncsource_found = true; | 616 | syncsource_found = true; |
| 575 | min_peer_sel=PEER_SYNCSOURCE; | 617 | min_peer_sel = PEER_SYNCSOURCE; |
| 576 | } | 618 | } |
| 577 | } | 619 | } |
| 578 | } | 620 | } |
| 579 | if(verbose) printf("%d candidate peers available\n", num_candidates); | 621 | if (verbose) { |
| 580 | if(verbose && syncsource_found) printf("synchronization source found\n"); | 622 | printf("%d candidate peers available\n", num_candidates); |
| 581 | if(! syncsource_found){ | 623 | } |
| 624 | if (verbose && syncsource_found) { | ||
| 625 | printf("synchronization source found\n"); | ||
| 626 | } | ||
| 627 | if (!syncsource_found) { | ||
| 582 | *status = STATE_UNKNOWN; | 628 | *status = STATE_UNKNOWN; |
| 583 | if(verbose) printf("warning: no synchronization source found\n"); | 629 | if (verbose) { |
| 630 | printf("warning: no synchronization source found\n"); | ||
| 631 | } | ||
| 584 | } | 632 | } |
| 585 | 633 | ||
| 586 | 634 | for (run = 0; run < AVG_NUM; run++) { | |
| 587 | for (run=0; run<AVG_NUM; run++){ | 635 | if (verbose) { |
| 588 | if(verbose) printf("jitter run %d of %d\n", run+1, AVG_NUM); | 636 | printf("jitter run %d of %d\n", run + 1, AVG_NUM); |
| 589 | for (i = 0; i < npeers; i++){ | 637 | } |
| 638 | for (i = 0; i < npeers; i++) { | ||
| 590 | /* Only query this server if it is the current sync source */ | 639 | /* Only query this server if it is the current sync source */ |
| 591 | if (PEER_SEL(peers[i].status) >= min_peer_sel){ | 640 | if (PEER_SEL(peers[i].status) >= min_peer_sel) { |
| 592 | char jitter_data[MAX_CM_SIZE+1]; | 641 | char jitter_data[MAX_CM_SIZE + 1]; |
| 593 | size_t jitter_data_count; | 642 | size_t jitter_data_count; |
| 594 | 643 | ||
| 595 | num_selected++; | 644 | num_selected++; |
| @@ -602,7 +651,7 @@ double jitter_request(int *status){ | |||
| 602 | */ | 651 | */ |
| 603 | /* Older servers doesn't know what jitter is, so if we get an | 652 | /* Older servers doesn't know what jitter is, so if we get an |
| 604 | * error on the first pass we redo it with "dispersion" */ | 653 | * error on the first pass we redo it with "dispersion" */ |
| 605 | strncpy(req.data, getvar, MAX_CM_SIZE-1); | 654 | strncpy(req.data, getvar, MAX_CM_SIZE - 1); |
| 606 | req.count = htons(strlen(getvar)); | 655 | req.count = htons(strlen(getvar)); |
| 607 | DBG(printf("sending READVAR request...\n")); | 656 | DBG(printf("sending READVAR request...\n")); |
| 608 | write(conn, &req, SIZEOF_NTPCM(req)); | 657 | write(conn, &req, SIZEOF_NTPCM(req)); |
| @@ -613,8 +662,11 @@ double jitter_request(int *status){ | |||
| 613 | read(conn, &req, SIZEOF_NTPCM(req)); | 662 | read(conn, &req, SIZEOF_NTPCM(req)); |
| 614 | DBG(print_ntp_control_message(&req)); | 663 | DBG(print_ntp_control_message(&req)); |
| 615 | 664 | ||
| 616 | if(req.op&REM_ERROR && strstr(getvar, "jitter")) { | 665 | if (req.op & REM_ERROR && strstr(getvar, "jitter")) { |
| 617 | if(verbose) printf("The 'jitter' command failed (old ntp server?)\nRestarting with 'dispersion'...\n"); | 666 | if (verbose) { |
| 667 | printf("The 'jitter' command failed (old ntp server?)\nRestarting with " | ||
| 668 | "'dispersion'...\n"); | ||
| 669 | } | ||
| 618 | getvar = "dispersion"; | 670 | getvar = "dispersion"; |
| 619 | num_selected--; | 671 | num_selected--; |
| 620 | i--; | 672 | i--; |
| @@ -622,32 +674,33 @@ double jitter_request(int *status){ | |||
| 622 | } | 674 | } |
| 623 | 675 | ||
| 624 | /* get to the float value */ | 676 | /* get to the float value */ |
| 625 | if(verbose) { | 677 | if (verbose) { |
| 626 | printf("parsing jitter from peer %.2x: ", ntohs(peers[i].assoc)); | 678 | printf("parsing jitter from peer %.2x: ", ntohs(peers[i].assoc)); |
| 627 | } | 679 | } |
| 628 | if((jitter_data_count = ntohs(req.count)) >= sizeof(jitter_data)){ | 680 | if ((jitter_data_count = ntohs(req.count)) >= sizeof(jitter_data)) { |
| 629 | die(STATE_UNKNOWN, | 681 | die(STATE_UNKNOWN, _("jitter response too large (%lu bytes)\n"), |
| 630 | _("jitter response too large (%lu bytes)\n"), | 682 | (unsigned long)jitter_data_count); |
| 631 | (unsigned long)jitter_data_count); | ||
| 632 | } | 683 | } |
| 633 | memcpy(jitter_data, req.data, jitter_data_count); | 684 | memcpy(jitter_data, req.data, jitter_data_count); |
| 634 | jitter_data[jitter_data_count] = '\0'; | 685 | jitter_data[jitter_data_count] = '\0'; |
| 635 | startofvalue = strchr(jitter_data, '='); | 686 | startofvalue = strchr(jitter_data, '='); |
| 636 | if(startofvalue != NULL) { | 687 | if (startofvalue != NULL) { |
| 637 | startofvalue++; | 688 | startofvalue++; |
| 638 | jitter = strtod(startofvalue, &nptr); | 689 | jitter = strtod(startofvalue, &nptr); |
| 639 | } | 690 | } |
| 640 | if(startofvalue == NULL || startofvalue==nptr){ | 691 | if (startofvalue == NULL || startofvalue == nptr) { |
| 641 | printf("warning: unable to read server jitter response.\n"); | 692 | printf("warning: unable to read server jitter response.\n"); |
| 642 | *status = STATE_UNKNOWN; | 693 | *status = STATE_UNKNOWN; |
| 643 | } else { | 694 | } else { |
| 644 | if(verbose) printf("%g\n", jitter); | 695 | if (verbose) { |
| 696 | printf("%g\n", jitter); | ||
| 697 | } | ||
| 645 | num_valid++; | 698 | num_valid++; |
| 646 | rval += jitter; | 699 | rval += jitter; |
| 647 | } | 700 | } |
| 648 | } | 701 | } |
| 649 | } | 702 | } |
| 650 | if(verbose){ | 703 | if (verbose) { |
| 651 | printf("jitter parsed from %d/%d peers\n", num_valid, num_selected); | 704 | printf("jitter parsed from %d/%d peers\n", num_valid, num_selected); |
| 652 | } | 705 | } |
| 653 | } | 706 | } |
| @@ -655,37 +708,33 @@ double jitter_request(int *status){ | |||
| 655 | rval = num_valid ? rval / num_valid : -1.0; | 708 | rval = num_valid ? rval / num_valid : -1.0; |
| 656 | 709 | ||
| 657 | close(conn); | 710 | close(conn); |
| 658 | if(peers!=NULL) free(peers); | 711 | if (peers != NULL) { |
| 712 | free(peers); | ||
| 713 | } | ||
| 659 | /* If we return -1.0, it means no synchronization source was found */ | 714 | /* If we return -1.0, it means no synchronization source was found */ |
| 660 | return rval; | 715 | return rval; |
| 661 | } | 716 | } |
| 662 | 717 | ||
| 663 | int process_arguments(int argc, char **argv){ | 718 | int process_arguments(int argc, char **argv) { |
| 664 | int c; | 719 | int c; |
| 665 | int option=0; | 720 | int option = 0; |
| 666 | static struct option longopts[] = { | 721 | static struct option longopts[] = { |
| 667 | {"version", no_argument, 0, 'V'}, | 722 | {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, |
| 668 | {"help", no_argument, 0, 'h'}, | 723 | {"verbose", no_argument, 0, 'v'}, {"use-ipv4", no_argument, 0, '4'}, |
| 669 | {"verbose", no_argument, 0, 'v'}, | 724 | {"use-ipv6", no_argument, 0, '6'}, {"warning", required_argument, 0, 'w'}, |
| 670 | {"use-ipv4", no_argument, 0, '4'}, | 725 | {"critical", required_argument, 0, 'c'}, {"jwarn", required_argument, 0, 'j'}, |
| 671 | {"use-ipv6", no_argument, 0, '6'}, | 726 | {"jcrit", required_argument, 0, 'k'}, {"timeout", required_argument, 0, 't'}, |
| 672 | {"warning", required_argument, 0, 'w'}, | 727 | {"hostname", required_argument, 0, 'H'}, {0, 0, 0, 0}}; |
| 673 | {"critical", required_argument, 0, 'c'}, | 728 | |
| 674 | {"jwarn", required_argument, 0, 'j'}, | 729 | if (argc < 2) { |
| 675 | {"jcrit", required_argument, 0, 'k'}, | 730 | usage("\n"); |
| 676 | {"timeout", required_argument, 0, 't'}, | 731 | } |
| 677 | {"hostname", required_argument, 0, 'H'}, | ||
| 678 | {0, 0, 0, 0} | ||
| 679 | }; | ||
| 680 | |||
| 681 | |||
| 682 | if (argc < 2) | ||
| 683 | usage ("\n"); | ||
| 684 | 732 | ||
| 685 | while (1) { | 733 | while (1) { |
| 686 | c = getopt_long (argc, argv, "Vhv46w:c:j:k:t:H:", longopts, &option); | 734 | c = getopt_long(argc, argv, "Vhv46w:c:j:k:t:H:", longopts, &option); |
| 687 | if (c == -1 || c == EOF || c == 1) | 735 | if (c == -1 || c == EOF || c == 1) { |
| 688 | break; | 736 | break; |
| 737 | } | ||
| 689 | 738 | ||
| 690 | switch (c) { | 739 | switch (c) { |
| 691 | case 'h': | 740 | case 'h': |
| @@ -716,12 +765,13 @@ int process_arguments(int argc, char **argv){ | |||
| 716 | jcrit = optarg; | 765 | jcrit = optarg; |
| 717 | break; | 766 | break; |
| 718 | case 'H': | 767 | case 'H': |
| 719 | if(!is_host(optarg)) | 768 | if (!is_host(optarg)) { |
| 720 | usage2(_("Invalid hostname/address"), optarg); | 769 | usage2(_("Invalid hostname/address"), optarg); |
| 770 | } | ||
| 721 | server_address = strdup(optarg); | 771 | server_address = strdup(optarg); |
| 722 | break; | 772 | break; |
| 723 | case 't': | 773 | case 't': |
| 724 | socket_timeout=atoi(optarg); | 774 | socket_timeout = atoi(optarg); |
| 725 | break; | 775 | break; |
| 726 | case '4': | 776 | case '4': |
| 727 | address_family = AF_INET; | 777 | address_family = AF_INET; |
| @@ -730,64 +780,59 @@ int process_arguments(int argc, char **argv){ | |||
| 730 | #ifdef USE_IPV6 | 780 | #ifdef USE_IPV6 |
| 731 | address_family = AF_INET6; | 781 | address_family = AF_INET6; |
| 732 | #else | 782 | #else |
| 733 | usage4 (_("IPv6 support not available")); | 783 | usage4(_("IPv6 support not available")); |
| 734 | #endif | 784 | #endif |
| 735 | break; | 785 | break; |
| 736 | case '?': | 786 | case '?': |
| 737 | /* print short usage statement if args not parsable */ | 787 | /* print short usage statement if args not parsable */ |
| 738 | usage5 (); | 788 | usage5(); |
| 739 | break; | 789 | break; |
| 740 | } | 790 | } |
| 741 | } | 791 | } |
| 742 | 792 | ||
| 743 | if(server_address == NULL){ | 793 | if (server_address == NULL) { |
| 744 | usage4(_("Hostname was not supplied")); | 794 | usage4(_("Hostname was not supplied")); |
| 745 | } | 795 | } |
| 746 | 796 | ||
| 747 | return 0; | 797 | return 0; |
| 748 | } | 798 | } |
| 749 | 799 | ||
| 750 | char *perfd_offset (double offset) | 800 | char *perfd_offset(double offset) { |
| 751 | { | 801 | return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, |
| 752 | return fperfdata ("offset", offset, "s", | 802 | offset_thresholds->critical->end, false, 0, false, 0); |
| 753 | true, offset_thresholds->warning->end, | ||
| 754 | true, offset_thresholds->critical->end, | ||
| 755 | false, 0, false, 0); | ||
| 756 | } | 803 | } |
| 757 | 804 | ||
| 758 | char *perfd_jitter (double jitter) | 805 | char *perfd_jitter(double jitter) { |
| 759 | { | 806 | return fperfdata("jitter", jitter, "s", do_jitter, jitter_thresholds->warning->end, do_jitter, |
| 760 | return fperfdata ("jitter", jitter, "s", | 807 | jitter_thresholds->critical->end, true, 0, false, 0); |
| 761 | do_jitter, jitter_thresholds->warning->end, | ||
| 762 | do_jitter, jitter_thresholds->critical->end, | ||
| 763 | true, 0, false, 0); | ||
| 764 | } | 808 | } |
| 765 | 809 | ||
| 766 | int main(int argc, char *argv[]){ | 810 | int main(int argc, char *argv[]) { |
| 767 | int result, offset_result, jitter_result; | 811 | int result, offset_result, jitter_result; |
| 768 | double offset=0, jitter=0; | 812 | double offset = 0, jitter = 0; |
| 769 | char *result_line, *perfdata_line; | 813 | char *result_line, *perfdata_line; |
| 770 | 814 | ||
| 771 | setlocale (LC_ALL, ""); | 815 | setlocale(LC_ALL, ""); |
| 772 | bindtextdomain (PACKAGE, LOCALEDIR); | 816 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 773 | textdomain (PACKAGE); | 817 | textdomain(PACKAGE); |
| 774 | 818 | ||
| 775 | result = offset_result = jitter_result = STATE_OK; | 819 | result = offset_result = jitter_result = STATE_OK; |
| 776 | 820 | ||
| 777 | /* Parse extra opts if any */ | 821 | /* Parse extra opts if any */ |
| 778 | argv=np_extra_opts (&argc, argv, progname); | 822 | argv = np_extra_opts(&argc, argv, progname); |
| 779 | 823 | ||
| 780 | if (process_arguments (argc, argv) == ERROR) | 824 | if (process_arguments(argc, argv) == ERROR) { |
| 781 | usage4 (_("Could not parse arguments")); | 825 | usage4(_("Could not parse arguments")); |
| 826 | } | ||
| 782 | 827 | ||
| 783 | set_thresholds(&offset_thresholds, owarn, ocrit); | 828 | set_thresholds(&offset_thresholds, owarn, ocrit); |
| 784 | set_thresholds(&jitter_thresholds, jwarn, jcrit); | 829 | set_thresholds(&jitter_thresholds, jwarn, jcrit); |
| 785 | 830 | ||
| 786 | /* initialize alarm signal handling */ | 831 | /* initialize alarm signal handling */ |
| 787 | signal (SIGALRM, socket_timeout_alarm_handler); | 832 | signal(SIGALRM, socket_timeout_alarm_handler); |
| 788 | 833 | ||
| 789 | /* set socket timeout */ | 834 | /* set socket timeout */ |
| 790 | alarm (socket_timeout); | 835 | alarm(socket_timeout); |
| 791 | 836 | ||
| 792 | offset = offset_request(server_address, &offset_result); | 837 | offset = offset_request(server_address, &offset_result); |
| 793 | /* check_ntp used to always return CRITICAL if offset_result == STATE_UNKNOWN. | 838 | /* check_ntp used to always return CRITICAL if offset_result == STATE_UNKNOWN. |
| @@ -803,31 +848,32 @@ int main(int argc, char *argv[]){ | |||
| 803 | * servers recognize. Trying to check the jitter on OpenNTPD | 848 | * servers recognize. Trying to check the jitter on OpenNTPD |
| 804 | * (for example) will result in an error | 849 | * (for example) will result in an error |
| 805 | */ | 850 | */ |
| 806 | if(do_jitter){ | 851 | if (do_jitter) { |
| 807 | jitter=jitter_request(&jitter_result); | 852 | jitter = jitter_request(&jitter_result); |
| 808 | result = max_state_alt(result, get_status(jitter, jitter_thresholds)); | 853 | result = max_state_alt(result, get_status(jitter, jitter_thresholds)); |
| 809 | /* -1 indicates that we couldn't calculate the jitter | 854 | /* -1 indicates that we couldn't calculate the jitter |
| 810 | * Only overrides STATE_OK from the offset */ | 855 | * Only overrides STATE_OK from the offset */ |
| 811 | if(jitter == -1.0 && result == STATE_OK) | 856 | if (jitter == -1.0 && result == STATE_OK) { |
| 812 | result = STATE_UNKNOWN; | 857 | result = STATE_UNKNOWN; |
| 858 | } | ||
| 813 | } | 859 | } |
| 814 | result = max_state_alt(result, jitter_result); | 860 | result = max_state_alt(result, jitter_result); |
| 815 | 861 | ||
| 816 | switch (result) { | 862 | switch (result) { |
| 817 | case STATE_CRITICAL : | 863 | case STATE_CRITICAL: |
| 818 | xasprintf(&result_line, _("NTP CRITICAL:")); | 864 | xasprintf(&result_line, _("NTP CRITICAL:")); |
| 819 | break; | 865 | break; |
| 820 | case STATE_WARNING : | 866 | case STATE_WARNING: |
| 821 | xasprintf(&result_line, _("NTP WARNING:")); | 867 | xasprintf(&result_line, _("NTP WARNING:")); |
| 822 | break; | 868 | break; |
| 823 | case STATE_OK : | 869 | case STATE_OK: |
| 824 | xasprintf(&result_line, _("NTP OK:")); | 870 | xasprintf(&result_line, _("NTP OK:")); |
| 825 | break; | 871 | break; |
| 826 | default : | 872 | default: |
| 827 | xasprintf(&result_line, _("NTP UNKNOWN:")); | 873 | xasprintf(&result_line, _("NTP UNKNOWN:")); |
| 828 | break; | 874 | break; |
| 829 | } | 875 | } |
| 830 | if(offset_result == STATE_UNKNOWN){ | 876 | if (offset_result == STATE_UNKNOWN) { |
| 831 | xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); | 877 | xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); |
| 832 | xasprintf(&perfdata_line, ""); | 878 | xasprintf(&perfdata_line, ""); |
| 833 | } else { | 879 | } else { |
| @@ -836,41 +882,41 @@ int main(int argc, char *argv[]){ | |||
| 836 | } | 882 | } |
| 837 | if (do_jitter) { | 883 | if (do_jitter) { |
| 838 | xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); | 884 | xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); |
| 839 | xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); | 885 | xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); |
| 840 | } | 886 | } |
| 841 | printf("%s|%s\n", result_line, perfdata_line); | 887 | printf("%s|%s\n", result_line, perfdata_line); |
| 842 | 888 | ||
| 843 | if(server_address!=NULL) free(server_address); | 889 | if (server_address != NULL) { |
| 890 | free(server_address); | ||
| 891 | } | ||
| 844 | return result; | 892 | return result; |
| 845 | } | 893 | } |
| 846 | 894 | ||
| 847 | 895 | void print_help(void) { | |
| 848 | |||
| 849 | void print_help(void){ | ||
| 850 | print_revision(progname, NP_VERSION); | 896 | print_revision(progname, NP_VERSION); |
| 851 | 897 | ||
| 852 | printf ("Copyright (c) 2006 Sean Finney\n"); | 898 | printf("Copyright (c) 2006 Sean Finney\n"); |
| 853 | printf (COPYRIGHT, copyright, email); | 899 | printf(COPYRIGHT, copyright, email); |
| 854 | 900 | ||
| 855 | printf ("%s\n", _("This plugin checks the selected ntp server")); | 901 | printf("%s\n", _("This plugin checks the selected ntp server")); |
| 856 | 902 | ||
| 857 | printf ("\n\n"); | 903 | printf("\n\n"); |
| 858 | 904 | ||
| 859 | print_usage(); | 905 | print_usage(); |
| 860 | printf (UT_HELP_VRSN); | 906 | printf(UT_HELP_VRSN); |
| 861 | printf (UT_EXTRA_OPTS); | 907 | printf(UT_EXTRA_OPTS); |
| 862 | printf (UT_HOST_PORT, 'p', "123"); | 908 | printf(UT_HOST_PORT, 'p', "123"); |
| 863 | printf (UT_IPv46); | 909 | printf(UT_IPv46); |
| 864 | printf (" %s\n", "-w, --warning=THRESHOLD"); | 910 | printf(" %s\n", "-w, --warning=THRESHOLD"); |
| 865 | printf (" %s\n", _("Offset to result in warning status (seconds)")); | 911 | printf(" %s\n", _("Offset to result in warning status (seconds)")); |
| 866 | printf (" %s\n", "-c, --critical=THRESHOLD"); | 912 | printf(" %s\n", "-c, --critical=THRESHOLD"); |
| 867 | printf (" %s\n", _("Offset to result in critical status (seconds)")); | 913 | printf(" %s\n", _("Offset to result in critical status (seconds)")); |
| 868 | printf (" %s\n", "-j, --jwarn=THRESHOLD"); | 914 | printf(" %s\n", "-j, --jwarn=THRESHOLD"); |
| 869 | printf (" %s\n", _("Warning threshold for jitter")); | 915 | printf(" %s\n", _("Warning threshold for jitter")); |
| 870 | printf (" %s\n", "-k, --jcrit=THRESHOLD"); | 916 | printf(" %s\n", "-k, --jcrit=THRESHOLD"); |
| 871 | printf (" %s\n", _("Critical threshold for jitter")); | 917 | printf(" %s\n", _("Critical threshold for jitter")); |
| 872 | printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 918 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 873 | printf (UT_VERBOSE); | 919 | printf(UT_VERBOSE); |
| 874 | 920 | ||
| 875 | printf("\n"); | 921 | printf("\n"); |
| 876 | printf("%s\n", _("Notes:")); | 922 | printf("%s\n", _("Notes:")); |
| @@ -881,21 +927,21 @@ void print_help(void){ | |||
| 881 | printf(" %s\n", _("Normal offset check:")); | 927 | printf(" %s\n", _("Normal offset check:")); |
| 882 | printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1")); | 928 | printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1")); |
| 883 | printf("\n"); | 929 | printf("\n"); |
| 884 | printf(" %s\n", _("Check jitter too, avoiding critical notifications if jitter isn't available")); | 930 | printf(" %s\n", |
| 931 | _("Check jitter too, avoiding critical notifications if jitter isn't available")); | ||
| 885 | printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); | 932 | printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); |
| 886 | printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); | 933 | printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); |
| 887 | 934 | ||
| 888 | printf (UT_SUPPORT); | 935 | printf(UT_SUPPORT); |
| 889 | 936 | ||
| 890 | printf ("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); | 937 | printf("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); |
| 891 | printf ("%s\n\n", _("check_ntp_time instead.")); | 938 | printf("%s\n\n", _("check_ntp_time instead.")); |
| 892 | } | 939 | } |
| 893 | 940 | ||
| 894 | void | 941 | void print_usage(void) { |
| 895 | print_usage(void) | 942 | printf("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); |
| 896 | { | 943 | printf("%s\n\n", _("check_ntp_time instead.")); |
| 897 | printf ("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); | 944 | printf("%s\n", _("Usage:")); |
| 898 | printf ("%s\n\n", _("check_ntp_time instead.")); | 945 | printf(" %s -H <host> [-w <warn>] [-c <crit>] [-j <warn>] [-k <crit>] [-4|-6] [-v verbose]\n", |
| 899 | printf ("%s\n", _("Usage:")); | 946 | progname); |
| 900 | printf(" %s -H <host> [-w <warn>] [-c <crit>] [-j <warn>] [-k <crit>] [-4|-6] [-v verbose]\n", progname); | ||
| 901 | } | 947 | } |
