summaryrefslogtreecommitdiffstats
path: root/plugins/check_ntp.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_ntp.c')
-rw-r--r--plugins/check_ntp.c756
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
33const char *progname = "check_ntp"; 33const char *progname = "check_ntp";
34const char *copyright = "2006-2024"; 34const 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
41static char *server_address=NULL; 41static char *server_address = NULL;
42static int verbose=0; 42static int verbose = 0;
43static bool do_offset = false; 43static bool do_offset = false;
44static char *owarn="60"; 44static char *owarn = "60";
45static char *ocrit="120"; 45static char *ocrit = "120";
46static bool do_jitter = false; 46static bool do_jitter = false;
47static char *jwarn="5000"; 47static char *jwarn = "5000";
48static char *jcrit="10000"; 48static char *jcrit = "10000";
49 49
50static int process_arguments (int /*argc*/, char ** /*argv*/); 50static int process_arguments(int /*argc*/, char ** /*argv*/);
51static thresholds *offset_thresholds = NULL; 51static thresholds *offset_thresholds = NULL;
52static thresholds *jitter_thresholds = NULL; 52static thresholds *jitter_thresholds = NULL;
53static void print_help (void); 53static void print_help(void);
54void print_usage (void); 54void 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 */
65typedef struct { 65typedef 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 */
91typedef struct { 91typedef 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 */
209static inline double calc_offset(const ntp_message *m, const struct timeval *t){ 231static 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 */
219void print_ntp_message(const ntp_message *p){ 241void 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
244void print_ntp_control_message(const ntp_control_message *p){ 266void 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
280void setup_request(ntp_message *p){ 301void 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. */
299int best_offset_server(const ntp_server_results *slist, int nservers){ 320int 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 :( */
357double offset_request(const char *host, int *status){ 382double 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
503void 545void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) {
504setup_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 */
515double jitter_request(int *status){ 556double 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
663int process_arguments(int argc, char **argv){ 718int 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
750char *perfd_offset (double offset) 800char *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
758char *perfd_jitter (double jitter) 805char *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
766int main(int argc, char *argv[]){ 810int 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 895void print_help(void) {
848
849void 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
894void 941void print_usage(void) {
895print_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}