1 /* $NetBSD: ntp_control.c,v 1.7 2013/12/28 03:20:14 christos Exp $ */ 2 3 /* 4 * ntp_control.c - respond to mode 6 control messages and send async 5 * traps. Provides service to ntpq and others. 6 */ 7 8 #ifdef HAVE_CONFIG_H 9 # include <config.h> 10 #endif 11 12 #include <stdio.h> 13 #include <ctype.h> 14 #include <signal.h> 15 #include <sys/stat.h> 16 #ifdef HAVE_NETINET_IN_H 17 # include <netinet/in.h> 18 #endif 19 #include <arpa/inet.h> 20 21 #include "ntpd.h" 22 #include "ntp_io.h" 23 #include "ntp_refclock.h" 24 #include "ntp_control.h" 25 #include "ntp_unixtime.h" 26 #include "ntp_stdlib.h" 27 #include "ntp_config.h" 28 #include "ntp_crypto.h" 29 #include "ntp_assert.h" 30 #include "ntp_leapsec.h" 31 #include "ntp_md5.h" /* provides OpenSSL digest API */ 32 #include "lib_strbuf.h" 33 #ifdef KERNEL_PLL 34 # include "ntp_syscall.h" 35 #endif 36 37 38 /* 39 * Structure to hold request procedure information 40 */ 41 42 struct ctl_proc { 43 short control_code; /* defined request code */ 44 #define NO_REQUEST (-1) 45 u_short flags; /* flags word */ 46 /* Only one flag. Authentication required or not. */ 47 #define NOAUTH 0 48 #define AUTH 1 49 void (*handler) (struct recvbuf *, int); /* handle request */ 50 }; 51 52 53 /* 54 * Request processing routines 55 */ 56 static void ctl_error (u_char); 57 #ifdef REFCLOCK 58 static u_short ctlclkstatus (struct refclockstat *); 59 #endif 60 static void ctl_flushpkt (u_char); 61 static void ctl_putdata (const char *, unsigned int, int); 62 static void ctl_putstr (const char *, const char *, size_t); 63 static void ctl_putdblf (const char *, const char *, double); 64 const char ctl_def_dbl_fmt[] = "%.3f"; 65 #define ctl_putdbl(tag, d) ctl_putdblf(tag, ctl_def_dbl_fmt, d) 66 const char ctl_def_dbl6_fmt[] = "%.6f"; 67 #define ctl_putdbl6(tag, d) ctl_putdblf(tag, ctl_def_dbl6_fmt, d) 68 const char ctl_def_sfp_fmt[] = "%g"; 69 #define ctl_putsfp(tag, sfp) ctl_putdblf(tag, ctl_def_sfp_fmt, \ 70 FPTOD(sfp)) 71 static void ctl_putuint (const char *, u_long); 72 static void ctl_puthex (const char *, u_long); 73 static void ctl_putint (const char *, long); 74 static void ctl_putts (const char *, l_fp *); 75 static void ctl_putadr (const char *, u_int32, 76 sockaddr_u *); 77 static void ctl_putrefid (const char *, u_int32); 78 static void ctl_putarray (const char *, double *, int); 79 static void ctl_putsys (int); 80 static void ctl_putpeer (int, struct peer *); 81 static void ctl_putfs (const char *, tstamp_t); 82 #ifdef REFCLOCK 83 static void ctl_putclock (int, struct refclockstat *, int); 84 #endif /* REFCLOCK */ 85 static const struct ctl_var *ctl_getitem(const struct ctl_var *, 86 char **); 87 static u_short count_var (const struct ctl_var *); 88 static void control_unspec (struct recvbuf *, int); 89 static void read_status (struct recvbuf *, int); 90 static void read_sysvars (void); 91 static void read_peervars (void); 92 static void read_variables (struct recvbuf *, int); 93 static void write_variables (struct recvbuf *, int); 94 static void read_clockstatus(struct recvbuf *, int); 95 static void write_clockstatus(struct recvbuf *, int); 96 static void set_trap (struct recvbuf *, int); 97 static void save_config (struct recvbuf *, int); 98 static void configure (struct recvbuf *, int); 99 static void send_mru_entry (mon_entry *, int); 100 static void send_random_tag_value(int); 101 static void read_mru_list (struct recvbuf *, int); 102 static void send_ifstats_entry(endpt *, u_int); 103 static void read_ifstats (struct recvbuf *); 104 static void sockaddrs_from_restrict_u(sockaddr_u *, sockaddr_u *, 105 restrict_u *, int); 106 static void send_restrict_entry(restrict_u *, int, u_int); 107 static void send_restrict_list(restrict_u *, int, u_int *); 108 static void read_addr_restrictions(struct recvbuf *); 109 static void read_ordlist (struct recvbuf *, int); 110 static u_int32 derive_nonce (sockaddr_u *, u_int32, u_int32); 111 static void generate_nonce (struct recvbuf *, char *, size_t); 112 static int validate_nonce (const char *, struct recvbuf *); 113 static void req_nonce (struct recvbuf *, int); 114 static void unset_trap (struct recvbuf *, int); 115 static struct ctl_trap *ctlfindtrap(sockaddr_u *, 116 struct interface *); 117 118 static const struct ctl_proc control_codes[] = { 119 { CTL_OP_UNSPEC, NOAUTH, control_unspec }, 120 { CTL_OP_READSTAT, NOAUTH, read_status }, 121 { CTL_OP_READVAR, NOAUTH, read_variables }, 122 { CTL_OP_WRITEVAR, AUTH, write_variables }, 123 { CTL_OP_READCLOCK, NOAUTH, read_clockstatus }, 124 { CTL_OP_WRITECLOCK, NOAUTH, write_clockstatus }, 125 { CTL_OP_SETTRAP, NOAUTH, set_trap }, 126 { CTL_OP_CONFIGURE, AUTH, configure }, 127 { CTL_OP_SAVECONFIG, AUTH, save_config }, 128 { CTL_OP_READ_MRU, NOAUTH, read_mru_list }, 129 { CTL_OP_READ_ORDLIST_A, AUTH, read_ordlist }, 130 { CTL_OP_REQ_NONCE, NOAUTH, req_nonce }, 131 { CTL_OP_UNSETTRAP, NOAUTH, unset_trap }, 132 { NO_REQUEST, 0, NULL } 133 }; 134 135 /* 136 * System variables we understand 137 */ 138 #define CS_LEAP 1 139 #define CS_STRATUM 2 140 #define CS_PRECISION 3 141 #define CS_ROOTDELAY 4 142 #define CS_ROOTDISPERSION 5 143 #define CS_REFID 6 144 #define CS_REFTIME 7 145 #define CS_POLL 8 146 #define CS_PEERID 9 147 #define CS_OFFSET 10 148 #define CS_DRIFT 11 149 #define CS_JITTER 12 150 #define CS_ERROR 13 151 #define CS_CLOCK 14 152 #define CS_PROCESSOR 15 153 #define CS_SYSTEM 16 154 #define CS_VERSION 17 155 #define CS_STABIL 18 156 #define CS_VARLIST 19 157 #define CS_TAI 20 158 #define CS_LEAPTAB 21 159 #define CS_LEAPEND 22 160 #define CS_RATE 23 161 #define CS_MRU_ENABLED 24 162 #define CS_MRU_DEPTH 25 163 #define CS_MRU_DEEPEST 26 164 #define CS_MRU_MINDEPTH 27 165 #define CS_MRU_MAXAGE 28 166 #define CS_MRU_MAXDEPTH 29 167 #define CS_MRU_MEM 30 168 #define CS_MRU_MAXMEM 31 169 #define CS_SS_UPTIME 32 170 #define CS_SS_RESET 33 171 #define CS_SS_RECEIVED 34 172 #define CS_SS_THISVER 35 173 #define CS_SS_OLDVER 36 174 #define CS_SS_BADFORMAT 37 175 #define CS_SS_BADAUTH 38 176 #define CS_SS_DECLINED 39 177 #define CS_SS_RESTRICTED 40 178 #define CS_SS_LIMITED 41 179 #define CS_SS_KODSENT 42 180 #define CS_SS_PROCESSED 43 181 #define CS_PEERADR 44 182 #define CS_PEERMODE 45 183 #define CS_BCASTDELAY 46 184 #define CS_AUTHDELAY 47 185 #define CS_AUTHKEYS 48 186 #define CS_AUTHFREEK 49 187 #define CS_AUTHKLOOKUPS 50 188 #define CS_AUTHKNOTFOUND 51 189 #define CS_AUTHKUNCACHED 52 190 #define CS_AUTHKEXPIRED 53 191 #define CS_AUTHENCRYPTS 54 192 #define CS_AUTHDECRYPTS 55 193 #define CS_AUTHRESET 56 194 #define CS_K_OFFSET 57 195 #define CS_K_FREQ 58 196 #define CS_K_MAXERR 59 197 #define CS_K_ESTERR 60 198 #define CS_K_STFLAGS 61 199 #define CS_K_TIMECONST 62 200 #define CS_K_PRECISION 63 201 #define CS_K_FREQTOL 64 202 #define CS_K_PPS_FREQ 65 203 #define CS_K_PPS_STABIL 66 204 #define CS_K_PPS_JITTER 67 205 #define CS_K_PPS_CALIBDUR 68 206 #define CS_K_PPS_CALIBS 69 207 #define CS_K_PPS_CALIBERRS 70 208 #define CS_K_PPS_JITEXC 71 209 #define CS_K_PPS_STBEXC 72 210 #define CS_KERN_FIRST CS_K_OFFSET 211 #define CS_KERN_LAST CS_K_PPS_STBEXC 212 #define CS_IOSTATS_RESET 73 213 #define CS_TOTAL_RBUF 74 214 #define CS_FREE_RBUF 75 215 #define CS_USED_RBUF 76 216 #define CS_RBUF_LOWATER 77 217 #define CS_IO_DROPPED 78 218 #define CS_IO_IGNORED 79 219 #define CS_IO_RECEIVED 80 220 #define CS_IO_SENT 81 221 #define CS_IO_SENDFAILED 82 222 #define CS_IO_WAKEUPS 83 223 #define CS_IO_GOODWAKEUPS 84 224 #define CS_TIMERSTATS_RESET 85 225 #define CS_TIMER_OVERRUNS 86 226 #define CS_TIMER_XMTS 87 227 #define CS_FUZZ 88 228 #define CS_MAX_NOAUTOKEY CS_FUZZ 229 #ifdef AUTOKEY 230 #define CS_FLAGS (1 + CS_MAX_NOAUTOKEY) 231 #define CS_HOST (2 + CS_MAX_NOAUTOKEY) 232 #define CS_PUBLIC (3 + CS_MAX_NOAUTOKEY) 233 #define CS_CERTIF (4 + CS_MAX_NOAUTOKEY) 234 #define CS_SIGNATURE (5 + CS_MAX_NOAUTOKEY) 235 #define CS_REVTIME (6 + CS_MAX_NOAUTOKEY) 236 #define CS_IDENT (7 + CS_MAX_NOAUTOKEY) 237 #define CS_DIGEST (8 + CS_MAX_NOAUTOKEY) 238 #define CS_MAXCODE CS_DIGEST 239 #else /* !AUTOKEY follows */ 240 #define CS_MAXCODE CS_MAX_NOAUTOKEY 241 #endif /* !AUTOKEY */ 242 243 /* 244 * Peer variables we understand 245 */ 246 #define CP_CONFIG 1 247 #define CP_AUTHENABLE 2 248 #define CP_AUTHENTIC 3 249 #define CP_SRCADR 4 250 #define CP_SRCPORT 5 251 #define CP_DSTADR 6 252 #define CP_DSTPORT 7 253 #define CP_LEAP 8 254 #define CP_HMODE 9 255 #define CP_STRATUM 10 256 #define CP_PPOLL 11 257 #define CP_HPOLL 12 258 #define CP_PRECISION 13 259 #define CP_ROOTDELAY 14 260 #define CP_ROOTDISPERSION 15 261 #define CP_REFID 16 262 #define CP_REFTIME 17 263 #define CP_ORG 18 264 #define CP_REC 19 265 #define CP_XMT 20 266 #define CP_REACH 21 267 #define CP_UNREACH 22 268 #define CP_TIMER 23 269 #define CP_DELAY 24 270 #define CP_OFFSET 25 271 #define CP_JITTER 26 272 #define CP_DISPERSION 27 273 #define CP_KEYID 28 274 #define CP_FILTDELAY 29 275 #define CP_FILTOFFSET 30 276 #define CP_PMODE 31 277 #define CP_RECEIVED 32 278 #define CP_SENT 33 279 #define CP_FILTERROR 34 280 #define CP_FLASH 35 281 #define CP_TTL 36 282 #define CP_VARLIST 37 283 #define CP_IN 38 284 #define CP_OUT 39 285 #define CP_RATE 40 286 #define CP_BIAS 41 287 #define CP_SRCHOST 42 288 #define CP_TIMEREC 43 289 #define CP_TIMEREACH 44 290 #define CP_BADAUTH 45 291 #define CP_BOGUSORG 46 292 #define CP_OLDPKT 47 293 #define CP_SELDISP 48 294 #define CP_SELBROKEN 49 295 #define CP_CANDIDATE 50 296 #define CP_MAX_NOAUTOKEY CP_CANDIDATE 297 #ifdef AUTOKEY 298 #define CP_FLAGS (1 + CP_MAX_NOAUTOKEY) 299 #define CP_HOST (2 + CP_MAX_NOAUTOKEY) 300 #define CP_VALID (3 + CP_MAX_NOAUTOKEY) 301 #define CP_INITSEQ (4 + CP_MAX_NOAUTOKEY) 302 #define CP_INITKEY (5 + CP_MAX_NOAUTOKEY) 303 #define CP_INITTSP (6 + CP_MAX_NOAUTOKEY) 304 #define CP_SIGNATURE (7 + CP_MAX_NOAUTOKEY) 305 #define CP_IDENT (8 + CP_MAX_NOAUTOKEY) 306 #define CP_MAXCODE CP_IDENT 307 #else /* !AUTOKEY follows */ 308 #define CP_MAXCODE CP_MAX_NOAUTOKEY 309 #endif /* !AUTOKEY */ 310 311 /* 312 * Clock variables we understand 313 */ 314 #define CC_TYPE 1 315 #define CC_TIMECODE 2 316 #define CC_POLL 3 317 #define CC_NOREPLY 4 318 #define CC_BADFORMAT 5 319 #define CC_BADDATA 6 320 #define CC_FUDGETIME1 7 321 #define CC_FUDGETIME2 8 322 #define CC_FUDGEVAL1 9 323 #define CC_FUDGEVAL2 10 324 #define CC_FLAGS 11 325 #define CC_DEVICE 12 326 #define CC_VARLIST 13 327 #define CC_MAXCODE CC_VARLIST 328 329 /* 330 * System variable values. The array can be indexed by the variable 331 * index to find the textual name. 332 */ 333 static const struct ctl_var sys_var[] = { 334 { 0, PADDING, "" }, /* 0 */ 335 { CS_LEAP, RW, "leap" }, /* 1 */ 336 { CS_STRATUM, RO, "stratum" }, /* 2 */ 337 { CS_PRECISION, RO, "precision" }, /* 3 */ 338 { CS_ROOTDELAY, RO, "rootdelay" }, /* 4 */ 339 { CS_ROOTDISPERSION, RO, "rootdisp" }, /* 5 */ 340 { CS_REFID, RO, "refid" }, /* 6 */ 341 { CS_REFTIME, RO, "reftime" }, /* 7 */ 342 { CS_POLL, RO, "tc" }, /* 8 */ 343 { CS_PEERID, RO, "peer" }, /* 9 */ 344 { CS_OFFSET, RO, "offset" }, /* 10 */ 345 { CS_DRIFT, RO, "frequency" }, /* 11 */ 346 { CS_JITTER, RO, "sys_jitter" }, /* 12 */ 347 { CS_ERROR, RO, "clk_jitter" }, /* 13 */ 348 { CS_CLOCK, RO, "clock" }, /* 14 */ 349 { CS_PROCESSOR, RO, "processor" }, /* 15 */ 350 { CS_SYSTEM, RO, "system" }, /* 16 */ 351 { CS_VERSION, RO, "version" }, /* 17 */ 352 { CS_STABIL, RO, "clk_wander" }, /* 18 */ 353 { CS_VARLIST, RO, "sys_var_list" }, /* 19 */ 354 { CS_TAI, RO, "tai" }, /* 20 */ 355 { CS_LEAPTAB, RO, "leapsec" }, /* 21 */ 356 { CS_LEAPEND, RO, "expire" }, /* 22 */ 357 { CS_RATE, RO, "mintc" }, /* 23 */ 358 { CS_MRU_ENABLED, RO, "mru_enabled" }, /* 24 */ 359 { CS_MRU_DEPTH, RO, "mru_depth" }, /* 25 */ 360 { CS_MRU_DEEPEST, RO, "mru_deepest" }, /* 26 */ 361 { CS_MRU_MINDEPTH, RO, "mru_mindepth" }, /* 27 */ 362 { CS_MRU_MAXAGE, RO, "mru_maxage" }, /* 28 */ 363 { CS_MRU_MAXDEPTH, RO, "mru_maxdepth" }, /* 29 */ 364 { CS_MRU_MEM, RO, "mru_mem" }, /* 30 */ 365 { CS_MRU_MAXMEM, RO, "mru_maxmem" }, /* 31 */ 366 { CS_SS_UPTIME, RO, "ss_uptime" }, /* 32 */ 367 { CS_SS_RESET, RO, "ss_reset" }, /* 33 */ 368 { CS_SS_RECEIVED, RO, "ss_received" }, /* 34 */ 369 { CS_SS_THISVER, RO, "ss_thisver" }, /* 35 */ 370 { CS_SS_OLDVER, RO, "ss_oldver" }, /* 36 */ 371 { CS_SS_BADFORMAT, RO, "ss_badformat" }, /* 37 */ 372 { CS_SS_BADAUTH, RO, "ss_badauth" }, /* 38 */ 373 { CS_SS_DECLINED, RO, "ss_declined" }, /* 39 */ 374 { CS_SS_RESTRICTED, RO, "ss_restricted" }, /* 40 */ 375 { CS_SS_LIMITED, RO, "ss_limited" }, /* 41 */ 376 { CS_SS_KODSENT, RO, "ss_kodsent" }, /* 42 */ 377 { CS_SS_PROCESSED, RO, "ss_processed" }, /* 43 */ 378 { CS_PEERADR, RO, "peeradr" }, /* 44 */ 379 { CS_PEERMODE, RO, "peermode" }, /* 45 */ 380 { CS_BCASTDELAY, RO, "bcastdelay" }, /* 46 */ 381 { CS_AUTHDELAY, RO, "authdelay" }, /* 47 */ 382 { CS_AUTHKEYS, RO, "authkeys" }, /* 48 */ 383 { CS_AUTHFREEK, RO, "authfreek" }, /* 49 */ 384 { CS_AUTHKLOOKUPS, RO, "authklookups" }, /* 50 */ 385 { CS_AUTHKNOTFOUND, RO, "authknotfound" }, /* 51 */ 386 { CS_AUTHKUNCACHED, RO, "authkuncached" }, /* 52 */ 387 { CS_AUTHKEXPIRED, RO, "authkexpired" }, /* 53 */ 388 { CS_AUTHENCRYPTS, RO, "authencrypts" }, /* 54 */ 389 { CS_AUTHDECRYPTS, RO, "authdecrypts" }, /* 55 */ 390 { CS_AUTHRESET, RO, "authreset" }, /* 56 */ 391 { CS_K_OFFSET, RO, "koffset" }, /* 57 */ 392 { CS_K_FREQ, RO, "kfreq" }, /* 58 */ 393 { CS_K_MAXERR, RO, "kmaxerr" }, /* 59 */ 394 { CS_K_ESTERR, RO, "kesterr" }, /* 60 */ 395 { CS_K_STFLAGS, RO, "kstflags" }, /* 61 */ 396 { CS_K_TIMECONST, RO, "ktimeconst" }, /* 62 */ 397 { CS_K_PRECISION, RO, "kprecis" }, /* 63 */ 398 { CS_K_FREQTOL, RO, "kfreqtol" }, /* 64 */ 399 { CS_K_PPS_FREQ, RO, "kppsfreq" }, /* 65 */ 400 { CS_K_PPS_STABIL, RO, "kppsstab" }, /* 66 */ 401 { CS_K_PPS_JITTER, RO, "kppsjitter" }, /* 67 */ 402 { CS_K_PPS_CALIBDUR, RO, "kppscalibdur" }, /* 68 */ 403 { CS_K_PPS_CALIBS, RO, "kppscalibs" }, /* 69 */ 404 { CS_K_PPS_CALIBERRS, RO, "kppscaliberrs" }, /* 70 */ 405 { CS_K_PPS_JITEXC, RO, "kppsjitexc" }, /* 71 */ 406 { CS_K_PPS_STBEXC, RO, "kppsstbexc" }, /* 72 */ 407 { CS_IOSTATS_RESET, RO, "iostats_reset" }, /* 73 */ 408 { CS_TOTAL_RBUF, RO, "total_rbuf" }, /* 74 */ 409 { CS_FREE_RBUF, RO, "free_rbuf" }, /* 75 */ 410 { CS_USED_RBUF, RO, "used_rbuf" }, /* 76 */ 411 { CS_RBUF_LOWATER, RO, "rbuf_lowater" }, /* 77 */ 412 { CS_IO_DROPPED, RO, "io_dropped" }, /* 78 */ 413 { CS_IO_IGNORED, RO, "io_ignored" }, /* 79 */ 414 { CS_IO_RECEIVED, RO, "io_received" }, /* 80 */ 415 { CS_IO_SENT, RO, "io_sent" }, /* 81 */ 416 { CS_IO_SENDFAILED, RO, "io_sendfailed" }, /* 82 */ 417 { CS_IO_WAKEUPS, RO, "io_wakeups" }, /* 83 */ 418 { CS_IO_GOODWAKEUPS, RO, "io_goodwakeups" }, /* 84 */ 419 { CS_TIMERSTATS_RESET, RO, "timerstats_reset" },/* 85 */ 420 { CS_TIMER_OVERRUNS, RO, "timer_overruns" }, /* 86 */ 421 { CS_TIMER_XMTS, RO, "timer_xmts" }, /* 87 */ 422 { CS_FUZZ, RO, "fuzz" }, /* 88 */ 423 #ifdef AUTOKEY 424 { CS_FLAGS, RO, "flags" }, /* 1 + CS_MAX_NOAUTOKEY */ 425 { CS_HOST, RO, "host" }, /* 2 + CS_MAX_NOAUTOKEY */ 426 { CS_PUBLIC, RO, "update" }, /* 3 + CS_MAX_NOAUTOKEY */ 427 { CS_CERTIF, RO, "cert" }, /* 4 + CS_MAX_NOAUTOKEY */ 428 { CS_SIGNATURE, RO, "signature" }, /* 5 + CS_MAX_NOAUTOKEY */ 429 { CS_REVTIME, RO, "until" }, /* 6 + CS_MAX_NOAUTOKEY */ 430 { CS_IDENT, RO, "ident" }, /* 7 + CS_MAX_NOAUTOKEY */ 431 { CS_DIGEST, RO, "digest" }, /* 8 + CS_MAX_NOAUTOKEY */ 432 #endif /* AUTOKEY */ 433 { 0, EOV, "" } /* 87/95 */ 434 }; 435 436 static struct ctl_var *ext_sys_var = NULL; 437 438 /* 439 * System variables we print by default (in fuzzball order, 440 * more-or-less) 441 */ 442 static const u_char def_sys_var[] = { 443 CS_VERSION, 444 CS_PROCESSOR, 445 CS_SYSTEM, 446 CS_LEAP, 447 CS_STRATUM, 448 CS_PRECISION, 449 CS_ROOTDELAY, 450 CS_ROOTDISPERSION, 451 CS_REFID, 452 CS_REFTIME, 453 CS_CLOCK, 454 CS_PEERID, 455 CS_POLL, 456 CS_RATE, 457 CS_OFFSET, 458 CS_DRIFT, 459 CS_JITTER, 460 CS_ERROR, 461 CS_STABIL, 462 CS_TAI, 463 CS_LEAPTAB, 464 CS_LEAPEND, 465 #ifdef AUTOKEY 466 CS_HOST, 467 CS_IDENT, 468 CS_FLAGS, 469 CS_DIGEST, 470 CS_SIGNATURE, 471 CS_PUBLIC, 472 CS_CERTIF, 473 #endif /* AUTOKEY */ 474 0 475 }; 476 477 478 /* 479 * Peer variable list 480 */ 481 static const struct ctl_var peer_var[] = { 482 { 0, PADDING, "" }, /* 0 */ 483 { CP_CONFIG, RO, "config" }, /* 1 */ 484 { CP_AUTHENABLE, RO, "authenable" }, /* 2 */ 485 { CP_AUTHENTIC, RO, "authentic" }, /* 3 */ 486 { CP_SRCADR, RO, "srcadr" }, /* 4 */ 487 { CP_SRCPORT, RO, "srcport" }, /* 5 */ 488 { CP_DSTADR, RO, "dstadr" }, /* 6 */ 489 { CP_DSTPORT, RO, "dstport" }, /* 7 */ 490 { CP_LEAP, RO, "leap" }, /* 8 */ 491 { CP_HMODE, RO, "hmode" }, /* 9 */ 492 { CP_STRATUM, RO, "stratum" }, /* 10 */ 493 { CP_PPOLL, RO, "ppoll" }, /* 11 */ 494 { CP_HPOLL, RO, "hpoll" }, /* 12 */ 495 { CP_PRECISION, RO, "precision" }, /* 13 */ 496 { CP_ROOTDELAY, RO, "rootdelay" }, /* 14 */ 497 { CP_ROOTDISPERSION, RO, "rootdisp" }, /* 15 */ 498 { CP_REFID, RO, "refid" }, /* 16 */ 499 { CP_REFTIME, RO, "reftime" }, /* 17 */ 500 { CP_ORG, RO, "org" }, /* 18 */ 501 { CP_REC, RO, "rec" }, /* 19 */ 502 { CP_XMT, RO, "xleave" }, /* 20 */ 503 { CP_REACH, RO, "reach" }, /* 21 */ 504 { CP_UNREACH, RO, "unreach" }, /* 22 */ 505 { CP_TIMER, RO, "timer" }, /* 23 */ 506 { CP_DELAY, RO, "delay" }, /* 24 */ 507 { CP_OFFSET, RO, "offset" }, /* 25 */ 508 { CP_JITTER, RO, "jitter" }, /* 26 */ 509 { CP_DISPERSION, RO, "dispersion" }, /* 27 */ 510 { CP_KEYID, RO, "keyid" }, /* 28 */ 511 { CP_FILTDELAY, RO, "filtdelay" }, /* 29 */ 512 { CP_FILTOFFSET, RO, "filtoffset" }, /* 30 */ 513 { CP_PMODE, RO, "pmode" }, /* 31 */ 514 { CP_RECEIVED, RO, "received"}, /* 32 */ 515 { CP_SENT, RO, "sent" }, /* 33 */ 516 { CP_FILTERROR, RO, "filtdisp" }, /* 34 */ 517 { CP_FLASH, RO, "flash" }, /* 35 */ 518 { CP_TTL, RO, "ttl" }, /* 36 */ 519 { CP_VARLIST, RO, "peer_var_list" }, /* 37 */ 520 { CP_IN, RO, "in" }, /* 38 */ 521 { CP_OUT, RO, "out" }, /* 39 */ 522 { CP_RATE, RO, "headway" }, /* 40 */ 523 { CP_BIAS, RO, "bias" }, /* 41 */ 524 { CP_SRCHOST, RO, "srchost" }, /* 42 */ 525 { CP_TIMEREC, RO, "timerec" }, /* 43 */ 526 { CP_TIMEREACH, RO, "timereach" }, /* 44 */ 527 { CP_BADAUTH, RO, "badauth" }, /* 45 */ 528 { CP_BOGUSORG, RO, "bogusorg" }, /* 46 */ 529 { CP_OLDPKT, RO, "oldpkt" }, /* 47 */ 530 { CP_SELDISP, RO, "seldisp" }, /* 48 */ 531 { CP_SELBROKEN, RO, "selbroken" }, /* 49 */ 532 { CP_CANDIDATE, RO, "candidate" }, /* 50 */ 533 #ifdef AUTOKEY 534 { CP_FLAGS, RO, "flags" }, /* 1 + CP_MAX_NOAUTOKEY */ 535 { CP_HOST, RO, "host" }, /* 2 + CP_MAX_NOAUTOKEY */ 536 { CP_VALID, RO, "valid" }, /* 3 + CP_MAX_NOAUTOKEY */ 537 { CP_INITSEQ, RO, "initsequence" }, /* 4 + CP_MAX_NOAUTOKEY */ 538 { CP_INITKEY, RO, "initkey" }, /* 5 + CP_MAX_NOAUTOKEY */ 539 { CP_INITTSP, RO, "timestamp" }, /* 6 + CP_MAX_NOAUTOKEY */ 540 { CP_SIGNATURE, RO, "signature" }, /* 7 + CP_MAX_NOAUTOKEY */ 541 { CP_IDENT, RO, "ident" }, /* 8 + CP_MAX_NOAUTOKEY */ 542 #endif /* AUTOKEY */ 543 { 0, EOV, "" } /* 50/58 */ 544 }; 545 546 547 /* 548 * Peer variables we print by default 549 */ 550 static const u_char def_peer_var[] = { 551 CP_SRCADR, 552 CP_SRCPORT, 553 CP_SRCHOST, 554 CP_DSTADR, 555 CP_DSTPORT, 556 CP_OUT, 557 CP_IN, 558 CP_LEAP, 559 CP_STRATUM, 560 CP_PRECISION, 561 CP_ROOTDELAY, 562 CP_ROOTDISPERSION, 563 CP_REFID, 564 CP_REFTIME, 565 CP_REC, 566 CP_REACH, 567 CP_UNREACH, 568 CP_HMODE, 569 CP_PMODE, 570 CP_HPOLL, 571 CP_PPOLL, 572 CP_RATE, 573 CP_FLASH, 574 CP_KEYID, 575 CP_TTL, 576 CP_OFFSET, 577 CP_DELAY, 578 CP_DISPERSION, 579 CP_JITTER, 580 CP_XMT, 581 CP_BIAS, 582 CP_FILTDELAY, 583 CP_FILTOFFSET, 584 CP_FILTERROR, 585 #ifdef AUTOKEY 586 CP_HOST, 587 CP_FLAGS, 588 CP_SIGNATURE, 589 CP_VALID, 590 CP_INITSEQ, 591 CP_IDENT, 592 #endif /* AUTOKEY */ 593 0 594 }; 595 596 597 #ifdef REFCLOCK 598 /* 599 * Clock variable list 600 */ 601 static const struct ctl_var clock_var[] = { 602 { 0, PADDING, "" }, /* 0 */ 603 { CC_TYPE, RO, "type" }, /* 1 */ 604 { CC_TIMECODE, RO, "timecode" }, /* 2 */ 605 { CC_POLL, RO, "poll" }, /* 3 */ 606 { CC_NOREPLY, RO, "noreply" }, /* 4 */ 607 { CC_BADFORMAT, RO, "badformat" }, /* 5 */ 608 { CC_BADDATA, RO, "baddata" }, /* 6 */ 609 { CC_FUDGETIME1, RO, "fudgetime1" }, /* 7 */ 610 { CC_FUDGETIME2, RO, "fudgetime2" }, /* 8 */ 611 { CC_FUDGEVAL1, RO, "stratum" }, /* 9 */ 612 { CC_FUDGEVAL2, RO, "refid" }, /* 10 */ 613 { CC_FLAGS, RO, "flags" }, /* 11 */ 614 { CC_DEVICE, RO, "device" }, /* 12 */ 615 { CC_VARLIST, RO, "clock_var_list" }, /* 13 */ 616 { 0, EOV, "" } /* 14 */ 617 }; 618 619 620 /* 621 * Clock variables printed by default 622 */ 623 static const u_char def_clock_var[] = { 624 CC_DEVICE, 625 CC_TYPE, /* won't be output if device = known */ 626 CC_TIMECODE, 627 CC_POLL, 628 CC_NOREPLY, 629 CC_BADFORMAT, 630 CC_BADDATA, 631 CC_FUDGETIME1, 632 CC_FUDGETIME2, 633 CC_FUDGEVAL1, 634 CC_FUDGEVAL2, 635 CC_FLAGS, 636 0 637 }; 638 #endif 639 640 /* 641 * MRU string constants shared by send_mru_entry() and read_mru_list(). 642 */ 643 static const char addr_fmt[] = "addr.%d"; 644 static const char last_fmt[] = "last.%d"; 645 646 /* 647 * System and processor definitions. 648 */ 649 #ifndef HAVE_UNAME 650 # ifndef STR_SYSTEM 651 # define STR_SYSTEM "UNIX" 652 # endif 653 # ifndef STR_PROCESSOR 654 # define STR_PROCESSOR "unknown" 655 # endif 656 657 static const char str_system[] = STR_SYSTEM; 658 static const char str_processor[] = STR_PROCESSOR; 659 #else 660 # include <sys/utsname.h> 661 static struct utsname utsnamebuf; 662 #endif /* HAVE_UNAME */ 663 664 /* 665 * Trap structures. We only allow a few of these, and send a copy of 666 * each async message to each live one. Traps time out after an hour, it 667 * is up to the trap receipient to keep resetting it to avoid being 668 * timed out. 669 */ 670 /* ntp_request.c */ 671 struct ctl_trap ctl_traps[CTL_MAXTRAPS]; 672 int num_ctl_traps; 673 674 /* 675 * Type bits, for ctlsettrap() call. 676 */ 677 #define TRAP_TYPE_CONFIG 0 /* used by configuration code */ 678 #define TRAP_TYPE_PRIO 1 /* priority trap */ 679 #define TRAP_TYPE_NONPRIO 2 /* nonpriority trap */ 680 681 682 /* 683 * List relating reference clock types to control message time sources. 684 * Index by the reference clock type. This list will only be used iff 685 * the reference clock driver doesn't set peer->sstclktype to something 686 * different than CTL_SST_TS_UNSPEC. 687 */ 688 #ifdef REFCLOCK 689 static const u_char clocktypes[] = { 690 CTL_SST_TS_NTP, /* REFCLK_NONE (0) */ 691 CTL_SST_TS_LOCAL, /* REFCLK_LOCALCLOCK (1) */ 692 CTL_SST_TS_UHF, /* deprecated REFCLK_GPS_TRAK (2) */ 693 CTL_SST_TS_HF, /* REFCLK_WWV_PST (3) */ 694 CTL_SST_TS_LF, /* REFCLK_WWVB_SPECTRACOM (4) */ 695 CTL_SST_TS_UHF, /* REFCLK_TRUETIME (5) */ 696 CTL_SST_TS_UHF, /* REFCLK_IRIG_AUDIO (6) */ 697 CTL_SST_TS_HF, /* REFCLK_CHU (7) */ 698 CTL_SST_TS_LF, /* REFCLOCK_PARSE (default) (8) */ 699 CTL_SST_TS_LF, /* REFCLK_GPS_MX4200 (9) */ 700 CTL_SST_TS_UHF, /* REFCLK_GPS_AS2201 (10) */ 701 CTL_SST_TS_UHF, /* REFCLK_GPS_ARBITER (11) */ 702 CTL_SST_TS_UHF, /* REFCLK_IRIG_TPRO (12) */ 703 CTL_SST_TS_ATOM, /* REFCLK_ATOM_LEITCH (13) */ 704 CTL_SST_TS_LF, /* deprecated REFCLK_MSF_EES (14) */ 705 CTL_SST_TS_NTP, /* not used (15) */ 706 CTL_SST_TS_UHF, /* REFCLK_IRIG_BANCOMM (16) */ 707 CTL_SST_TS_UHF, /* REFCLK_GPS_DATU (17) */ 708 CTL_SST_TS_TELEPHONE, /* REFCLK_NIST_ACTS (18) */ 709 CTL_SST_TS_HF, /* REFCLK_WWV_HEATH (19) */ 710 CTL_SST_TS_UHF, /* REFCLK_GPS_NMEA (20) */ 711 CTL_SST_TS_UHF, /* REFCLK_GPS_VME (21) */ 712 CTL_SST_TS_ATOM, /* REFCLK_ATOM_PPS (22) */ 713 CTL_SST_TS_NTP, /* not used (23) */ 714 CTL_SST_TS_NTP, /* not used (24) */ 715 CTL_SST_TS_NTP, /* not used (25) */ 716 CTL_SST_TS_UHF, /* REFCLK_GPS_HP (26) */ 717 CTL_SST_TS_LF, /* REFCLK_ARCRON_MSF (27) */ 718 CTL_SST_TS_UHF, /* REFCLK_SHM (28) */ 719 CTL_SST_TS_UHF, /* REFCLK_PALISADE (29) */ 720 CTL_SST_TS_UHF, /* REFCLK_ONCORE (30) */ 721 CTL_SST_TS_UHF, /* REFCLK_JUPITER (31) */ 722 CTL_SST_TS_LF, /* REFCLK_CHRONOLOG (32) */ 723 CTL_SST_TS_LF, /* REFCLK_DUMBCLOCK (33) */ 724 CTL_SST_TS_LF, /* REFCLK_ULINK (34) */ 725 CTL_SST_TS_LF, /* REFCLK_PCF (35) */ 726 CTL_SST_TS_HF, /* REFCLK_WWV (36) */ 727 CTL_SST_TS_LF, /* REFCLK_FG (37) */ 728 CTL_SST_TS_UHF, /* REFCLK_HOPF_SERIAL (38) */ 729 CTL_SST_TS_UHF, /* REFCLK_HOPF_PCI (39) */ 730 CTL_SST_TS_LF, /* REFCLK_JJY (40) */ 731 CTL_SST_TS_UHF, /* REFCLK_TT560 (41) */ 732 CTL_SST_TS_UHF, /* REFCLK_ZYFER (42) */ 733 CTL_SST_TS_UHF, /* REFCLK_RIPENCC (43) */ 734 CTL_SST_TS_UHF, /* REFCLK_NEOCLOCK4X (44) */ 735 CTL_SST_TS_UHF, /* REFCLK_TSYNCPCI (45) */ 736 }; 737 #endif /* REFCLOCK */ 738 739 740 /* 741 * Keyid used for authenticating write requests. 742 */ 743 keyid_t ctl_auth_keyid; 744 745 /* 746 * We keep track of the last error reported by the system internally 747 */ 748 static u_char ctl_sys_last_event; 749 static u_char ctl_sys_num_events; 750 751 752 /* 753 * Statistic counters to keep track of requests and responses. 754 */ 755 u_long ctltimereset; /* time stats reset */ 756 u_long numctlreq; /* number of requests we've received */ 757 u_long numctlbadpkts; /* number of bad control packets */ 758 u_long numctlresponses; /* number of resp packets sent with data */ 759 u_long numctlfrags; /* number of fragments sent */ 760 u_long numctlerrors; /* number of error responses sent */ 761 u_long numctltooshort; /* number of too short input packets */ 762 u_long numctlinputresp; /* number of responses on input */ 763 u_long numctlinputfrag; /* number of fragments on input */ 764 u_long numctlinputerr; /* number of input pkts with err bit set */ 765 u_long numctlbadoffset; /* number of input pkts with nonzero offset */ 766 u_long numctlbadversion; /* number of input pkts with unknown version */ 767 u_long numctldatatooshort; /* data too short for count */ 768 u_long numctlbadop; /* bad op code found in packet */ 769 u_long numasyncmsgs; /* number of async messages we've sent */ 770 771 /* 772 * Response packet used by these routines. Also some state information 773 * so that we can handle packet formatting within a common set of 774 * subroutines. Note we try to enter data in place whenever possible, 775 * but the need to set the more bit correctly means we occasionally 776 * use the extra buffer and copy. 777 */ 778 static struct ntp_control rpkt; 779 static u_char res_version; 780 static u_char res_opcode; 781 static associd_t res_associd; 782 static u_short res_frags; /* datagrams in this response */ 783 static int res_offset; /* offset of payload in response */ 784 static u_char * datapt; 785 static u_char * dataend; 786 static int datalinelen; 787 static int datanotbinflag; 788 static sockaddr_u *rmt_addr; 789 static struct interface *lcl_inter; 790 791 static u_char res_authenticate; 792 static u_char res_authokay; 793 static keyid_t res_keyid; 794 795 #define MAXDATALINELEN (72) 796 797 static u_char res_async; /* sending async trap response? */ 798 799 /* 800 * Pointers for saving state when decoding request packets 801 */ 802 static char *reqpt; 803 static char *reqend; 804 805 /* 806 * init_control - initialize request data 807 */ 808 void 809 init_control(void) 810 { 811 size_t i; 812 813 #ifdef HAVE_UNAME 814 uname(&utsnamebuf); 815 #endif /* HAVE_UNAME */ 816 817 ctl_clr_stats(); 818 819 ctl_auth_keyid = 0; 820 ctl_sys_last_event = EVNT_UNSPEC; 821 ctl_sys_num_events = 0; 822 823 num_ctl_traps = 0; 824 for (i = 0; i < COUNTOF(ctl_traps); i++) 825 ctl_traps[i].tr_flags = 0; 826 } 827 828 829 /* 830 * ctl_error - send an error response for the current request 831 */ 832 static void 833 ctl_error( 834 u_char errcode 835 ) 836 { 837 int maclen; 838 839 numctlerrors++; 840 DPRINTF(3, ("sending control error %u\n", errcode)); 841 842 /* 843 * Fill in the fields. We assume rpkt.sequence and rpkt.associd 844 * have already been filled in. 845 */ 846 rpkt.r_m_e_op = (u_char)CTL_RESPONSE | CTL_ERROR | 847 (res_opcode & CTL_OP_MASK); 848 rpkt.status = htons((u_short)(errcode << 8) & 0xff00); 849 rpkt.count = 0; 850 851 /* 852 * send packet and bump counters 853 */ 854 if (res_authenticate && sys_authenticate) { 855 maclen = authencrypt(res_keyid, (u_int32 *)&rpkt, 856 CTL_HEADER_LEN); 857 sendpkt(rmt_addr, lcl_inter, -2, (void *)&rpkt, 858 CTL_HEADER_LEN + maclen); 859 } else 860 sendpkt(rmt_addr, lcl_inter, -3, (void *)&rpkt, 861 CTL_HEADER_LEN); 862 } 863 864 /* 865 * save_config - Implements ntpq -c "saveconfig <filename>" 866 * Writes current configuration including any runtime 867 * changes by ntpq's :config or config-from-file 868 */ 869 void 870 save_config( 871 struct recvbuf *rbufp, 872 int restrict_mask 873 ) 874 { 875 char reply[128]; 876 #ifdef SAVECONFIG 877 char filespec[128]; 878 char filename[128]; 879 char fullpath[512]; 880 const char savedconfig_eq[] = "savedconfig="; 881 char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)]; 882 time_t now; 883 int fd; 884 FILE *fptr; 885 #endif 886 887 if (RES_NOMODIFY & restrict_mask) { 888 snprintf(reply, sizeof(reply), 889 "saveconfig prohibited by restrict ... nomodify"); 890 ctl_putdata(reply, strlen(reply), 0); 891 ctl_flushpkt(0); 892 NLOG(NLOG_SYSINFO) 893 msyslog(LOG_NOTICE, 894 "saveconfig from %s rejected due to nomodify restriction", 895 stoa(&rbufp->recv_srcadr)); 896 sys_restricted++; 897 return; 898 } 899 900 #ifdef SAVECONFIG 901 if (NULL == saveconfigdir) { 902 snprintf(reply, sizeof(reply), 903 "saveconfig prohibited, no saveconfigdir configured"); 904 ctl_putdata(reply, strlen(reply), 0); 905 ctl_flushpkt(0); 906 NLOG(NLOG_SYSINFO) 907 msyslog(LOG_NOTICE, 908 "saveconfig from %s rejected, no saveconfigdir", 909 stoa(&rbufp->recv_srcadr)); 910 return; 911 } 912 913 if (0 == reqend - reqpt) 914 return; 915 916 strlcpy(filespec, reqpt, sizeof(filespec)); 917 time(&now); 918 919 /* 920 * allow timestamping of the saved config filename with 921 * strftime() format such as: 922 * ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf" 923 * XXX: Nice feature, but not too safe. 924 */ 925 if (0 == strftime(filename, sizeof(filename), filespec, 926 localtime(&now))) 927 strlcpy(filename, filespec, sizeof(filename)); 928 929 /* 930 * Conceptually we should be searching for DIRSEP in filename, 931 * however Windows actually recognizes both forward and 932 * backslashes as equivalent directory separators at the API 933 * level. On POSIX systems we could allow '\\' but such 934 * filenames are tricky to manipulate from a shell, so just 935 * reject both types of slashes on all platforms. 936 */ 937 if (strchr(filename, '\\') || strchr(filename, '/')) { 938 snprintf(reply, sizeof(reply), 939 "saveconfig does not allow directory in filename"); 940 ctl_putdata(reply, strlen(reply), 0); 941 ctl_flushpkt(0); 942 msyslog(LOG_NOTICE, 943 "saveconfig with path from %s rejected", 944 stoa(&rbufp->recv_srcadr)); 945 return; 946 } 947 948 snprintf(fullpath, sizeof(fullpath), "%s%s", 949 saveconfigdir, filename); 950 951 fd = open(fullpath, O_CREAT | O_TRUNC | O_WRONLY, 952 S_IRUSR | S_IWUSR); 953 if (-1 == fd) 954 fptr = NULL; 955 else 956 fptr = fdopen(fd, "w"); 957 958 if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) { 959 snprintf(reply, sizeof(reply), 960 "Unable to save configuration to file %s", 961 filename); 962 msyslog(LOG_ERR, 963 "saveconfig %s from %s failed", filename, 964 stoa(&rbufp->recv_srcadr)); 965 } else { 966 snprintf(reply, sizeof(reply), 967 "Configuration saved to %s", filename); 968 msyslog(LOG_NOTICE, 969 "Configuration saved to %s (requested by %s)", 970 fullpath, stoa(&rbufp->recv_srcadr)); 971 /* 972 * save the output filename in system variable 973 * savedconfig, retrieved with: 974 * ntpq -c "rv 0 savedconfig" 975 */ 976 snprintf(savedconfig, sizeof(savedconfig), "%s%s", 977 savedconfig_eq, filename); 978 set_sys_var(savedconfig, strlen(savedconfig) + 1, RO); 979 } 980 981 if (NULL != fptr) 982 fclose(fptr); 983 #else /* !SAVECONFIG follows */ 984 snprintf(reply, sizeof(reply), 985 "saveconfig unavailable, configured with --disable-saveconfig"); 986 #endif 987 988 ctl_putdata(reply, strlen(reply), 0); 989 ctl_flushpkt(0); 990 } 991 992 993 /* 994 * process_control - process an incoming control message 995 */ 996 void 997 process_control( 998 struct recvbuf *rbufp, 999 int restrict_mask 1000 ) 1001 { 1002 struct ntp_control *pkt; 1003 int req_count; 1004 int req_data; 1005 const struct ctl_proc *cc; 1006 keyid_t *pkid; 1007 int properlen; 1008 size_t maclen; 1009 1010 DPRINTF(3, ("in process_control()\n")); 1011 1012 /* 1013 * Save the addresses for error responses 1014 */ 1015 numctlreq++; 1016 rmt_addr = &rbufp->recv_srcadr; 1017 lcl_inter = rbufp->dstadr; 1018 pkt = (struct ntp_control *)&rbufp->recv_pkt; 1019 1020 /* 1021 * If the length is less than required for the header, or 1022 * it is a response or a fragment, ignore this. 1023 */ 1024 if (rbufp->recv_length < (int)CTL_HEADER_LEN 1025 || (CTL_RESPONSE | CTL_MORE | CTL_ERROR) & pkt->r_m_e_op 1026 || pkt->offset != 0) { 1027 DPRINTF(1, ("invalid format in control packet\n")); 1028 if (rbufp->recv_length < (int)CTL_HEADER_LEN) 1029 numctltooshort++; 1030 if (CTL_RESPONSE & pkt->r_m_e_op) 1031 numctlinputresp++; 1032 if (CTL_MORE & pkt->r_m_e_op) 1033 numctlinputfrag++; 1034 if (CTL_ERROR & pkt->r_m_e_op) 1035 numctlinputerr++; 1036 if (pkt->offset != 0) 1037 numctlbadoffset++; 1038 return; 1039 } 1040 res_version = PKT_VERSION(pkt->li_vn_mode); 1041 if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) { 1042 DPRINTF(1, ("unknown version %d in control packet\n", 1043 res_version)); 1044 numctlbadversion++; 1045 return; 1046 } 1047 1048 /* 1049 * Pull enough data from the packet to make intelligent 1050 * responses 1051 */ 1052 rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version, 1053 MODE_CONTROL); 1054 res_opcode = pkt->r_m_e_op; 1055 rpkt.sequence = pkt->sequence; 1056 rpkt.associd = pkt->associd; 1057 rpkt.status = 0; 1058 res_frags = 1; 1059 res_offset = 0; 1060 res_associd = htons(pkt->associd); 1061 res_async = FALSE; 1062 res_authenticate = FALSE; 1063 res_keyid = 0; 1064 res_authokay = FALSE; 1065 req_count = (int)ntohs(pkt->count); 1066 datanotbinflag = FALSE; 1067 datalinelen = 0; 1068 datapt = rpkt.u.data; 1069 dataend = &rpkt.u.data[CTL_MAX_DATA_LEN]; 1070 1071 if ((rbufp->recv_length & 0x3) != 0) 1072 DPRINTF(3, ("Control packet length %d unrounded\n", 1073 rbufp->recv_length)); 1074 1075 /* 1076 * We're set up now. Make sure we've got at least enough 1077 * incoming data space to match the count. 1078 */ 1079 req_data = rbufp->recv_length - CTL_HEADER_LEN; 1080 if (req_data < req_count || rbufp->recv_length & 0x3) { 1081 ctl_error(CERR_BADFMT); 1082 numctldatatooshort++; 1083 return; 1084 } 1085 1086 properlen = req_count + CTL_HEADER_LEN; 1087 /* round up proper len to a 8 octet boundary */ 1088 1089 properlen = (properlen + 7) & ~7; 1090 maclen = rbufp->recv_length - properlen; 1091 if ((rbufp->recv_length & 3) == 0 && 1092 maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN && 1093 sys_authenticate) { 1094 res_authenticate = TRUE; 1095 pkid = (void *)((char *)pkt + properlen); 1096 res_keyid = ntohl(*pkid); 1097 DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n", 1098 rbufp->recv_length, properlen, res_keyid, 1099 maclen)); 1100 1101 if (!authistrusted(res_keyid)) 1102 DPRINTF(3, ("invalid keyid %08x\n", res_keyid)); 1103 else if (authdecrypt(res_keyid, (u_int32 *)pkt, 1104 rbufp->recv_length - maclen, 1105 maclen)) { 1106 res_authokay = TRUE; 1107 DPRINTF(3, ("authenticated okay\n")); 1108 } else { 1109 res_keyid = 0; 1110 DPRINTF(3, ("authentication failed\n")); 1111 } 1112 } 1113 1114 /* 1115 * Set up translate pointers 1116 */ 1117 reqpt = (char *)pkt->u.data; 1118 reqend = reqpt + req_count; 1119 1120 /* 1121 * Look for the opcode processor 1122 */ 1123 for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) { 1124 if (cc->control_code == res_opcode) { 1125 DPRINTF(3, ("opcode %d, found command handler\n", 1126 res_opcode)); 1127 if (cc->flags == AUTH 1128 && (!res_authokay 1129 || res_keyid != ctl_auth_keyid)) { 1130 ctl_error(CERR_PERMISSION); 1131 return; 1132 } 1133 (cc->handler)(rbufp, restrict_mask); 1134 return; 1135 } 1136 } 1137 1138 /* 1139 * Can't find this one, return an error. 1140 */ 1141 numctlbadop++; 1142 ctl_error(CERR_BADOP); 1143 return; 1144 } 1145 1146 1147 /* 1148 * ctlpeerstatus - return a status word for this peer 1149 */ 1150 u_short 1151 ctlpeerstatus( 1152 register struct peer *p 1153 ) 1154 { 1155 u_short status; 1156 1157 status = p->status; 1158 if (FLAG_CONFIG & p->flags) 1159 status |= CTL_PST_CONFIG; 1160 if (p->keyid) 1161 status |= CTL_PST_AUTHENABLE; 1162 if (FLAG_AUTHENTIC & p->flags) 1163 status |= CTL_PST_AUTHENTIC; 1164 if (p->reach) 1165 status |= CTL_PST_REACH; 1166 if (MDF_TXONLY_MASK & p->cast_flags) 1167 status |= CTL_PST_BCAST; 1168 1169 return CTL_PEER_STATUS(status, p->num_events, p->last_event); 1170 } 1171 1172 1173 /* 1174 * ctlclkstatus - return a status word for this clock 1175 */ 1176 #ifdef REFCLOCK 1177 static u_short 1178 ctlclkstatus( 1179 struct refclockstat *pcs 1180 ) 1181 { 1182 return CTL_PEER_STATUS(0, pcs->lastevent, pcs->currentstatus); 1183 } 1184 #endif 1185 1186 1187 /* 1188 * ctlsysstatus - return the system status word 1189 */ 1190 u_short 1191 ctlsysstatus(void) 1192 { 1193 register u_char this_clock; 1194 1195 this_clock = CTL_SST_TS_UNSPEC; 1196 #ifdef REFCLOCK 1197 if (sys_peer != NULL) { 1198 if (CTL_SST_TS_UNSPEC != sys_peer->sstclktype) 1199 this_clock = sys_peer->sstclktype; 1200 else if (sys_peer->refclktype < COUNTOF(clocktypes)) 1201 this_clock = clocktypes[sys_peer->refclktype]; 1202 } 1203 #else /* REFCLOCK */ 1204 if (sys_peer != 0) 1205 this_clock = CTL_SST_TS_NTP; 1206 #endif /* REFCLOCK */ 1207 return CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events, 1208 ctl_sys_last_event); 1209 } 1210 1211 1212 /* 1213 * ctl_flushpkt - write out the current packet and prepare 1214 * another if necessary. 1215 */ 1216 static void 1217 ctl_flushpkt( 1218 u_char more 1219 ) 1220 { 1221 size_t i; 1222 int dlen; 1223 int sendlen; 1224 int maclen; 1225 int totlen; 1226 keyid_t keyid; 1227 1228 dlen = datapt - rpkt.u.data; 1229 if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) { 1230 /* 1231 * Big hack, output a trailing \r\n 1232 */ 1233 *datapt++ = '\r'; 1234 *datapt++ = '\n'; 1235 dlen += 2; 1236 } 1237 sendlen = dlen + CTL_HEADER_LEN; 1238 1239 /* 1240 * Pad to a multiple of 32 bits 1241 */ 1242 while (sendlen & 0x3) { 1243 *datapt++ = '\0'; 1244 sendlen++; 1245 } 1246 1247 /* 1248 * Fill in the packet with the current info 1249 */ 1250 rpkt.r_m_e_op = CTL_RESPONSE | more | 1251 (res_opcode & CTL_OP_MASK); 1252 rpkt.count = htons((u_short)dlen); 1253 rpkt.offset = htons((u_short)res_offset); 1254 if (res_async) { 1255 for (i = 0; i < COUNTOF(ctl_traps); i++) { 1256 if (TRAP_INUSE & ctl_traps[i].tr_flags) { 1257 rpkt.li_vn_mode = 1258 PKT_LI_VN_MODE( 1259 sys_leap, 1260 ctl_traps[i].tr_version, 1261 MODE_CONTROL); 1262 rpkt.sequence = 1263 htons(ctl_traps[i].tr_sequence); 1264 sendpkt(&ctl_traps[i].tr_addr, 1265 ctl_traps[i].tr_localaddr, -4, 1266 (struct pkt *)&rpkt, sendlen); 1267 if (!more) 1268 ctl_traps[i].tr_sequence++; 1269 numasyncmsgs++; 1270 } 1271 } 1272 } else { 1273 if (res_authenticate && sys_authenticate) { 1274 totlen = sendlen; 1275 /* 1276 * If we are going to authenticate, then there 1277 * is an additional requirement that the MAC 1278 * begin on a 64 bit boundary. 1279 */ 1280 while (totlen & 7) { 1281 *datapt++ = '\0'; 1282 totlen++; 1283 } 1284 keyid = htonl(res_keyid); 1285 memcpy(datapt, &keyid, sizeof(keyid)); 1286 maclen = authencrypt(res_keyid, 1287 (u_int32 *)&rpkt, totlen); 1288 sendpkt(rmt_addr, lcl_inter, -5, 1289 (struct pkt *)&rpkt, totlen + maclen); 1290 } else { 1291 sendpkt(rmt_addr, lcl_inter, -6, 1292 (struct pkt *)&rpkt, sendlen); 1293 } 1294 if (more) 1295 numctlfrags++; 1296 else 1297 numctlresponses++; 1298 } 1299 1300 /* 1301 * Set us up for another go around. 1302 */ 1303 res_frags++; 1304 res_offset += dlen; 1305 datapt = rpkt.u.data; 1306 } 1307 1308 1309 /* 1310 * ctl_putdata - write data into the packet, fragmenting and starting 1311 * another if this one is full. 1312 */ 1313 static void 1314 ctl_putdata( 1315 const char *dp, 1316 unsigned int dlen, 1317 int bin /* set to 1 when data is binary */ 1318 ) 1319 { 1320 int overhead; 1321 1322 overhead = 0; 1323 if (!bin) { 1324 datanotbinflag = TRUE; 1325 overhead = 3; 1326 if (datapt != rpkt.u.data) { 1327 *datapt++ = ','; 1328 datalinelen++; 1329 if ((dlen + datalinelen + 1) >= MAXDATALINELEN) { 1330 *datapt++ = '\r'; 1331 *datapt++ = '\n'; 1332 datalinelen = 0; 1333 } else { 1334 *datapt++ = ' '; 1335 datalinelen++; 1336 } 1337 } 1338 } 1339 1340 /* 1341 * Save room for trailing junk 1342 */ 1343 if (dlen + overhead + datapt > dataend) { 1344 /* 1345 * Not enough room in this one, flush it out. 1346 */ 1347 ctl_flushpkt(CTL_MORE); 1348 } 1349 memcpy(datapt, dp, dlen); 1350 datapt += dlen; 1351 datalinelen += dlen; 1352 } 1353 1354 1355 /* 1356 * ctl_putstr - write a tagged string into the response packet 1357 * in the form: 1358 * 1359 * tag="data" 1360 * 1361 * len is the data length excluding the NUL terminator, 1362 * as in ctl_putstr("var", "value", strlen("value")); 1363 */ 1364 static void 1365 ctl_putstr( 1366 const char * tag, 1367 const char * data, 1368 size_t len 1369 ) 1370 { 1371 char buffer[512]; 1372 char *cp; 1373 size_t tl; 1374 1375 tl = strlen(tag); 1376 memcpy(buffer, tag, tl); 1377 cp = buffer + tl; 1378 if (len > 0) { 1379 NTP_INSIST(tl + 3 + len <= sizeof(buffer)); 1380 *cp++ = '='; 1381 *cp++ = '"'; 1382 memcpy(cp, data, len); 1383 cp += len; 1384 *cp++ = '"'; 1385 } 1386 ctl_putdata(buffer, (u_int)(cp - buffer), 0); 1387 } 1388 1389 1390 /* 1391 * ctl_putunqstr - write a tagged string into the response packet 1392 * in the form: 1393 * 1394 * tag=data 1395 * 1396 * len is the data length excluding the NUL terminator. 1397 * data must not contain a comma or whitespace. 1398 */ 1399 static void 1400 ctl_putunqstr( 1401 const char * tag, 1402 const char * data, 1403 size_t len 1404 ) 1405 { 1406 char buffer[512]; 1407 char *cp; 1408 size_t tl; 1409 1410 tl = strlen(tag); 1411 memcpy(buffer, tag, tl); 1412 cp = buffer + tl; 1413 if (len > 0) { 1414 NTP_INSIST(tl + 1 + len <= sizeof(buffer)); 1415 *cp++ = '='; 1416 memcpy(cp, data, len); 1417 cp += len; 1418 } 1419 ctl_putdata(buffer, (u_int)(cp - buffer), 0); 1420 } 1421 1422 1423 /* 1424 * ctl_putdblf - write a tagged, signed double into the response packet 1425 */ 1426 static void 1427 ctl_putdblf( 1428 const char * tag, 1429 const char * fmt, 1430 double d 1431 ) 1432 { 1433 char *cp; 1434 const char *cq; 1435 char buffer[200]; 1436 1437 cp = buffer; 1438 cq = tag; 1439 while (*cq != '\0') 1440 *cp++ = *cq++; 1441 *cp++ = '='; 1442 NTP_INSIST((size_t)(cp - buffer) < sizeof(buffer)); 1443 snprintf(cp, sizeof(buffer) - (cp - buffer), fmt, d); 1444 cp += strlen(cp); 1445 ctl_putdata(buffer, (unsigned)(cp - buffer), 0); 1446 } 1447 1448 /* 1449 * ctl_putuint - write a tagged unsigned integer into the response 1450 */ 1451 static void 1452 ctl_putuint( 1453 const char *tag, 1454 u_long uval 1455 ) 1456 { 1457 register char *cp; 1458 register const char *cq; 1459 char buffer[200]; 1460 1461 cp = buffer; 1462 cq = tag; 1463 while (*cq != '\0') 1464 *cp++ = *cq++; 1465 1466 *cp++ = '='; 1467 NTP_INSIST((cp - buffer) < (int)sizeof(buffer)); 1468 snprintf(cp, sizeof(buffer) - (cp - buffer), "%lu", uval); 1469 cp += strlen(cp); 1470 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1471 } 1472 1473 /* 1474 * ctl_putfs - write a decoded filestamp into the response 1475 */ 1476 static void 1477 ctl_putfs( 1478 const char *tag, 1479 tstamp_t uval 1480 ) 1481 { 1482 register char *cp; 1483 register const char *cq; 1484 char buffer[200]; 1485 struct tm *tm = NULL; 1486 time_t fstamp; 1487 1488 cp = buffer; 1489 cq = tag; 1490 while (*cq != '\0') 1491 *cp++ = *cq++; 1492 1493 *cp++ = '='; 1494 fstamp = uval - JAN_1970; 1495 tm = gmtime(&fstamp); 1496 if (NULL == tm) 1497 return; 1498 NTP_INSIST((cp - buffer) < (int)sizeof(buffer)); 1499 snprintf(cp, sizeof(buffer) - (cp - buffer), 1500 "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 1501 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); 1502 cp += strlen(cp); 1503 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1504 } 1505 1506 1507 /* 1508 * ctl_puthex - write a tagged unsigned integer, in hex, into the 1509 * response 1510 */ 1511 static void 1512 ctl_puthex( 1513 const char *tag, 1514 u_long uval 1515 ) 1516 { 1517 register char *cp; 1518 register const char *cq; 1519 char buffer[200]; 1520 1521 cp = buffer; 1522 cq = tag; 1523 while (*cq != '\0') 1524 *cp++ = *cq++; 1525 1526 *cp++ = '='; 1527 NTP_INSIST((cp - buffer) < (int)sizeof(buffer)); 1528 snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%lx", uval); 1529 cp += strlen(cp); 1530 ctl_putdata(buffer,(unsigned)( cp - buffer ), 0); 1531 } 1532 1533 1534 /* 1535 * ctl_putint - write a tagged signed integer into the response 1536 */ 1537 static void 1538 ctl_putint( 1539 const char *tag, 1540 long ival 1541 ) 1542 { 1543 register char *cp; 1544 register const char *cq; 1545 char buffer[200]; 1546 1547 cp = buffer; 1548 cq = tag; 1549 while (*cq != '\0') 1550 *cp++ = *cq++; 1551 1552 *cp++ = '='; 1553 NTP_INSIST((cp - buffer) < (int)sizeof(buffer)); 1554 snprintf(cp, sizeof(buffer) - (cp - buffer), "%ld", ival); 1555 cp += strlen(cp); 1556 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1557 } 1558 1559 1560 /* 1561 * ctl_putts - write a tagged timestamp, in hex, into the response 1562 */ 1563 static void 1564 ctl_putts( 1565 const char *tag, 1566 l_fp *ts 1567 ) 1568 { 1569 register char *cp; 1570 register const char *cq; 1571 char buffer[200]; 1572 1573 cp = buffer; 1574 cq = tag; 1575 while (*cq != '\0') 1576 *cp++ = *cq++; 1577 1578 *cp++ = '='; 1579 NTP_INSIST((size_t)(cp - buffer) < sizeof(buffer)); 1580 snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%08x.%08x", 1581 (u_int)ts->l_ui, (u_int)ts->l_uf); 1582 cp += strlen(cp); 1583 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1584 } 1585 1586 1587 /* 1588 * ctl_putadr - write an IP address into the response 1589 */ 1590 static void 1591 ctl_putadr( 1592 const char *tag, 1593 u_int32 addr32, 1594 sockaddr_u *addr 1595 ) 1596 { 1597 register char *cp; 1598 register const char *cq; 1599 char buffer[200]; 1600 1601 cp = buffer; 1602 cq = tag; 1603 while (*cq != '\0') 1604 *cp++ = *cq++; 1605 1606 *cp++ = '='; 1607 if (NULL == addr) 1608 cq = numtoa(addr32); 1609 else 1610 cq = stoa(addr); 1611 NTP_INSIST((cp - buffer) < (int)sizeof(buffer)); 1612 snprintf(cp, sizeof(buffer) - (cp - buffer), "%s", cq); 1613 cp += strlen(cp); 1614 ctl_putdata(buffer, (unsigned)(cp - buffer), 0); 1615 } 1616 1617 1618 /* 1619 * ctl_putrefid - send a u_int32 refid as printable text 1620 */ 1621 static void 1622 ctl_putrefid( 1623 const char * tag, 1624 u_int32 refid 1625 ) 1626 { 1627 char output[16]; 1628 char * optr; 1629 char * oplim; 1630 char * iptr; 1631 char * iplim; 1632 char * past_eq; 1633 1634 optr = output; 1635 oplim = output + sizeof(output); 1636 while (optr < oplim && '\0' != *tag) 1637 *optr++ = *tag++; 1638 if (optr < oplim) { 1639 *optr++ = '='; 1640 past_eq = optr; 1641 } 1642 if (!(optr < oplim)) 1643 return; 1644 iptr = (char *)&refid; 1645 iplim = iptr + sizeof(refid); 1646 for ( ; optr < oplim && iptr < iplim && '\0' != *iptr; 1647 iptr++, optr++) 1648 if (isprint((int)*iptr)) 1649 *optr = *iptr; 1650 else 1651 *optr = '.'; 1652 if (!(optr <= oplim)) 1653 optr = past_eq; 1654 ctl_putdata(output, (u_int)(optr - output), FALSE); 1655 } 1656 1657 1658 /* 1659 * ctl_putarray - write a tagged eight element double array into the response 1660 */ 1661 static void 1662 ctl_putarray( 1663 const char *tag, 1664 double *arr, 1665 int start 1666 ) 1667 { 1668 register char *cp; 1669 register const char *cq; 1670 char buffer[200]; 1671 int i; 1672 cp = buffer; 1673 cq = tag; 1674 while (*cq != '\0') 1675 *cp++ = *cq++; 1676 *cp++ = '='; 1677 i = start; 1678 do { 1679 if (i == 0) 1680 i = NTP_SHIFT; 1681 i--; 1682 NTP_INSIST((cp - buffer) < (int)sizeof(buffer)); 1683 snprintf(cp, sizeof(buffer) - (cp - buffer), 1684 " %.2f", arr[i] * 1e3); 1685 cp += strlen(cp); 1686 } while (i != start); 1687 ctl_putdata(buffer, (unsigned)(cp - buffer), 0); 1688 } 1689 1690 1691 /* 1692 * ctl_putsys - output a system variable 1693 */ 1694 static void 1695 ctl_putsys( 1696 int varid 1697 ) 1698 { 1699 l_fp tmp; 1700 char str[256]; 1701 u_int u; 1702 double kb; 1703 double dtemp; 1704 const char *ss; 1705 #ifdef AUTOKEY 1706 struct cert_info *cp; 1707 #endif /* AUTOKEY */ 1708 #ifdef KERNEL_PLL 1709 static struct timex ntx; 1710 static u_long ntp_adjtime_time; 1711 1712 static const double to_ms = 1713 # ifdef STA_NANO 1714 1.0e-6; /* nsec to msec */ 1715 # else 1716 1.0e-3; /* usec to msec */ 1717 # endif 1718 1719 /* 1720 * CS_K_* variables depend on up-to-date output of ntp_adjtime() 1721 */ 1722 if (CS_KERN_FIRST <= varid && varid <= CS_KERN_LAST && 1723 current_time != ntp_adjtime_time) { 1724 ZERO(ntx); 1725 if (ntp_adjtime(&ntx) < 0) 1726 msyslog(LOG_ERR, "ntp_adjtime() for mode 6 query failed: %m"); 1727 else 1728 ntp_adjtime_time = current_time; 1729 } 1730 #endif /* KERNEL_PLL */ 1731 1732 switch (varid) { 1733 1734 case CS_LEAP: 1735 ctl_putuint(sys_var[CS_LEAP].text, sys_leap); 1736 break; 1737 1738 case CS_STRATUM: 1739 ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum); 1740 break; 1741 1742 case CS_PRECISION: 1743 ctl_putint(sys_var[CS_PRECISION].text, sys_precision); 1744 break; 1745 1746 case CS_ROOTDELAY: 1747 ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay * 1748 1e3); 1749 break; 1750 1751 case CS_ROOTDISPERSION: 1752 ctl_putdbl(sys_var[CS_ROOTDISPERSION].text, 1753 sys_rootdisp * 1e3); 1754 break; 1755 1756 case CS_REFID: 1757 if (sys_stratum > 1 && sys_stratum < STRATUM_UNSPEC) 1758 ctl_putadr(sys_var[varid].text, sys_refid, NULL); 1759 else 1760 ctl_putrefid(sys_var[varid].text, sys_refid); 1761 break; 1762 1763 case CS_REFTIME: 1764 ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime); 1765 break; 1766 1767 case CS_POLL: 1768 ctl_putuint(sys_var[CS_POLL].text, sys_poll); 1769 break; 1770 1771 case CS_PEERID: 1772 if (sys_peer == NULL) 1773 ctl_putuint(sys_var[CS_PEERID].text, 0); 1774 else 1775 ctl_putuint(sys_var[CS_PEERID].text, 1776 sys_peer->associd); 1777 break; 1778 1779 case CS_PEERADR: 1780 if (sys_peer != NULL && sys_peer->dstadr != NULL) 1781 ss = sptoa(&sys_peer->srcadr); 1782 else 1783 ss = "0.0.0.0:0"; 1784 ctl_putunqstr(sys_var[CS_PEERADR].text, ss, strlen(ss)); 1785 break; 1786 1787 case CS_PEERMODE: 1788 u = (sys_peer != NULL) 1789 ? sys_peer->hmode 1790 : MODE_UNSPEC; 1791 ctl_putuint(sys_var[CS_PEERMODE].text, u); 1792 break; 1793 1794 case CS_OFFSET: 1795 ctl_putdbl6(sys_var[CS_OFFSET].text, last_offset * 1e3); 1796 break; 1797 1798 case CS_DRIFT: 1799 ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6); 1800 break; 1801 1802 case CS_JITTER: 1803 ctl_putdbl6(sys_var[CS_JITTER].text, sys_jitter * 1e3); 1804 break; 1805 1806 case CS_ERROR: 1807 ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3); 1808 break; 1809 1810 case CS_CLOCK: 1811 get_systime(&tmp); 1812 ctl_putts(sys_var[CS_CLOCK].text, &tmp); 1813 break; 1814 1815 case CS_PROCESSOR: 1816 #ifndef HAVE_UNAME 1817 ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor, 1818 sizeof(str_processor) - 1); 1819 #else 1820 ctl_putstr(sys_var[CS_PROCESSOR].text, 1821 utsnamebuf.machine, strlen(utsnamebuf.machine)); 1822 #endif /* HAVE_UNAME */ 1823 break; 1824 1825 case CS_SYSTEM: 1826 #ifndef HAVE_UNAME 1827 ctl_putstr(sys_var[CS_SYSTEM].text, str_system, 1828 sizeof(str_system) - 1); 1829 #else 1830 snprintf(str, sizeof(str), "%s/%s", utsnamebuf.sysname, 1831 utsnamebuf.release); 1832 ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str)); 1833 #endif /* HAVE_UNAME */ 1834 break; 1835 1836 case CS_VERSION: 1837 ctl_putstr(sys_var[CS_VERSION].text, Version, 1838 strlen(Version)); 1839 break; 1840 1841 case CS_STABIL: 1842 ctl_putdbl(sys_var[CS_STABIL].text, clock_stability * 1843 1e6); 1844 break; 1845 1846 case CS_VARLIST: 1847 { 1848 char buf[CTL_MAX_DATA_LEN]; 1849 //buffPointer, firstElementPointer, buffEndPointer 1850 char *buffp, *buffend; 1851 int firstVarName; 1852 const char *ss1; 1853 int len; 1854 const struct ctl_var *k; 1855 1856 buffp = buf; 1857 buffend = buf + sizeof(buf); 1858 if (buffp + strlen(sys_var[CS_VARLIST].text) + 4 > buffend) 1859 break; /* really long var name */ 1860 1861 snprintf(buffp, sizeof(buf), "%s=\"",sys_var[CS_VARLIST].text); 1862 buffp += strlen(buffp); 1863 firstVarName = TRUE; 1864 for (k = sys_var; !(k->flags & EOV); k++) { 1865 if (k->flags & PADDING) 1866 continue; 1867 len = strlen(k->text); 1868 if (buffp + len + 1 >= buffend) 1869 break; 1870 if (!firstVarName) 1871 *buffp++ = ','; 1872 else 1873 firstVarName = FALSE; 1874 memcpy(buffp, k->text, len); 1875 buffp += len; 1876 } 1877 1878 for (k = ext_sys_var; k && !(k->flags & EOV); k++) { 1879 if (k->flags & PADDING) 1880 continue; 1881 if (NULL == k->text) 1882 continue; 1883 ss1 = strchr(k->text, '='); 1884 if (NULL == ss1) 1885 len = strlen(k->text); 1886 else 1887 len = ss1 - k->text; 1888 if (buffp + len + 1 >= buffend) 1889 break; 1890 if (firstVarName) { 1891 *buffp++ = ','; 1892 firstVarName = FALSE; 1893 } 1894 memcpy(buffp, k->text,(unsigned)len); 1895 buffp += len; 1896 } 1897 if (buffp + 2 >= buffend) 1898 break; 1899 1900 *buffp++ = '"'; 1901 *buffp = '\0'; 1902 1903 ctl_putdata(buf, (unsigned)( buffp - buf ), 0); 1904 break; 1905 } 1906 1907 case CS_TAI: 1908 if (sys_tai > 0) 1909 ctl_putuint(sys_var[CS_TAI].text, sys_tai); 1910 break; 1911 1912 case CS_LEAPTAB: 1913 { 1914 leap_signature_t lsig; 1915 leapsec_getsig(&lsig); 1916 if (lsig.ttime > 0) 1917 ctl_putfs(sys_var[CS_LEAPTAB].text, lsig.ttime); 1918 break; 1919 } 1920 1921 case CS_LEAPEND: 1922 { 1923 leap_signature_t lsig; 1924 leapsec_getsig(&lsig); 1925 if (lsig.etime > 0) 1926 ctl_putfs(sys_var[CS_LEAPEND].text, lsig.etime); 1927 break; 1928 } 1929 1930 case CS_RATE: 1931 ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll); 1932 break; 1933 1934 case CS_MRU_ENABLED: 1935 ctl_puthex(sys_var[varid].text, mon_enabled); 1936 break; 1937 1938 case CS_MRU_DEPTH: 1939 ctl_putuint(sys_var[varid].text, mru_entries); 1940 break; 1941 1942 case CS_MRU_MEM: 1943 kb = mru_entries * (sizeof(mon_entry) / 1024.); 1944 u = (u_int)kb; 1945 if (kb - u >= 0.5) 1946 u++; 1947 ctl_putuint(sys_var[varid].text, u); 1948 break; 1949 1950 case CS_MRU_DEEPEST: 1951 ctl_putuint(sys_var[varid].text, mru_peakentries); 1952 break; 1953 1954 case CS_MRU_MINDEPTH: 1955 ctl_putuint(sys_var[varid].text, mru_mindepth); 1956 break; 1957 1958 case CS_MRU_MAXAGE: 1959 ctl_putint(sys_var[varid].text, mru_maxage); 1960 break; 1961 1962 case CS_MRU_MAXDEPTH: 1963 ctl_putuint(sys_var[varid].text, mru_maxdepth); 1964 break; 1965 1966 case CS_MRU_MAXMEM: 1967 kb = mru_maxdepth * (sizeof(mon_entry) / 1024.); 1968 u = (u_int)kb; 1969 if (kb - u >= 0.5) 1970 u++; 1971 ctl_putuint(sys_var[varid].text, u); 1972 break; 1973 1974 case CS_SS_UPTIME: 1975 ctl_putuint(sys_var[varid].text, current_time); 1976 break; 1977 1978 case CS_SS_RESET: 1979 ctl_putuint(sys_var[varid].text, 1980 current_time - sys_stattime); 1981 break; 1982 1983 case CS_SS_RECEIVED: 1984 ctl_putuint(sys_var[varid].text, sys_received); 1985 break; 1986 1987 case CS_SS_THISVER: 1988 ctl_putuint(sys_var[varid].text, sys_newversion); 1989 break; 1990 1991 case CS_SS_OLDVER: 1992 ctl_putuint(sys_var[varid].text, sys_oldversion); 1993 break; 1994 1995 case CS_SS_BADFORMAT: 1996 ctl_putuint(sys_var[varid].text, sys_badlength); 1997 break; 1998 1999 case CS_SS_BADAUTH: 2000 ctl_putuint(sys_var[varid].text, sys_badauth); 2001 break; 2002 2003 case CS_SS_DECLINED: 2004 ctl_putuint(sys_var[varid].text, sys_declined); 2005 break; 2006 2007 case CS_SS_RESTRICTED: 2008 ctl_putuint(sys_var[varid].text, sys_restricted); 2009 break; 2010 2011 case CS_SS_LIMITED: 2012 ctl_putuint(sys_var[varid].text, sys_limitrejected); 2013 break; 2014 2015 case CS_SS_KODSENT: 2016 ctl_putuint(sys_var[varid].text, sys_kodsent); 2017 break; 2018 2019 case CS_SS_PROCESSED: 2020 ctl_putuint(sys_var[varid].text, sys_processed); 2021 break; 2022 2023 case CS_BCASTDELAY: 2024 ctl_putdbl(sys_var[varid].text, sys_bdelay * 1e3); 2025 break; 2026 2027 case CS_AUTHDELAY: 2028 LFPTOD(&sys_authdelay, dtemp); 2029 ctl_putdbl(sys_var[varid].text, dtemp * 1e3); 2030 break; 2031 2032 case CS_AUTHKEYS: 2033 ctl_putuint(sys_var[varid].text, authnumkeys); 2034 break; 2035 2036 case CS_AUTHFREEK: 2037 ctl_putuint(sys_var[varid].text, authnumfreekeys); 2038 break; 2039 2040 case CS_AUTHKLOOKUPS: 2041 ctl_putuint(sys_var[varid].text, authkeylookups); 2042 break; 2043 2044 case CS_AUTHKNOTFOUND: 2045 ctl_putuint(sys_var[varid].text, authkeynotfound); 2046 break; 2047 2048 case CS_AUTHKUNCACHED: 2049 ctl_putuint(sys_var[varid].text, authkeyuncached); 2050 break; 2051 2052 case CS_AUTHKEXPIRED: 2053 ctl_putuint(sys_var[varid].text, authkeyexpired); 2054 break; 2055 2056 case CS_AUTHENCRYPTS: 2057 ctl_putuint(sys_var[varid].text, authencryptions); 2058 break; 2059 2060 case CS_AUTHDECRYPTS: 2061 ctl_putuint(sys_var[varid].text, authdecryptions); 2062 break; 2063 2064 case CS_AUTHRESET: 2065 ctl_putuint(sys_var[varid].text, 2066 current_time - auth_timereset); 2067 break; 2068 2069 /* 2070 * CTL_IF_KERNLOOP() puts a zero if the kernel loop is 2071 * unavailable, otherwise calls putfunc with args. 2072 */ 2073 #ifndef KERNEL_PLL 2074 # define CTL_IF_KERNLOOP(putfunc, args) \ 2075 ctl_putint(sys_var[varid].text, 0) 2076 #else 2077 # define CTL_IF_KERNLOOP(putfunc, args) \ 2078 putfunc args 2079 #endif 2080 2081 /* 2082 * CTL_IF_KERNPPS() puts a zero if either the kernel 2083 * loop is unavailable, or kernel hard PPS is not 2084 * active, otherwise calls putfunc with args. 2085 */ 2086 #ifndef KERNEL_PLL 2087 # define CTL_IF_KERNPPS(putfunc, args) \ 2088 ctl_putint(sys_var[varid].text, 0) 2089 #else 2090 # define CTL_IF_KERNPPS(putfunc, args) \ 2091 if (0 == ntx.shift) \ 2092 ctl_putint(sys_var[varid].text, 0); \ 2093 else \ 2094 putfunc args /* no trailing ; */ 2095 #endif 2096 2097 case CS_K_OFFSET: 2098 CTL_IF_KERNLOOP( 2099 ctl_putdblf, 2100 (sys_var[varid].text, "%g", to_ms * ntx.offset) 2101 ); 2102 break; 2103 2104 case CS_K_FREQ: 2105 CTL_IF_KERNLOOP( 2106 ctl_putsfp, 2107 (sys_var[varid].text, ntx.freq) 2108 ); 2109 break; 2110 2111 case CS_K_MAXERR: 2112 CTL_IF_KERNLOOP( 2113 ctl_putdblf, 2114 (sys_var[varid].text, "%.6g", 2115 to_ms * ntx.maxerror) 2116 ); 2117 break; 2118 2119 case CS_K_ESTERR: 2120 CTL_IF_KERNLOOP( 2121 ctl_putdblf, 2122 (sys_var[varid].text, "%.6g", 2123 to_ms * ntx.esterror) 2124 ); 2125 break; 2126 2127 case CS_K_STFLAGS: 2128 #ifndef KERNEL_PLL 2129 ss = ""; 2130 #else 2131 ss = k_st_flags(ntx.status); 2132 #endif 2133 ctl_putstr(sys_var[varid].text, ss, strlen(ss)); 2134 break; 2135 2136 case CS_K_TIMECONST: 2137 CTL_IF_KERNLOOP( 2138 ctl_putint, 2139 (sys_var[varid].text, ntx.constant) 2140 ); 2141 break; 2142 2143 case CS_K_PRECISION: 2144 CTL_IF_KERNLOOP( 2145 ctl_putdblf, 2146 (sys_var[varid].text, "%.6g", 2147 to_ms * ntx.precision) 2148 ); 2149 break; 2150 2151 case CS_K_FREQTOL: 2152 CTL_IF_KERNLOOP( 2153 ctl_putsfp, 2154 (sys_var[varid].text, ntx.tolerance) 2155 ); 2156 break; 2157 2158 case CS_K_PPS_FREQ: 2159 CTL_IF_KERNPPS( 2160 ctl_putsfp, 2161 (sys_var[varid].text, ntx.ppsfreq) 2162 ); 2163 break; 2164 2165 case CS_K_PPS_STABIL: 2166 CTL_IF_KERNPPS( 2167 ctl_putsfp, 2168 (sys_var[varid].text, ntx.stabil) 2169 ); 2170 break; 2171 2172 case CS_K_PPS_JITTER: 2173 CTL_IF_KERNPPS( 2174 ctl_putdbl, 2175 (sys_var[varid].text, to_ms * ntx.jitter) 2176 ); 2177 break; 2178 2179 case CS_K_PPS_CALIBDUR: 2180 CTL_IF_KERNPPS( 2181 ctl_putint, 2182 (sys_var[varid].text, 1 << ntx.shift) 2183 ); 2184 break; 2185 2186 case CS_K_PPS_CALIBS: 2187 CTL_IF_KERNPPS( 2188 ctl_putint, 2189 (sys_var[varid].text, ntx.calcnt) 2190 ); 2191 break; 2192 2193 case CS_K_PPS_CALIBERRS: 2194 CTL_IF_KERNPPS( 2195 ctl_putint, 2196 (sys_var[varid].text, ntx.errcnt) 2197 ); 2198 break; 2199 2200 case CS_K_PPS_JITEXC: 2201 CTL_IF_KERNPPS( 2202 ctl_putint, 2203 (sys_var[varid].text, ntx.jitcnt) 2204 ); 2205 break; 2206 2207 case CS_K_PPS_STBEXC: 2208 CTL_IF_KERNPPS( 2209 ctl_putint, 2210 (sys_var[varid].text, ntx.stbcnt) 2211 ); 2212 break; 2213 2214 case CS_IOSTATS_RESET: 2215 ctl_putuint(sys_var[varid].text, 2216 current_time - io_timereset); 2217 break; 2218 2219 case CS_TOTAL_RBUF: 2220 ctl_putuint(sys_var[varid].text, total_recvbuffs()); 2221 break; 2222 2223 case CS_FREE_RBUF: 2224 ctl_putuint(sys_var[varid].text, free_recvbuffs()); 2225 break; 2226 2227 case CS_USED_RBUF: 2228 ctl_putuint(sys_var[varid].text, full_recvbuffs()); 2229 break; 2230 2231 case CS_RBUF_LOWATER: 2232 ctl_putuint(sys_var[varid].text, lowater_additions()); 2233 break; 2234 2235 case CS_IO_DROPPED: 2236 ctl_putuint(sys_var[varid].text, packets_dropped); 2237 break; 2238 2239 case CS_IO_IGNORED: 2240 ctl_putuint(sys_var[varid].text, packets_ignored); 2241 break; 2242 2243 case CS_IO_RECEIVED: 2244 ctl_putuint(sys_var[varid].text, packets_received); 2245 break; 2246 2247 case CS_IO_SENT: 2248 ctl_putuint(sys_var[varid].text, packets_sent); 2249 break; 2250 2251 case CS_IO_SENDFAILED: 2252 ctl_putuint(sys_var[varid].text, packets_notsent); 2253 break; 2254 2255 case CS_IO_WAKEUPS: 2256 ctl_putuint(sys_var[varid].text, handler_calls); 2257 break; 2258 2259 case CS_IO_GOODWAKEUPS: 2260 ctl_putuint(sys_var[varid].text, handler_pkts); 2261 break; 2262 2263 case CS_TIMERSTATS_RESET: 2264 ctl_putuint(sys_var[varid].text, 2265 current_time - timer_timereset); 2266 break; 2267 2268 case CS_TIMER_OVERRUNS: 2269 ctl_putuint(sys_var[varid].text, alarm_overflow); 2270 break; 2271 2272 case CS_TIMER_XMTS: 2273 ctl_putuint(sys_var[varid].text, timer_xmtcalls); 2274 break; 2275 2276 case CS_FUZZ: 2277 ctl_putdbl(sys_var[varid].text, sys_fuzz * 1e3); 2278 break; 2279 #ifdef AUTOKEY 2280 case CS_FLAGS: 2281 if (crypto_flags) 2282 ctl_puthex(sys_var[CS_FLAGS].text, 2283 crypto_flags); 2284 break; 2285 2286 case CS_DIGEST: 2287 if (crypto_flags) { 2288 strlcpy(str, OBJ_nid2ln(crypto_nid), 2289 COUNTOF(str)); 2290 ctl_putstr(sys_var[CS_DIGEST].text, str, 2291 strlen(str)); 2292 } 2293 break; 2294 2295 case CS_SIGNATURE: 2296 if (crypto_flags) { 2297 const EVP_MD *dp; 2298 2299 dp = EVP_get_digestbynid(crypto_flags >> 16); 2300 strlcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)), 2301 COUNTOF(str)); 2302 ctl_putstr(sys_var[CS_SIGNATURE].text, str, 2303 strlen(str)); 2304 } 2305 break; 2306 2307 case CS_HOST: 2308 if (hostval.ptr != NULL) 2309 ctl_putstr(sys_var[CS_HOST].text, hostval.ptr, 2310 strlen(hostval.ptr)); 2311 break; 2312 2313 case CS_IDENT: 2314 if (sys_ident != NULL) 2315 ctl_putstr(sys_var[CS_IDENT].text, sys_ident, 2316 strlen(sys_ident)); 2317 break; 2318 2319 case CS_CERTIF: 2320 for (cp = cinfo; cp != NULL; cp = cp->link) { 2321 snprintf(str, sizeof(str), "%s %s 0x%x", 2322 cp->subject, cp->issuer, cp->flags); 2323 ctl_putstr(sys_var[CS_CERTIF].text, str, 2324 strlen(str)); 2325 ctl_putfs(sys_var[CS_REVTIME].text, cp->last); 2326 } 2327 break; 2328 2329 case CS_PUBLIC: 2330 if (hostval.tstamp != 0) 2331 ctl_putfs(sys_var[CS_PUBLIC].text, 2332 ntohl(hostval.tstamp)); 2333 break; 2334 #endif /* AUTOKEY */ 2335 } 2336 } 2337 2338 2339 /* 2340 * ctl_putpeer - output a peer variable 2341 */ 2342 static void 2343 ctl_putpeer( 2344 int id, 2345 struct peer *p 2346 ) 2347 { 2348 char buf[CTL_MAX_DATA_LEN]; 2349 char *s; 2350 char *t; 2351 char *be; 2352 int i; 2353 const struct ctl_var *k; 2354 #ifdef AUTOKEY 2355 struct autokey *ap; 2356 const EVP_MD *dp; 2357 const char *str; 2358 #endif /* AUTOKEY */ 2359 2360 switch (id) { 2361 2362 case CP_CONFIG: 2363 ctl_putuint(peer_var[id].text, 2364 !(FLAG_PREEMPT & p->flags)); 2365 break; 2366 2367 case CP_AUTHENABLE: 2368 ctl_putuint(peer_var[id].text, !(p->keyid)); 2369 break; 2370 2371 case CP_AUTHENTIC: 2372 ctl_putuint(peer_var[id].text, 2373 !!(FLAG_AUTHENTIC & p->flags)); 2374 break; 2375 2376 case CP_SRCADR: 2377 ctl_putadr(peer_var[id].text, 0, &p->srcadr); 2378 break; 2379 2380 case CP_SRCPORT: 2381 ctl_putuint(peer_var[id].text, SRCPORT(&p->srcadr)); 2382 break; 2383 2384 case CP_SRCHOST: 2385 if (p->hostname != NULL) 2386 ctl_putstr(peer_var[id].text, p->hostname, 2387 strlen(p->hostname)); 2388 break; 2389 2390 case CP_DSTADR: 2391 ctl_putadr(peer_var[id].text, 0, 2392 (p->dstadr != NULL) 2393 ? &p->dstadr->sin 2394 : NULL); 2395 break; 2396 2397 case CP_DSTPORT: 2398 ctl_putuint(peer_var[id].text, 2399 (p->dstadr != NULL) 2400 ? SRCPORT(&p->dstadr->sin) 2401 : 0); 2402 break; 2403 2404 case CP_IN: 2405 if (p->r21 > 0.) 2406 ctl_putdbl(peer_var[id].text, p->r21 / 1e3); 2407 break; 2408 2409 case CP_OUT: 2410 if (p->r34 > 0.) 2411 ctl_putdbl(peer_var[id].text, p->r34 / 1e3); 2412 break; 2413 2414 case CP_RATE: 2415 ctl_putuint(peer_var[id].text, p->throttle); 2416 break; 2417 2418 case CP_LEAP: 2419 ctl_putuint(peer_var[id].text, p->leap); 2420 break; 2421 2422 case CP_HMODE: 2423 ctl_putuint(peer_var[id].text, p->hmode); 2424 break; 2425 2426 case CP_STRATUM: 2427 ctl_putuint(peer_var[id].text, p->stratum); 2428 break; 2429 2430 case CP_PPOLL: 2431 ctl_putuint(peer_var[id].text, p->ppoll); 2432 break; 2433 2434 case CP_HPOLL: 2435 ctl_putuint(peer_var[id].text, p->hpoll); 2436 break; 2437 2438 case CP_PRECISION: 2439 ctl_putint(peer_var[id].text, p->precision); 2440 break; 2441 2442 case CP_ROOTDELAY: 2443 ctl_putdbl(peer_var[id].text, p->rootdelay * 1e3); 2444 break; 2445 2446 case CP_ROOTDISPERSION: 2447 ctl_putdbl(peer_var[id].text, p->rootdisp * 1e3); 2448 break; 2449 2450 case CP_REFID: 2451 #ifdef REFCLOCK 2452 if (p->flags & FLAG_REFCLOCK) { 2453 ctl_putrefid(peer_var[id].text, p->refid); 2454 break; 2455 } 2456 #endif 2457 if (p->stratum > 1 && p->stratum < STRATUM_UNSPEC) 2458 ctl_putadr(peer_var[id].text, p->refid, 2459 NULL); 2460 else 2461 ctl_putrefid(peer_var[id].text, p->refid); 2462 break; 2463 2464 case CP_REFTIME: 2465 ctl_putts(peer_var[id].text, &p->reftime); 2466 break; 2467 2468 case CP_ORG: 2469 ctl_putts(peer_var[id].text, &p->aorg); 2470 break; 2471 2472 case CP_REC: 2473 ctl_putts(peer_var[id].text, &p->dst); 2474 break; 2475 2476 case CP_XMT: 2477 if (p->xleave) 2478 ctl_putdbl(peer_var[id].text, p->xleave * 1e3); 2479 break; 2480 2481 case CP_BIAS: 2482 if (p->bias != 0.) 2483 ctl_putdbl(peer_var[id].text, p->bias * 1e3); 2484 break; 2485 2486 case CP_REACH: 2487 ctl_puthex(peer_var[id].text, p->reach); 2488 break; 2489 2490 case CP_FLASH: 2491 ctl_puthex(peer_var[id].text, p->flash); 2492 break; 2493 2494 case CP_TTL: 2495 #ifdef REFCLOCK 2496 if (p->flags & FLAG_REFCLOCK) { 2497 ctl_putuint(peer_var[id].text, p->ttl); 2498 break; 2499 } 2500 #endif 2501 if (p->ttl > 0 && p->ttl < COUNTOF(sys_ttl)) 2502 ctl_putint(peer_var[id].text, 2503 sys_ttl[p->ttl]); 2504 break; 2505 2506 case CP_UNREACH: 2507 ctl_putuint(peer_var[id].text, p->unreach); 2508 break; 2509 2510 case CP_TIMER: 2511 ctl_putuint(peer_var[id].text, 2512 p->nextdate - current_time); 2513 break; 2514 2515 case CP_DELAY: 2516 ctl_putdbl(peer_var[id].text, p->delay * 1e3); 2517 break; 2518 2519 case CP_OFFSET: 2520 ctl_putdbl(peer_var[id].text, p->offset * 1e3); 2521 break; 2522 2523 case CP_JITTER: 2524 ctl_putdbl(peer_var[id].text, p->jitter * 1e3); 2525 break; 2526 2527 case CP_DISPERSION: 2528 ctl_putdbl(peer_var[id].text, p->disp * 1e3); 2529 break; 2530 2531 case CP_KEYID: 2532 if (p->keyid > NTP_MAXKEY) 2533 ctl_puthex(peer_var[id].text, p->keyid); 2534 else 2535 ctl_putuint(peer_var[id].text, p->keyid); 2536 break; 2537 2538 case CP_FILTDELAY: 2539 ctl_putarray(peer_var[id].text, p->filter_delay, 2540 p->filter_nextpt); 2541 break; 2542 2543 case CP_FILTOFFSET: 2544 ctl_putarray(peer_var[id].text, p->filter_offset, 2545 p->filter_nextpt); 2546 break; 2547 2548 case CP_FILTERROR: 2549 ctl_putarray(peer_var[id].text, p->filter_disp, 2550 p->filter_nextpt); 2551 break; 2552 2553 case CP_PMODE: 2554 ctl_putuint(peer_var[id].text, p->pmode); 2555 break; 2556 2557 case CP_RECEIVED: 2558 ctl_putuint(peer_var[id].text, p->received); 2559 break; 2560 2561 case CP_SENT: 2562 ctl_putuint(peer_var[id].text, p->sent); 2563 break; 2564 2565 case CP_VARLIST: 2566 s = buf; 2567 be = buf + sizeof(buf); 2568 if (strlen(peer_var[id].text) + 4 > sizeof(buf)) 2569 break; /* really long var name */ 2570 2571 snprintf(s, sizeof(buf), "%s=\"", peer_var[id].text); 2572 s += strlen(s); 2573 t = s; 2574 for (k = peer_var; !(EOV & k->flags); k++) { 2575 if (PADDING & k->flags) 2576 continue; 2577 i = strlen(k->text); 2578 if (s + i + 1 >= be) 2579 break; 2580 if (s != t) 2581 *s++ = ','; 2582 memcpy(s, k->text, i); 2583 s += i; 2584 } 2585 if (s + 2 < be) { 2586 *s++ = '"'; 2587 *s = '\0'; 2588 ctl_putdata(buf, (u_int)(s - buf), 0); 2589 } 2590 break; 2591 2592 case CP_TIMEREC: 2593 ctl_putuint(peer_var[id].text, 2594 current_time - p->timereceived); 2595 break; 2596 2597 case CP_TIMEREACH: 2598 ctl_putuint(peer_var[id].text, 2599 current_time - p->timereachable); 2600 break; 2601 2602 case CP_BADAUTH: 2603 ctl_putuint(peer_var[id].text, p->badauth); 2604 break; 2605 2606 case CP_BOGUSORG: 2607 ctl_putuint(peer_var[id].text, p->bogusorg); 2608 break; 2609 2610 case CP_OLDPKT: 2611 ctl_putuint(peer_var[id].text, p->oldpkt); 2612 break; 2613 2614 case CP_SELDISP: 2615 ctl_putuint(peer_var[id].text, p->seldisptoolarge); 2616 break; 2617 2618 case CP_SELBROKEN: 2619 ctl_putuint(peer_var[id].text, p->selbroken); 2620 break; 2621 2622 case CP_CANDIDATE: 2623 ctl_putuint(peer_var[id].text, p->status); 2624 break; 2625 #ifdef AUTOKEY 2626 case CP_FLAGS: 2627 if (p->crypto) 2628 ctl_puthex(peer_var[id].text, p->crypto); 2629 break; 2630 2631 case CP_SIGNATURE: 2632 if (p->crypto) { 2633 dp = EVP_get_digestbynid(p->crypto >> 16); 2634 str = OBJ_nid2ln(EVP_MD_pkey_type(dp)); 2635 ctl_putstr(peer_var[id].text, str, strlen(str)); 2636 } 2637 break; 2638 2639 case CP_HOST: 2640 if (p->subject != NULL) 2641 ctl_putstr(peer_var[id].text, p->subject, 2642 strlen(p->subject)); 2643 break; 2644 2645 case CP_VALID: /* not used */ 2646 break; 2647 2648 case CP_INITSEQ: 2649 if (NULL == (ap = p->recval.ptr)) 2650 break; 2651 2652 ctl_putint(peer_var[CP_INITSEQ].text, ap->seq); 2653 ctl_puthex(peer_var[CP_INITKEY].text, ap->key); 2654 ctl_putfs(peer_var[CP_INITTSP].text, 2655 ntohl(p->recval.tstamp)); 2656 break; 2657 2658 case CP_IDENT: 2659 if (p->ident != NULL) 2660 ctl_putstr(peer_var[id].text, p->ident, 2661 strlen(p->ident)); 2662 break; 2663 2664 2665 #endif /* AUTOKEY */ 2666 } 2667 } 2668 2669 2670 #ifdef REFCLOCK 2671 /* 2672 * ctl_putclock - output clock variables 2673 */ 2674 static void 2675 ctl_putclock( 2676 int id, 2677 struct refclockstat *pcs, 2678 int mustput 2679 ) 2680 { 2681 char buf[CTL_MAX_DATA_LEN]; 2682 char *s, *t, *be; 2683 const char *ss; 2684 int i; 2685 const struct ctl_var *k; 2686 2687 switch (id) { 2688 2689 case CC_TYPE: 2690 if (mustput || pcs->clockdesc == NULL 2691 || *(pcs->clockdesc) == '\0') { 2692 ctl_putuint(clock_var[id].text, pcs->type); 2693 } 2694 break; 2695 case CC_TIMECODE: 2696 ctl_putstr(clock_var[id].text, 2697 pcs->p_lastcode, 2698 (unsigned)pcs->lencode); 2699 break; 2700 2701 case CC_POLL: 2702 ctl_putuint(clock_var[id].text, pcs->polls); 2703 break; 2704 2705 case CC_NOREPLY: 2706 ctl_putuint(clock_var[id].text, 2707 pcs->noresponse); 2708 break; 2709 2710 case CC_BADFORMAT: 2711 ctl_putuint(clock_var[id].text, 2712 pcs->badformat); 2713 break; 2714 2715 case CC_BADDATA: 2716 ctl_putuint(clock_var[id].text, 2717 pcs->baddata); 2718 break; 2719 2720 case CC_FUDGETIME1: 2721 if (mustput || (pcs->haveflags & CLK_HAVETIME1)) 2722 ctl_putdbl(clock_var[id].text, 2723 pcs->fudgetime1 * 1e3); 2724 break; 2725 2726 case CC_FUDGETIME2: 2727 if (mustput || (pcs->haveflags & CLK_HAVETIME2)) 2728 ctl_putdbl(clock_var[id].text, 2729 pcs->fudgetime2 * 1e3); 2730 break; 2731 2732 case CC_FUDGEVAL1: 2733 if (mustput || (pcs->haveflags & CLK_HAVEVAL1)) 2734 ctl_putint(clock_var[id].text, 2735 pcs->fudgeval1); 2736 break; 2737 2738 case CC_FUDGEVAL2: 2739 if (mustput || (pcs->haveflags & CLK_HAVEVAL2)) { 2740 if (pcs->fudgeval1 > 1) 2741 ctl_putadr(clock_var[id].text, 2742 pcs->fudgeval2, NULL); 2743 else 2744 ctl_putrefid(clock_var[id].text, 2745 pcs->fudgeval2); 2746 } 2747 break; 2748 2749 case CC_FLAGS: 2750 ctl_putuint(clock_var[id].text, pcs->flags); 2751 break; 2752 2753 case CC_DEVICE: 2754 if (pcs->clockdesc == NULL || 2755 *(pcs->clockdesc) == '\0') { 2756 if (mustput) 2757 ctl_putstr(clock_var[id].text, 2758 "", 0); 2759 } else { 2760 ctl_putstr(clock_var[id].text, 2761 pcs->clockdesc, 2762 strlen(pcs->clockdesc)); 2763 } 2764 break; 2765 2766 case CC_VARLIST: 2767 s = buf; 2768 be = buf + sizeof(buf); 2769 if (strlen(clock_var[CC_VARLIST].text) + 4 > 2770 sizeof(buf)) 2771 break; /* really long var name */ 2772 2773 snprintf(s, sizeof(buf), "%s=\"", 2774 clock_var[CC_VARLIST].text); 2775 s += strlen(s); 2776 t = s; 2777 2778 for (k = clock_var; !(EOV & k->flags); k++) { 2779 if (PADDING & k->flags) 2780 continue; 2781 2782 i = strlen(k->text); 2783 if (s + i + 1 >= be) 2784 break; 2785 2786 if (s != t) 2787 *s++ = ','; 2788 memcpy(s, k->text, i); 2789 s += i; 2790 } 2791 2792 for (k = pcs->kv_list; k && !(EOV & k->flags); k++) { 2793 if (PADDING & k->flags) 2794 continue; 2795 2796 ss = k->text; 2797 if (NULL == ss) 2798 continue; 2799 2800 while (*ss && *ss != '=') 2801 ss++; 2802 i = ss - k->text; 2803 if (s + i + 1 >= be) 2804 break; 2805 2806 if (s != t) 2807 *s++ = ','; 2808 memcpy(s, k->text, (unsigned)i); 2809 s += i; 2810 *s = '\0'; 2811 } 2812 if (s + 2 >= be) 2813 break; 2814 2815 *s++ = '"'; 2816 *s = '\0'; 2817 ctl_putdata(buf, (unsigned)(s - buf), 0); 2818 break; 2819 } 2820 } 2821 #endif 2822 2823 2824 2825 /* 2826 * ctl_getitem - get the next data item from the incoming packet 2827 */ 2828 static const struct ctl_var * 2829 ctl_getitem( 2830 const struct ctl_var *var_list, 2831 char **data 2832 ) 2833 { 2834 static const struct ctl_var eol = { 0, EOV, NULL }; 2835 static char buf[128]; 2836 static u_long quiet_until; 2837 const struct ctl_var *v; 2838 const char *pch; 2839 char *cp; 2840 char *tp; 2841 2842 /* 2843 * Delete leading commas and white space 2844 */ 2845 while (reqpt < reqend && (*reqpt == ',' || 2846 isspace((unsigned char)*reqpt))) 2847 reqpt++; 2848 if (reqpt >= reqend) 2849 return NULL; 2850 2851 if (NULL == var_list) 2852 return &eol; 2853 2854 /* 2855 * Look for a first character match on the tag. If we find 2856 * one, see if it is a full match. 2857 */ 2858 v = var_list; 2859 cp = reqpt; 2860 for (v = var_list; !(EOV & v->flags); v++) { 2861 if (!(PADDING & v->flags) && *cp == *(v->text)) { 2862 pch = v->text; 2863 while ('\0' != *pch && '=' != *pch && cp < reqend 2864 && *cp == *pch) { 2865 cp++; 2866 pch++; 2867 } 2868 if ('\0' == *pch || '=' == *pch) { 2869 while (cp < reqend && isspace((u_char)*cp)) 2870 cp++; 2871 if (cp == reqend || ',' == *cp) { 2872 buf[0] = '\0'; 2873 *data = buf; 2874 if (cp < reqend) 2875 cp++; 2876 reqpt = cp; 2877 return v; 2878 } 2879 if ('=' == *cp) { 2880 cp++; 2881 tp = buf; 2882 while (cp < reqend && isspace((u_char)*cp)) 2883 cp++; 2884 while (cp < reqend && *cp != ',') { 2885 *tp++ = *cp++; 2886 if ((size_t)(tp - buf) >= sizeof(buf)) { 2887 ctl_error(CERR_BADFMT); 2888 numctlbadpkts++; 2889 NLOG(NLOG_SYSEVENT) 2890 if (quiet_until <= current_time) { 2891 quiet_until = current_time + 300; 2892 msyslog(LOG_WARNING, 2893 "Possible 'ntpdx' exploit from %s#%u (possibly spoofed)", stoa(rmt_addr), SRCPORT(rmt_addr)); 2894 } 2895 return NULL; 2896 } 2897 } 2898 if (cp < reqend) 2899 cp++; 2900 *tp-- = '\0'; 2901 while (tp >= buf && isspace((u_char)*tp)) 2902 *tp-- = '\0'; 2903 reqpt = cp; 2904 *data = buf; 2905 return v; 2906 } 2907 } 2908 cp = reqpt; 2909 } 2910 } 2911 return v; 2912 } 2913 2914 2915 /* 2916 * control_unspec - response to an unspecified op-code 2917 */ 2918 /*ARGSUSED*/ 2919 static void 2920 control_unspec( 2921 struct recvbuf *rbufp, 2922 int restrict_mask 2923 ) 2924 { 2925 struct peer *peer; 2926 2927 /* 2928 * What is an appropriate response to an unspecified op-code? 2929 * I return no errors and no data, unless a specified assocation 2930 * doesn't exist. 2931 */ 2932 if (res_associd) { 2933 peer = findpeerbyassoc(res_associd); 2934 if (NULL == peer) { 2935 ctl_error(CERR_BADASSOC); 2936 return; 2937 } 2938 rpkt.status = htons(ctlpeerstatus(peer)); 2939 } else 2940 rpkt.status = htons(ctlsysstatus()); 2941 ctl_flushpkt(0); 2942 } 2943 2944 2945 /* 2946 * read_status - return either a list of associd's, or a particular 2947 * peer's status. 2948 */ 2949 /*ARGSUSED*/ 2950 static void 2951 read_status( 2952 struct recvbuf *rbufp, 2953 int restrict_mask 2954 ) 2955 { 2956 struct peer *peer; 2957 const u_char *cp; 2958 size_t n; 2959 /* a_st holds association ID, status pairs alternating */ 2960 u_short a_st[CTL_MAX_DATA_LEN / sizeof(u_short)]; 2961 2962 #ifdef DEBUG 2963 if (debug > 2) 2964 printf("read_status: ID %d\n", res_associd); 2965 #endif 2966 /* 2967 * Two choices here. If the specified association ID is 2968 * zero we return all known assocation ID's. Otherwise 2969 * we return a bunch of stuff about the particular peer. 2970 */ 2971 if (res_associd) { 2972 peer = findpeerbyassoc(res_associd); 2973 if (NULL == peer) { 2974 ctl_error(CERR_BADASSOC); 2975 return; 2976 } 2977 rpkt.status = htons(ctlpeerstatus(peer)); 2978 if (res_authokay) 2979 peer->num_events = 0; 2980 /* 2981 * For now, output everything we know about the 2982 * peer. May be more selective later. 2983 */ 2984 for (cp = def_peer_var; *cp != 0; cp++) 2985 ctl_putpeer((int)*cp, peer); 2986 ctl_flushpkt(0); 2987 return; 2988 } 2989 n = 0; 2990 rpkt.status = htons(ctlsysstatus()); 2991 for (peer = peer_list; peer != NULL; peer = peer->p_link) { 2992 a_st[n++] = htons(peer->associd); 2993 a_st[n++] = htons(ctlpeerstatus(peer)); 2994 /* two entries each loop iteration, so n + 1 */ 2995 if (n + 1 >= COUNTOF(a_st)) { 2996 ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 2997 1); 2998 n = 0; 2999 } 3000 } 3001 if (n) 3002 ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 1); 3003 ctl_flushpkt(0); 3004 } 3005 3006 3007 /* 3008 * read_peervars - half of read_variables() implementation 3009 */ 3010 static void 3011 read_peervars(void) 3012 { 3013 const struct ctl_var *v; 3014 struct peer *peer; 3015 const u_char *cp; 3016 size_t i; 3017 char * valuep; 3018 u_char wants[CP_MAXCODE + 1]; 3019 u_int gotvar; 3020 3021 /* 3022 * Wants info for a particular peer. See if we know 3023 * the guy. 3024 */ 3025 peer = findpeerbyassoc(res_associd); 3026 if (NULL == peer) { 3027 ctl_error(CERR_BADASSOC); 3028 return; 3029 } 3030 rpkt.status = htons(ctlpeerstatus(peer)); 3031 if (res_authokay) 3032 peer->num_events = 0; 3033 ZERO(wants); 3034 gotvar = 0; 3035 while (NULL != (v = ctl_getitem(peer_var, &valuep))) { 3036 if (v->flags & EOV) { 3037 ctl_error(CERR_UNKNOWNVAR); 3038 return; 3039 } 3040 NTP_INSIST(v->code < COUNTOF(wants)); 3041 wants[v->code] = 1; 3042 gotvar = 1; 3043 } 3044 if (gotvar) { 3045 for (i = 1; i < COUNTOF(wants); i++) 3046 if (wants[i]) 3047 ctl_putpeer(i, peer); 3048 } else 3049 for (cp = def_peer_var; *cp != 0; cp++) 3050 ctl_putpeer((int)*cp, peer); 3051 ctl_flushpkt(0); 3052 } 3053 3054 3055 /* 3056 * read_sysvars - half of read_variables() implementation 3057 */ 3058 static void 3059 read_sysvars(void) 3060 { 3061 const struct ctl_var *v; 3062 struct ctl_var *kv; 3063 u_int n; 3064 u_int gotvar; 3065 const u_char *cs; 3066 char * valuep; 3067 const char * pch; 3068 u_char *wants; 3069 size_t wants_count; 3070 3071 /* 3072 * Wants system variables. Figure out which he wants 3073 * and give them to him. 3074 */ 3075 rpkt.status = htons(ctlsysstatus()); 3076 if (res_authokay) 3077 ctl_sys_num_events = 0; 3078 wants_count = CS_MAXCODE + 1 + count_var(ext_sys_var); 3079 wants = emalloc_zero(wants_count); 3080 gotvar = 0; 3081 while (NULL != (v = ctl_getitem(sys_var, &valuep))) { 3082 if (!(EOV & v->flags)) { 3083 NTP_INSIST(v->code < wants_count); 3084 wants[v->code] = 1; 3085 gotvar = 1; 3086 } else { 3087 v = ctl_getitem(ext_sys_var, &valuep); 3088 NTP_INSIST(v != NULL); 3089 if (EOV & v->flags) { 3090 ctl_error(CERR_UNKNOWNVAR); 3091 free(wants); 3092 return; 3093 } 3094 n = v->code + CS_MAXCODE + 1; 3095 NTP_INSIST(n < wants_count); 3096 wants[n] = 1; 3097 gotvar = 1; 3098 } 3099 } 3100 if (gotvar) { 3101 for (n = 1; n <= CS_MAXCODE; n++) 3102 if (wants[n]) 3103 ctl_putsys(n); 3104 for (n = 0; n + CS_MAXCODE + 1 < wants_count; n++) 3105 if (wants[n + CS_MAXCODE + 1]) { 3106 pch = ext_sys_var[n].text; 3107 ctl_putdata(pch, strlen(pch), 0); 3108 } 3109 } else { 3110 for (cs = def_sys_var; *cs != 0; cs++) 3111 ctl_putsys((int)*cs); 3112 for (kv = ext_sys_var; kv && !(EOV & kv->flags); kv++) 3113 if (DEF & kv->flags) 3114 ctl_putdata(kv->text, strlen(kv->text), 3115 0); 3116 } 3117 free(wants); 3118 ctl_flushpkt(0); 3119 } 3120 3121 3122 /* 3123 * read_variables - return the variables the caller asks for 3124 */ 3125 /*ARGSUSED*/ 3126 static void 3127 read_variables( 3128 struct recvbuf *rbufp, 3129 int restrict_mask 3130 ) 3131 { 3132 if (res_associd) 3133 read_peervars(); 3134 else 3135 read_sysvars(); 3136 } 3137 3138 3139 /* 3140 * write_variables - write into variables. We only allow leap bit 3141 * writing this way. 3142 */ 3143 /*ARGSUSED*/ 3144 static void 3145 write_variables( 3146 struct recvbuf *rbufp, 3147 int restrict_mask 3148 ) 3149 { 3150 const struct ctl_var *v; 3151 int ext_var; 3152 char *valuep; 3153 long val; 3154 size_t octets; 3155 char *vareqv; 3156 const char *t; 3157 char *tt; 3158 3159 val = 0; 3160 /* 3161 * If he's trying to write into a peer tell him no way 3162 */ 3163 if (res_associd != 0) { 3164 ctl_error(CERR_PERMISSION); 3165 return; 3166 } 3167 3168 /* 3169 * Set status 3170 */ 3171 rpkt.status = htons(ctlsysstatus()); 3172 3173 /* 3174 * Look through the variables. Dump out at the first sign of 3175 * trouble. 3176 */ 3177 while ((v = ctl_getitem(sys_var, &valuep)) != 0) { 3178 ext_var = 0; 3179 if (v->flags & EOV) { 3180 if ((v = ctl_getitem(ext_sys_var, &valuep)) != 3181 0) { 3182 if (v->flags & EOV) { 3183 ctl_error(CERR_UNKNOWNVAR); 3184 return; 3185 } 3186 ext_var = 1; 3187 } else { 3188 break; 3189 } 3190 } 3191 if (!(v->flags & CAN_WRITE)) { 3192 ctl_error(CERR_PERMISSION); 3193 return; 3194 } 3195 if (!ext_var && (*valuep == '\0' || !atoint(valuep, 3196 &val))) { 3197 ctl_error(CERR_BADFMT); 3198 return; 3199 } 3200 if (!ext_var && (val & ~LEAP_NOTINSYNC) != 0) { 3201 ctl_error(CERR_BADVALUE); 3202 return; 3203 } 3204 3205 if (ext_var) { 3206 octets = strlen(v->text) + strlen(valuep) + 2; 3207 vareqv = emalloc(octets); 3208 tt = vareqv; 3209 t = v->text; 3210 while (*t && *t != '=') 3211 *tt++ = *t++; 3212 *tt++ = '='; 3213 memcpy(tt, valuep, 1 + strlen(valuep)); 3214 set_sys_var(vareqv, 1 + strlen(vareqv), v->flags); 3215 free(vareqv); 3216 } else { 3217 ctl_error(CERR_UNSPEC); /* really */ 3218 return; 3219 } 3220 } 3221 3222 /* 3223 * If we got anything, do it. xxx nothing to do *** 3224 */ 3225 /* 3226 if (leapind != ~0 || leapwarn != ~0) { 3227 if (!leap_setleap((int)leapind, (int)leapwarn)) { 3228 ctl_error(CERR_PERMISSION); 3229 return; 3230 } 3231 } 3232 */ 3233 ctl_flushpkt(0); 3234 } 3235 3236 /* 3237 * configure() processes ntpq :config/config-from-file, allowing 3238 * generic runtime reconfiguration. 3239 */ 3240 static void configure( 3241 struct recvbuf *rbufp, 3242 int restrict_mask 3243 ) 3244 { 3245 size_t data_count; 3246 int retval; 3247 int replace_nl; 3248 3249 /* I haven't yet implemented changes to an existing association. 3250 * Hence check if the association id is 0 3251 */ 3252 if (res_associd != 0) { 3253 ctl_error(CERR_BADVALUE); 3254 return; 3255 } 3256 3257 if (RES_NOMODIFY & restrict_mask) { 3258 snprintf(remote_config.err_msg, 3259 sizeof(remote_config.err_msg), 3260 "runtime configuration prohibited by restrict ... nomodify"); 3261 ctl_putdata(remote_config.err_msg, 3262 strlen(remote_config.err_msg), 0); 3263 ctl_flushpkt(0); 3264 NLOG(NLOG_SYSINFO) 3265 msyslog(LOG_NOTICE, 3266 "runtime config from %s rejected due to nomodify restriction", 3267 stoa(&rbufp->recv_srcadr)); 3268 sys_restricted++; 3269 return; 3270 } 3271 3272 /* Initialize the remote config buffer */ 3273 data_count = reqend - reqpt; 3274 memcpy(remote_config.buffer, reqpt, data_count); 3275 if (data_count > 0 3276 && '\n' != remote_config.buffer[data_count - 1]) 3277 remote_config.buffer[data_count++] = '\n'; 3278 remote_config.buffer[data_count] = '\0'; 3279 remote_config.pos = 0; 3280 remote_config.err_pos = 0; 3281 remote_config.no_errors = 0; 3282 3283 /* do not include terminating newline in log */ 3284 if (data_count > 0 3285 && '\n' == remote_config.buffer[data_count - 1]) { 3286 remote_config.buffer[data_count - 1] = '\0'; 3287 replace_nl = TRUE; 3288 } else { 3289 replace_nl = FALSE; 3290 } 3291 3292 DPRINTF(1, ("Got Remote Configuration Command: %s\n", 3293 remote_config.buffer)); 3294 msyslog(LOG_NOTICE, "%s config: %s", 3295 stoa(&rbufp->recv_srcadr), 3296 remote_config.buffer); 3297 3298 if (replace_nl) 3299 remote_config.buffer[data_count - 1] = '\n'; 3300 3301 config_remotely(&rbufp->recv_srcadr); 3302 3303 /* 3304 * Check if errors were reported. If not, output 'Config 3305 * Succeeded'. Else output the error count. It would be nice 3306 * to output any parser error messages. 3307 */ 3308 if (0 == remote_config.no_errors) { 3309 retval = snprintf(remote_config.err_msg, 3310 sizeof(remote_config.err_msg), 3311 "Config Succeeded"); 3312 if (retval > 0) 3313 remote_config.err_pos += retval; 3314 } 3315 3316 ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0); 3317 ctl_flushpkt(0); 3318 3319 DPRINTF(1, ("Reply: %s\n", remote_config.err_msg)); 3320 3321 if (remote_config.no_errors > 0) 3322 msyslog(LOG_NOTICE, "%d error in %s config", 3323 remote_config.no_errors, 3324 stoa(&rbufp->recv_srcadr)); 3325 } 3326 3327 3328 /* 3329 * derive_nonce - generate client-address-specific nonce value 3330 * associated with a given timestamp. 3331 */ 3332 static u_int32 derive_nonce( 3333 sockaddr_u * addr, 3334 u_int32 ts_i, 3335 u_int32 ts_f 3336 ) 3337 { 3338 static u_int32 salt[2]; 3339 union d_tag { 3340 u_char digest[EVP_MAX_MD_SIZE]; 3341 u_int32 extract; 3342 } d; 3343 EVP_MD_CTX ctx; 3344 u_int len; 3345 3346 while (!salt[0]) 3347 salt[0] = ntp_random(); 3348 salt[1] = conf_file_sum; 3349 3350 EVP_DigestInit(&ctx, EVP_get_digestbynid(NID_md5)); 3351 EVP_DigestUpdate(&ctx, salt, sizeof(salt)); 3352 EVP_DigestUpdate(&ctx, &ts_i, sizeof(ts_i)); 3353 EVP_DigestUpdate(&ctx, &ts_f, sizeof(ts_f)); 3354 if (IS_IPV4(addr)) 3355 EVP_DigestUpdate(&ctx, &SOCK_ADDR4(addr), 3356 sizeof(SOCK_ADDR4(addr))); 3357 else 3358 EVP_DigestUpdate(&ctx, &SOCK_ADDR6(addr), 3359 sizeof(SOCK_ADDR6(addr))); 3360 EVP_DigestUpdate(&ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr))); 3361 EVP_DigestUpdate(&ctx, salt, sizeof(salt)); 3362 EVP_DigestFinal(&ctx, d.digest, &len); 3363 3364 return d.extract; 3365 } 3366 3367 3368 /* 3369 * generate_nonce - generate client-address-specific nonce string. 3370 */ 3371 static void generate_nonce( 3372 struct recvbuf * rbufp, 3373 char * nonce, 3374 size_t nonce_octets 3375 ) 3376 { 3377 u_int32 derived; 3378 3379 derived = derive_nonce(&rbufp->recv_srcadr, 3380 rbufp->recv_time.l_ui, 3381 rbufp->recv_time.l_uf); 3382 snprintf(nonce, nonce_octets, "%08x%08x%08x", 3383 rbufp->recv_time.l_ui, rbufp->recv_time.l_uf, derived); 3384 } 3385 3386 3387 /* 3388 * validate_nonce - validate client-address-specific nonce string. 3389 * 3390 * Returns TRUE if the local calculation of the nonce matches the 3391 * client-provided value and the timestamp is recent enough. 3392 */ 3393 static int validate_nonce( 3394 const char * pnonce, 3395 struct recvbuf * rbufp 3396 ) 3397 { 3398 u_int ts_i; 3399 u_int ts_f; 3400 l_fp ts; 3401 l_fp now_delta; 3402 u_int supposed; 3403 u_int derived; 3404 3405 if (3 != sscanf(pnonce, "%08x%08x%08x", &ts_i, &ts_f, &supposed)) 3406 return FALSE; 3407 3408 ts.l_ui = (u_int32)ts_i; 3409 ts.l_uf = (u_int32)ts_f; 3410 derived = derive_nonce(&rbufp->recv_srcadr, ts.l_ui, ts.l_uf); 3411 get_systime(&now_delta); 3412 L_SUB(&now_delta, &ts); 3413 3414 return (supposed == derived && now_delta.l_ui < 16); 3415 } 3416 3417 3418 /* 3419 * send_random_tag_value - send a randomly-generated three character 3420 * tag prefix, a '.', an index, a '=' and a 3421 * random integer value. 3422 * 3423 * To try to force clients to ignore unrecognized tags in mrulist, 3424 * reslist, and ifstats responses, the first and last rows are spiced 3425 * with randomly-generated tag names with correct .# index. Make it 3426 * three characters knowing that none of the currently-used subscripted 3427 * tags have that length, avoiding the need to test for 3428 * tag collision. 3429 */ 3430 static void 3431 send_random_tag_value( 3432 int indx 3433 ) 3434 { 3435 int noise; 3436 char buf[32]; 3437 3438 noise = rand() ^ (rand() << 16); 3439 buf[0] = 'a' + noise % 26; 3440 noise >>= 5; 3441 buf[1] = 'a' + noise % 26; 3442 noise >>= 5; 3443 buf[2] = 'a' + noise % 26; 3444 noise >>= 5; 3445 buf[3] = '.'; 3446 snprintf(&buf[4], sizeof(buf) - 4, "%d", indx); 3447 ctl_putuint(buf, noise); 3448 } 3449 3450 3451 /* 3452 * Send a MRU list entry in response to a "ntpq -c mrulist" operation. 3453 * 3454 * To keep clients honest about not depending on the order of values, 3455 * and thereby avoid being locked into ugly workarounds to maintain 3456 * backward compatibility later as new fields are added to the response, 3457 * the order is random. 3458 */ 3459 static void 3460 send_mru_entry( 3461 mon_entry * mon, 3462 int count 3463 ) 3464 { 3465 const char first_fmt[] = "first.%d"; 3466 const char ct_fmt[] = "ct.%d"; 3467 const char mv_fmt[] = "mv.%d"; 3468 const char rs_fmt[] = "rs.%d"; 3469 char tag[32]; 3470 u_char sent[6]; /* 6 tag=value pairs */ 3471 u_int32 noise; 3472 u_int which; 3473 u_int remaining; 3474 const char * pch; 3475 3476 remaining = COUNTOF(sent); 3477 ZERO(sent); 3478 noise = (u_int32)(rand() ^ (rand() << 16)); 3479 while (remaining > 0) { 3480 which = (noise & 7) % COUNTOF(sent); 3481 noise >>= 3; 3482 while (sent[which]) 3483 which = (which + 1) % COUNTOF(sent); 3484 3485 switch (which) { 3486 3487 case 0: 3488 snprintf(tag, sizeof(tag), addr_fmt, count); 3489 pch = sptoa(&mon->rmtadr); 3490 ctl_putunqstr(tag, pch, strlen(pch)); 3491 break; 3492 3493 case 1: 3494 snprintf(tag, sizeof(tag), last_fmt, count); 3495 ctl_putts(tag, &mon->last); 3496 break; 3497 3498 case 2: 3499 snprintf(tag, sizeof(tag), first_fmt, count); 3500 ctl_putts(tag, &mon->first); 3501 break; 3502 3503 case 3: 3504 snprintf(tag, sizeof(tag), ct_fmt, count); 3505 ctl_putint(tag, mon->count); 3506 break; 3507 3508 case 4: 3509 snprintf(tag, sizeof(tag), mv_fmt, count); 3510 ctl_putuint(tag, mon->vn_mode); 3511 break; 3512 3513 case 5: 3514 snprintf(tag, sizeof(tag), rs_fmt, count); 3515 ctl_puthex(tag, mon->flags); 3516 break; 3517 } 3518 sent[which] = TRUE; 3519 remaining--; 3520 } 3521 } 3522 3523 3524 /* 3525 * read_mru_list - supports ntpq's mrulist command. 3526 * 3527 * The challenge here is to match ntpdc's monlist functionality without 3528 * being limited to hundreds of entries returned total, and without 3529 * requiring state on the server. If state were required, ntpq's 3530 * mrulist command would require authentication. 3531 * 3532 * The approach was suggested by Ry Jones. A finite and variable number 3533 * of entries are retrieved per request, to avoid having responses with 3534 * such large numbers of packets that socket buffers are overflowed and 3535 * packets lost. The entries are retrieved oldest-first, taking into 3536 * account that the MRU list will be changing between each request. We 3537 * can expect to see duplicate entries for addresses updated in the MRU 3538 * list during the fetch operation. In the end, the client can assemble 3539 * a close approximation of the MRU list at the point in time the last 3540 * response was sent by ntpd. The only difference is it may be longer, 3541 * containing some number of oldest entries which have since been 3542 * reclaimed. If necessary, the protocol could be extended to zap those 3543 * from the client snapshot at the end, but so far that doesn't seem 3544 * useful. 3545 * 3546 * To accomodate the changing MRU list, the starting point for requests 3547 * after the first request is supplied as a series of last seen 3548 * timestamps and associated addresses, the newest ones the client has 3549 * received. As long as at least one of those entries hasn't been 3550 * bumped to the head of the MRU list, ntpd can pick up at that point. 3551 * Otherwise, the request is failed and it is up to ntpq to back up and 3552 * provide the next newest entry's timestamps and addresses, conceivably 3553 * backing up all the way to the starting point. 3554 * 3555 * input parameters: 3556 * nonce= Regurgitated nonce retrieved by the client 3557 * previously using CTL_OP_REQ_NONCE, demonstrating 3558 * ability to receive traffic sent to its address. 3559 * frags= Limit on datagrams (fragments) in response. Used 3560 * by newer ntpq versions instead of limit= when 3561 * retrieving multiple entries. 3562 * limit= Limit on MRU entries returned. One of frags= or 3563 * limit= must be provided. 3564 * limit=1 is a special case: Instead of fetching 3565 * beginning with the supplied starting point's 3566 * newer neighbor, fetch the supplied entry, and 3567 * in that case the #.last timestamp can be zero. 3568 * This enables fetching a single entry by IP 3569 * address. When limit is not one and frags= is 3570 * provided, the fragment limit controls. 3571 * mincount= (decimal) Return entries with count >= mincount. 3572 * laddr= Return entries associated with the server's IP 3573 * address given. No port specification is needed, 3574 * and any supplied is ignored. 3575 * resall= 0x-prefixed hex restrict bits which must all be 3576 * lit for an MRU entry to be included. 3577 * Has precedence over any resany=. 3578 * resany= 0x-prefixed hex restrict bits, at least one of 3579 * which must be list for an MRU entry to be 3580 * included. 3581 * last.0= 0x-prefixed hex l_fp timestamp of newest entry 3582 * which client previously received. 3583 * addr.0= text of newest entry's IP address and port, 3584 * IPv6 addresses in bracketed form: [::]:123 3585 * last.1= timestamp of 2nd newest entry client has. 3586 * addr.1= address of 2nd newest entry. 3587 * [...] 3588 * 3589 * ntpq provides as many last/addr pairs as will fit in a single request 3590 * packet, except for the first request in a MRU fetch operation. 3591 * 3592 * The response begins with a new nonce value to be used for any 3593 * followup request. Following the nonce is the next newer entry than 3594 * referred to by last.0 and addr.0, if the "0" entry has not been 3595 * bumped to the front. If it has, the first entry returned will be the 3596 * next entry newer than referred to by last.1 and addr.1, and so on. 3597 * If none of the referenced entries remain unchanged, the request fails 3598 * and ntpq backs up to the next earlier set of entries to resync. 3599 * 3600 * Except for the first response, the response begins with confirmation 3601 * of the entry that precedes the first additional entry provided: 3602 * 3603 * last.older= hex l_fp timestamp matching one of the input 3604 * .last timestamps, which entry now precedes the 3605 * response 0. entry in the MRU list. 3606 * addr.older= text of address corresponding to older.last. 3607 * 3608 * And in any case, a successful response contains sets of values 3609 * comprising entries, with the oldest numbered 0 and incrementing from 3610 * there: 3611 * 3612 * addr.# text of IPv4 or IPv6 address and port 3613 * last.# hex l_fp timestamp of last receipt 3614 * first.# hex l_fp timestamp of first receipt 3615 * ct.# count of packets received 3616 * mv.# mode and version 3617 * rs.# restriction mask (RES_* bits) 3618 * 3619 * Note the code currently assumes there are no valid three letter 3620 * tags sent with each row, and needs to be adjusted if that changes. 3621 * 3622 * The client should accept the values in any order, and ignore .# 3623 * values which it does not understand, to allow a smooth path to 3624 * future changes without requiring a new opcode. Clients can rely 3625 * on all *.0 values preceding any *.1 values, that is all values for 3626 * a given index number are together in the response. 3627 * 3628 * The end of the response list is noted with one or two tag=value 3629 * pairs. Unconditionally: 3630 * 3631 * now= 0x-prefixed l_fp timestamp at the server marking 3632 * the end of the operation. 3633 * 3634 * If any entries were returned, now= is followed by: 3635 * 3636 * last.newest= hex l_fp identical to last.# of the prior 3637 * entry. 3638 */ 3639 static void read_mru_list( 3640 struct recvbuf *rbufp, 3641 int restrict_mask 3642 ) 3643 { 3644 const char nonce_text[] = "nonce"; 3645 const char frags_text[] = "frags"; 3646 const char limit_text[] = "limit"; 3647 const char mincount_text[] = "mincount"; 3648 const char resall_text[] = "resall"; 3649 const char resany_text[] = "resany"; 3650 const char maxlstint_text[] = "maxlstint"; 3651 const char laddr_text[] = "laddr"; 3652 const char resaxx_fmt[] = "0x%hx"; 3653 u_int limit; 3654 u_short frags; 3655 u_short resall; 3656 u_short resany; 3657 int mincount; 3658 u_int maxlstint; 3659 sockaddr_u laddr; 3660 struct interface * lcladr; 3661 u_int count; 3662 u_int ui; 3663 u_int uf; 3664 l_fp last[16]; 3665 sockaddr_u addr[COUNTOF(last)]; 3666 char buf[128]; 3667 struct ctl_var * in_parms; 3668 const struct ctl_var * v; 3669 char * val; 3670 const char * pch; 3671 char * pnonce; 3672 int nonce_valid; 3673 size_t i; 3674 int priors; 3675 u_short hash; 3676 mon_entry * mon; 3677 mon_entry * prior_mon; 3678 l_fp now; 3679 3680 if (RES_NOMRULIST & restrict_mask) { 3681 ctl_error(CERR_PERMISSION); 3682 NLOG(NLOG_SYSINFO) 3683 msyslog(LOG_NOTICE, 3684 "mrulist from %s rejected due to nomrulist restriction", 3685 stoa(&rbufp->recv_srcadr)); 3686 sys_restricted++; 3687 return; 3688 } 3689 /* 3690 * fill in_parms var list with all possible input parameters. 3691 */ 3692 in_parms = NULL; 3693 set_var(&in_parms, nonce_text, sizeof(nonce_text), 0); 3694 set_var(&in_parms, frags_text, sizeof(frags_text), 0); 3695 set_var(&in_parms, limit_text, sizeof(limit_text), 0); 3696 set_var(&in_parms, mincount_text, sizeof(mincount_text), 0); 3697 set_var(&in_parms, resall_text, sizeof(resall_text), 0); 3698 set_var(&in_parms, resany_text, sizeof(resany_text), 0); 3699 set_var(&in_parms, maxlstint_text, sizeof(maxlstint_text), 0); 3700 set_var(&in_parms, laddr_text, sizeof(laddr_text), 0); 3701 for (i = 0; i < COUNTOF(last); i++) { 3702 snprintf(buf, sizeof(buf), last_fmt, (int)i); 3703 set_var(&in_parms, buf, strlen(buf) + 1, 0); 3704 snprintf(buf, sizeof(buf), addr_fmt, (int)i); 3705 set_var(&in_parms, buf, strlen(buf) + 1, 0); 3706 } 3707 3708 /* decode input parms */ 3709 pnonce = NULL; 3710 frags = 0; 3711 limit = 0; 3712 mincount = 0; 3713 resall = 0; 3714 resany = 0; 3715 maxlstint = 0; 3716 lcladr = NULL; 3717 priors = 0; 3718 ZERO(last); 3719 ZERO(addr); 3720 3721 while (NULL != (v = ctl_getitem(in_parms, &val)) && 3722 !(EOV & v->flags)) { 3723 int si; 3724 3725 if (!strcmp(nonce_text, v->text)) { 3726 if (NULL != pnonce) 3727 free(pnonce); 3728 pnonce = estrdup(val); 3729 } else if (!strcmp(frags_text, v->text)) { 3730 sscanf(val, "%hu", &frags); 3731 } else if (!strcmp(limit_text, v->text)) { 3732 sscanf(val, "%u", &limit); 3733 } else if (!strcmp(mincount_text, v->text)) { 3734 if (1 != sscanf(val, "%d", &mincount) || 3735 mincount < 0) 3736 mincount = 0; 3737 } else if (!strcmp(resall_text, v->text)) { 3738 sscanf(val, resaxx_fmt, &resall); 3739 } else if (!strcmp(resany_text, v->text)) { 3740 sscanf(val, resaxx_fmt, &resany); 3741 } else if (!strcmp(maxlstint_text, v->text)) { 3742 sscanf(val, "%u", &maxlstint); 3743 } else if (!strcmp(laddr_text, v->text)) { 3744 if (decodenetnum(val, &laddr)) 3745 lcladr = getinterface(&laddr, 0); 3746 } else if (1 == sscanf(v->text, last_fmt, &si) && 3747 (size_t)si < COUNTOF(last)) { 3748 if (2 == sscanf(val, "0x%08x.%08x", &ui, &uf)) { 3749 last[si].l_ui = ui; 3750 last[si].l_uf = uf; 3751 if (!SOCK_UNSPEC(&addr[si]) && 3752 si == priors) 3753 priors++; 3754 } 3755 } else if (1 == sscanf(v->text, addr_fmt, &si) && 3756 (size_t)si < COUNTOF(addr)) { 3757 if (decodenetnum(val, &addr[si]) 3758 && last[si].l_ui && last[si].l_uf && 3759 si == priors) 3760 priors++; 3761 } 3762 } 3763 free_varlist(in_parms); 3764 in_parms = NULL; 3765 3766 /* return no responses until the nonce is validated */ 3767 if (NULL == pnonce) 3768 return; 3769 3770 nonce_valid = validate_nonce(pnonce, rbufp); 3771 free(pnonce); 3772 if (!nonce_valid) 3773 return; 3774 3775 if ((0 == frags && !(0 < limit && limit <= MRU_ROW_LIMIT)) || 3776 frags > MRU_FRAGS_LIMIT) { 3777 ctl_error(CERR_BADVALUE); 3778 return; 3779 } 3780 3781 /* 3782 * If either frags or limit is not given, use the max. 3783 */ 3784 if (0 != frags && 0 == limit) 3785 limit = UINT_MAX; 3786 else if (0 != limit && 0 == frags) 3787 frags = MRU_FRAGS_LIMIT; 3788 3789 /* 3790 * Find the starting point if one was provided. 3791 */ 3792 mon = NULL; 3793 for (i = 0; i < (size_t)priors; i++) { 3794 hash = MON_HASH(&addr[i]); 3795 for (mon = mon_hash[hash]; 3796 mon != NULL; 3797 mon = mon->hash_next) 3798 if (ADDR_PORT_EQ(&mon->rmtadr, &addr[i])) 3799 break; 3800 if (mon != NULL) { 3801 if (L_ISEQU(&mon->last, &last[i])) 3802 break; 3803 mon = NULL; 3804 } 3805 } 3806 3807 /* If a starting point was provided... */ 3808 if (priors) { 3809 /* and none could be found unmodified... */ 3810 if (NULL == mon) { 3811 /* tell ntpq to try again with older entries */ 3812 ctl_error(CERR_UNKNOWNVAR); 3813 return; 3814 } 3815 /* confirm the prior entry used as starting point */ 3816 ctl_putts("last.older", &mon->last); 3817 pch = sptoa(&mon->rmtadr); 3818 ctl_putunqstr("addr.older", pch, strlen(pch)); 3819 3820 /* 3821 * Move on to the first entry the client doesn't have, 3822 * except in the special case of a limit of one. In 3823 * that case return the starting point entry. 3824 */ 3825 if (limit > 1) 3826 mon = PREV_DLIST(mon_mru_list, mon, mru); 3827 } else { /* start with the oldest */ 3828 mon = TAIL_DLIST(mon_mru_list, mru); 3829 } 3830 3831 /* 3832 * send up to limit= entries in up to frags= datagrams 3833 */ 3834 get_systime(&now); 3835 generate_nonce(rbufp, buf, sizeof(buf)); 3836 ctl_putunqstr("nonce", buf, strlen(buf)); 3837 prior_mon = NULL; 3838 for (count = 0; 3839 mon != NULL && res_frags < frags && count < limit; 3840 mon = PREV_DLIST(mon_mru_list, mon, mru)) { 3841 3842 if (mon->count < mincount) 3843 continue; 3844 if (resall && resall != (resall & mon->flags)) 3845 continue; 3846 if (resany && !(resany & mon->flags)) 3847 continue; 3848 if (maxlstint > 0 && now.l_ui - mon->last.l_ui > 3849 maxlstint) 3850 continue; 3851 if (lcladr != NULL && mon->lcladr != lcladr) 3852 continue; 3853 3854 send_mru_entry(mon, count); 3855 if (!count) 3856 send_random_tag_value(0); 3857 count++; 3858 prior_mon = mon; 3859 } 3860 3861 /* 3862 * If this batch completes the MRU list, say so explicitly with 3863 * a now= l_fp timestamp. 3864 */ 3865 if (NULL == mon) { 3866 if (count > 1) 3867 send_random_tag_value(count - 1); 3868 ctl_putts("now", &now); 3869 /* if any entries were returned confirm the last */ 3870 if (prior_mon != NULL) 3871 ctl_putts("last.newest", &prior_mon->last); 3872 } 3873 ctl_flushpkt(0); 3874 } 3875 3876 3877 /* 3878 * Send a ifstats entry in response to a "ntpq -c ifstats" request. 3879 * 3880 * To keep clients honest about not depending on the order of values, 3881 * and thereby avoid being locked into ugly workarounds to maintain 3882 * backward compatibility later as new fields are added to the response, 3883 * the order is random. 3884 */ 3885 static void 3886 send_ifstats_entry( 3887 endpt * la, 3888 u_int ifnum 3889 ) 3890 { 3891 const char addr_fmtu[] = "addr.%u"; 3892 const char bcast_fmt[] = "bcast.%u"; 3893 const char en_fmt[] = "en.%u"; /* enabled */ 3894 const char name_fmt[] = "name.%u"; 3895 const char flags_fmt[] = "flags.%u"; 3896 const char tl_fmt[] = "tl.%u"; /* ttl */ 3897 const char mc_fmt[] = "mc.%u"; /* mcast count */ 3898 const char rx_fmt[] = "rx.%u"; 3899 const char tx_fmt[] = "tx.%u"; 3900 const char txerr_fmt[] = "txerr.%u"; 3901 const char pc_fmt[] = "pc.%u"; /* peer count */ 3902 const char up_fmt[] = "up.%u"; /* uptime */ 3903 char tag[32]; 3904 u_char sent[IFSTATS_FIELDS]; /* 12 tag=value pairs */ 3905 int noisebits; 3906 u_int32 noise; 3907 u_int which; 3908 u_int remaining; 3909 const char *pch; 3910 3911 remaining = COUNTOF(sent); 3912 ZERO(sent); 3913 noise = 0; 3914 noisebits = 0; 3915 while (remaining > 0) { 3916 if (noisebits < 4) { 3917 noise = rand() ^ (rand() << 16); 3918 noisebits = 31; 3919 } 3920 which = (noise & 0xf) % COUNTOF(sent); 3921 noise >>= 4; 3922 noisebits -= 4; 3923 3924 while (sent[which]) 3925 which = (which + 1) % COUNTOF(sent); 3926 3927 switch (which) { 3928 3929 case 0: 3930 snprintf(tag, sizeof(tag), addr_fmtu, ifnum); 3931 pch = sptoa(&la->sin); 3932 ctl_putunqstr(tag, pch, strlen(pch)); 3933 break; 3934 3935 case 1: 3936 snprintf(tag, sizeof(tag), bcast_fmt, ifnum); 3937 if (INT_BCASTOPEN & la->flags) 3938 pch = sptoa(&la->bcast); 3939 else 3940 pch = ""; 3941 ctl_putunqstr(tag, pch, strlen(pch)); 3942 break; 3943 3944 case 2: 3945 snprintf(tag, sizeof(tag), en_fmt, ifnum); 3946 ctl_putint(tag, !la->ignore_packets); 3947 break; 3948 3949 case 3: 3950 snprintf(tag, sizeof(tag), name_fmt, ifnum); 3951 ctl_putstr(tag, la->name, strlen(la->name)); 3952 break; 3953 3954 case 4: 3955 snprintf(tag, sizeof(tag), flags_fmt, ifnum); 3956 ctl_puthex(tag, (u_int)la->flags); 3957 break; 3958 3959 case 5: 3960 snprintf(tag, sizeof(tag), tl_fmt, ifnum); 3961 ctl_putint(tag, la->last_ttl); 3962 break; 3963 3964 case 6: 3965 snprintf(tag, sizeof(tag), mc_fmt, ifnum); 3966 ctl_putint(tag, la->num_mcast); 3967 break; 3968 3969 case 7: 3970 snprintf(tag, sizeof(tag), rx_fmt, ifnum); 3971 ctl_putint(tag, la->received); 3972 break; 3973 3974 case 8: 3975 snprintf(tag, sizeof(tag), tx_fmt, ifnum); 3976 ctl_putint(tag, la->sent); 3977 break; 3978 3979 case 9: 3980 snprintf(tag, sizeof(tag), txerr_fmt, ifnum); 3981 ctl_putint(tag, la->notsent); 3982 break; 3983 3984 case 10: 3985 snprintf(tag, sizeof(tag), pc_fmt, ifnum); 3986 ctl_putuint(tag, la->peercnt); 3987 break; 3988 3989 case 11: 3990 snprintf(tag, sizeof(tag), up_fmt, ifnum); 3991 ctl_putuint(tag, current_time - la->starttime); 3992 break; 3993 } 3994 sent[which] = TRUE; 3995 remaining--; 3996 } 3997 send_random_tag_value((int)ifnum); 3998 } 3999 4000 4001 /* 4002 * read_ifstats - send statistics for each local address, exposed by 4003 * ntpq -c ifstats 4004 */ 4005 static void 4006 read_ifstats( 4007 struct recvbuf * rbufp 4008 ) 4009 { 4010 u_int ifidx; 4011 endpt * la; 4012 4013 /* 4014 * loop over [0..sys_ifnum] searching ep_list for each 4015 * ifnum in turn. 4016 */ 4017 for (ifidx = 0; ifidx < sys_ifnum; ifidx++) { 4018 for (la = ep_list; la != NULL; la = la->elink) 4019 if (ifidx == la->ifnum) 4020 break; 4021 if (NULL == la) 4022 continue; 4023 /* return stats for one local address */ 4024 send_ifstats_entry(la, ifidx); 4025 } 4026 ctl_flushpkt(0); 4027 } 4028 4029 static void 4030 sockaddrs_from_restrict_u( 4031 sockaddr_u * psaA, 4032 sockaddr_u * psaM, 4033 restrict_u * pres, 4034 int ipv6 4035 ) 4036 { 4037 ZERO(*psaA); 4038 ZERO(*psaM); 4039 if (!ipv6) { 4040 psaA->sa.sa_family = AF_INET; 4041 psaA->sa4.sin_addr.s_addr = htonl(pres->u.v4.addr); 4042 psaM->sa.sa_family = AF_INET; 4043 psaM->sa4.sin_addr.s_addr = htonl(pres->u.v4.mask); 4044 } else { 4045 psaA->sa.sa_family = AF_INET6; 4046 memcpy(&psaA->sa6.sin6_addr, &pres->u.v6.addr, 4047 sizeof(psaA->sa6.sin6_addr)); 4048 psaM->sa.sa_family = AF_INET6; 4049 memcpy(&psaM->sa6.sin6_addr, &pres->u.v6.mask, 4050 sizeof(psaA->sa6.sin6_addr)); 4051 } 4052 } 4053 4054 4055 /* 4056 * Send a restrict entry in response to a "ntpq -c reslist" request. 4057 * 4058 * To keep clients honest about not depending on the order of values, 4059 * and thereby avoid being locked into ugly workarounds to maintain 4060 * backward compatibility later as new fields are added to the response, 4061 * the order is random. 4062 */ 4063 static void 4064 send_restrict_entry( 4065 restrict_u * pres, 4066 int ipv6, 4067 u_int idx 4068 ) 4069 { 4070 const char addr_fmtu[] = "addr.%u"; 4071 const char mask_fmtu[] = "mask.%u"; 4072 const char hits_fmt[] = "hits.%u"; 4073 const char flags_fmt[] = "flags.%u"; 4074 char tag[32]; 4075 u_char sent[RESLIST_FIELDS]; /* 4 tag=value pairs */ 4076 int noisebits; 4077 u_int32 noise; 4078 u_int which; 4079 u_int remaining; 4080 sockaddr_u addr; 4081 sockaddr_u mask; 4082 const char * pch; 4083 char * buf; 4084 const char * match_str; 4085 const char * access_str; 4086 4087 sockaddrs_from_restrict_u(&addr, &mask, pres, ipv6); 4088 remaining = COUNTOF(sent); 4089 ZERO(sent); 4090 noise = 0; 4091 noisebits = 0; 4092 while (remaining > 0) { 4093 if (noisebits < 2) { 4094 noise = rand() ^ (rand() << 16); 4095 noisebits = 31; 4096 } 4097 which = (noise & 0x3) % COUNTOF(sent); 4098 noise >>= 2; 4099 noisebits -= 2; 4100 4101 while (sent[which]) 4102 which = (which + 1) % COUNTOF(sent); 4103 4104 switch (which) { 4105 4106 case 0: 4107 snprintf(tag, sizeof(tag), addr_fmtu, idx); 4108 pch = stoa(&addr); 4109 ctl_putunqstr(tag, pch, strlen(pch)); 4110 break; 4111 4112 case 1: 4113 snprintf(tag, sizeof(tag), mask_fmtu, idx); 4114 pch = stoa(&mask); 4115 ctl_putunqstr(tag, pch, strlen(pch)); 4116 break; 4117 4118 case 2: 4119 snprintf(tag, sizeof(tag), hits_fmt, idx); 4120 ctl_putuint(tag, pres->count); 4121 break; 4122 4123 case 3: 4124 snprintf(tag, sizeof(tag), flags_fmt, idx); 4125 match_str = res_match_flags(pres->mflags); 4126 access_str = res_access_flags(pres->flags); 4127 if ('\0' == match_str[0]) { 4128 pch = access_str; 4129 } else { 4130 LIB_GETBUF(buf); 4131 snprintf(buf, LIB_BUFLENGTH, "%s %s", 4132 match_str, access_str); 4133 pch = buf; 4134 } 4135 ctl_putunqstr(tag, pch, strlen(pch)); 4136 break; 4137 } 4138 sent[which] = TRUE; 4139 remaining--; 4140 } 4141 send_random_tag_value((int)idx); 4142 } 4143 4144 4145 static void 4146 send_restrict_list( 4147 restrict_u * pres, 4148 int ipv6, 4149 u_int * pidx 4150 ) 4151 { 4152 for ( ; pres != NULL; pres = pres->link) { 4153 send_restrict_entry(pres, ipv6, *pidx); 4154 (*pidx)++; 4155 } 4156 } 4157 4158 4159 /* 4160 * read_addr_restrictions - returns IPv4 and IPv6 access control lists 4161 */ 4162 static void 4163 read_addr_restrictions( 4164 struct recvbuf * rbufp 4165 ) 4166 { 4167 u_int idx; 4168 4169 idx = 0; 4170 send_restrict_list(restrictlist4, FALSE, &idx); 4171 send_restrict_list(restrictlist6, TRUE, &idx); 4172 ctl_flushpkt(0); 4173 } 4174 4175 4176 /* 4177 * read_ordlist - CTL_OP_READ_ORDLIST_A for ntpq -c ifstats & reslist 4178 */ 4179 static void 4180 read_ordlist( 4181 struct recvbuf * rbufp, 4182 int restrict_mask 4183 ) 4184 { 4185 const char ifstats_s[] = "ifstats"; 4186 const size_t ifstats_chars = COUNTOF(ifstats_s) - 1; 4187 const char addr_rst_s[] = "addr_restrictions"; 4188 const size_t a_r_chars = COUNTOF(addr_rst_s) - 1; 4189 struct ntp_control * cpkt; 4190 u_short qdata_octets; 4191 4192 /* 4193 * CTL_OP_READ_ORDLIST_A was first named CTL_OP_READ_IFSTATS and 4194 * used only for ntpq -c ifstats. With the addition of reslist 4195 * the same opcode was generalized to retrieve ordered lists 4196 * which require authentication. The request data is empty or 4197 * contains "ifstats" (not null terminated) to retrieve local 4198 * addresses and associated stats. It is "addr_restrictions" 4199 * to retrieve the IPv4 then IPv6 remote address restrictions, 4200 * which are access control lists. Other request data return 4201 * CERR_UNKNOWNVAR. 4202 */ 4203 cpkt = (struct ntp_control *)&rbufp->recv_pkt; 4204 qdata_octets = ntohs(cpkt->count); 4205 if (0 == qdata_octets || (ifstats_chars == qdata_octets && 4206 !memcmp(ifstats_s, cpkt->u.data, ifstats_chars))) { 4207 read_ifstats(rbufp); 4208 return; 4209 } 4210 if (a_r_chars == qdata_octets && 4211 !memcmp(addr_rst_s, cpkt->u.data, a_r_chars)) { 4212 read_addr_restrictions(rbufp); 4213 return; 4214 } 4215 ctl_error(CERR_UNKNOWNVAR); 4216 } 4217 4218 4219 /* 4220 * req_nonce - CTL_OP_REQ_NONCE for ntpq -c mrulist prerequisite. 4221 */ 4222 static void req_nonce( 4223 struct recvbuf * rbufp, 4224 int restrict_mask 4225 ) 4226 { 4227 char buf[64]; 4228 4229 generate_nonce(rbufp, buf, sizeof(buf)); 4230 ctl_putunqstr("nonce", buf, strlen(buf)); 4231 ctl_flushpkt(0); 4232 } 4233 4234 4235 /* 4236 * read_clockstatus - return clock radio status 4237 */ 4238 /*ARGSUSED*/ 4239 static void 4240 read_clockstatus( 4241 struct recvbuf *rbufp, 4242 int restrict_mask 4243 ) 4244 { 4245 #ifndef REFCLOCK 4246 /* 4247 * If no refclock support, no data to return 4248 */ 4249 ctl_error(CERR_BADASSOC); 4250 #else 4251 const struct ctl_var * v; 4252 int i; 4253 struct peer * peer; 4254 char * valuep; 4255 u_char * wants; 4256 size_t wants_alloc; 4257 int gotvar; 4258 const u_char * cc; 4259 struct ctl_var * kv; 4260 struct refclockstat cs; 4261 4262 if (res_associd != 0) { 4263 peer = findpeerbyassoc(res_associd); 4264 } else { 4265 /* 4266 * Find a clock for this jerk. If the system peer 4267 * is a clock use it, else search peer_list for one. 4268 */ 4269 if (sys_peer != NULL && (FLAG_REFCLOCK & 4270 sys_peer->flags)) 4271 peer = sys_peer; 4272 else 4273 for (peer = peer_list; 4274 peer != NULL; 4275 peer = peer->p_link) 4276 if (FLAG_REFCLOCK & peer->flags) 4277 break; 4278 } 4279 if (NULL == peer || !(FLAG_REFCLOCK & peer->flags)) { 4280 ctl_error(CERR_BADASSOC); 4281 return; 4282 } 4283 /* 4284 * If we got here we have a peer which is a clock. Get his 4285 * status. 4286 */ 4287 cs.kv_list = NULL; 4288 refclock_control(&peer->srcadr, NULL, &cs); 4289 kv = cs.kv_list; 4290 /* 4291 * Look for variables in the packet. 4292 */ 4293 rpkt.status = htons(ctlclkstatus(&cs)); 4294 wants_alloc = CC_MAXCODE + 1 + count_var(kv); 4295 wants = emalloc_zero(wants_alloc); 4296 gotvar = FALSE; 4297 while (NULL != (v = ctl_getitem(clock_var, &valuep))) { 4298 if (!(EOV & v->flags)) { 4299 wants[v->code] = TRUE; 4300 gotvar = TRUE; 4301 } else { 4302 v = ctl_getitem(kv, &valuep); 4303 NTP_INSIST(NULL != v); 4304 if (EOV & v->flags) { 4305 ctl_error(CERR_UNKNOWNVAR); 4306 free(wants); 4307 free_varlist(cs.kv_list); 4308 return; 4309 } 4310 wants[CC_MAXCODE + 1 + v->code] = TRUE; 4311 gotvar = TRUE; 4312 } 4313 } 4314 4315 if (gotvar) { 4316 for (i = 1; i <= CC_MAXCODE; i++) 4317 if (wants[i]) 4318 ctl_putclock(i, &cs, TRUE); 4319 if (kv != NULL) 4320 for (i = 0; !(EOV & kv[i].flags); i++) 4321 if (wants[i + CC_MAXCODE + 1]) 4322 ctl_putdata(kv[i].text, 4323 strlen(kv[i].text), 4324 FALSE); 4325 } else { 4326 for (cc = def_clock_var; *cc != 0; cc++) 4327 ctl_putclock((int)*cc, &cs, FALSE); 4328 for ( ; kv != NULL && !(EOV & kv->flags); kv++) 4329 if (DEF & kv->flags) 4330 ctl_putdata(kv->text, strlen(kv->text), 4331 FALSE); 4332 } 4333 4334 free(wants); 4335 free_varlist(cs.kv_list); 4336 4337 ctl_flushpkt(0); 4338 #endif 4339 } 4340 4341 4342 /* 4343 * write_clockstatus - we don't do this 4344 */ 4345 /*ARGSUSED*/ 4346 static void 4347 write_clockstatus( 4348 struct recvbuf *rbufp, 4349 int restrict_mask 4350 ) 4351 { 4352 ctl_error(CERR_PERMISSION); 4353 } 4354 4355 /* 4356 * Trap support from here on down. We send async trap messages when the 4357 * upper levels report trouble. Traps can by set either by control 4358 * messages or by configuration. 4359 */ 4360 /* 4361 * set_trap - set a trap in response to a control message 4362 */ 4363 static void 4364 set_trap( 4365 struct recvbuf *rbufp, 4366 int restrict_mask 4367 ) 4368 { 4369 int traptype; 4370 4371 /* 4372 * See if this guy is allowed 4373 */ 4374 if (restrict_mask & RES_NOTRAP) { 4375 ctl_error(CERR_PERMISSION); 4376 return; 4377 } 4378 4379 /* 4380 * Determine his allowed trap type. 4381 */ 4382 traptype = TRAP_TYPE_PRIO; 4383 if (restrict_mask & RES_LPTRAP) 4384 traptype = TRAP_TYPE_NONPRIO; 4385 4386 /* 4387 * Call ctlsettrap() to do the work. Return 4388 * an error if it can't assign the trap. 4389 */ 4390 if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype, 4391 (int)res_version)) 4392 ctl_error(CERR_NORESOURCE); 4393 ctl_flushpkt(0); 4394 } 4395 4396 4397 /* 4398 * unset_trap - unset a trap in response to a control message 4399 */ 4400 static void 4401 unset_trap( 4402 struct recvbuf *rbufp, 4403 int restrict_mask 4404 ) 4405 { 4406 int traptype; 4407 4408 /* 4409 * We don't prevent anyone from removing his own trap unless the 4410 * trap is configured. Note we also must be aware of the 4411 * possibility that restriction flags were changed since this 4412 * guy last set his trap. Set the trap type based on this. 4413 */ 4414 traptype = TRAP_TYPE_PRIO; 4415 if (restrict_mask & RES_LPTRAP) 4416 traptype = TRAP_TYPE_NONPRIO; 4417 4418 /* 4419 * Call ctlclrtrap() to clear this out. 4420 */ 4421 if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype)) 4422 ctl_error(CERR_BADASSOC); 4423 ctl_flushpkt(0); 4424 } 4425 4426 4427 /* 4428 * ctlsettrap - called to set a trap 4429 */ 4430 int 4431 ctlsettrap( 4432 sockaddr_u *raddr, 4433 struct interface *linter, 4434 int traptype, 4435 int version 4436 ) 4437 { 4438 size_t n; 4439 struct ctl_trap *tp; 4440 struct ctl_trap *tptouse; 4441 4442 /* 4443 * See if we can find this trap. If so, we only need update 4444 * the flags and the time. 4445 */ 4446 if ((tp = ctlfindtrap(raddr, linter)) != NULL) { 4447 switch (traptype) { 4448 4449 case TRAP_TYPE_CONFIG: 4450 tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED; 4451 break; 4452 4453 case TRAP_TYPE_PRIO: 4454 if (tp->tr_flags & TRAP_CONFIGURED) 4455 return (1); /* don't change anything */ 4456 tp->tr_flags = TRAP_INUSE; 4457 break; 4458 4459 case TRAP_TYPE_NONPRIO: 4460 if (tp->tr_flags & TRAP_CONFIGURED) 4461 return (1); /* don't change anything */ 4462 tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO; 4463 break; 4464 } 4465 tp->tr_settime = current_time; 4466 tp->tr_resets++; 4467 return (1); 4468 } 4469 4470 /* 4471 * First we heard of this guy. Try to find a trap structure 4472 * for him to use, clearing out lesser priority guys if we 4473 * have to. Clear out anyone who's expired while we're at it. 4474 */ 4475 tptouse = NULL; 4476 for (n = 0; n < COUNTOF(ctl_traps); n++) { 4477 tp = &ctl_traps[n]; 4478 if ((TRAP_INUSE & tp->tr_flags) && 4479 !(TRAP_CONFIGURED & tp->tr_flags) && 4480 ((tp->tr_settime + CTL_TRAPTIME) > current_time)) { 4481 tp->tr_flags = 0; 4482 num_ctl_traps--; 4483 } 4484 if (!(TRAP_INUSE & tp->tr_flags)) { 4485 tptouse = tp; 4486 } else if (!(TRAP_CONFIGURED & tp->tr_flags)) { 4487 switch (traptype) { 4488 4489 case TRAP_TYPE_CONFIG: 4490 if (tptouse == NULL) { 4491 tptouse = tp; 4492 break; 4493 } 4494 if ((TRAP_NONPRIO & tptouse->tr_flags) && 4495 !(TRAP_NONPRIO & tp->tr_flags)) 4496 break; 4497 4498 if (!(TRAP_NONPRIO & tptouse->tr_flags) 4499 && (TRAP_NONPRIO & tp->tr_flags)) { 4500 tptouse = tp; 4501 break; 4502 } 4503 if (tptouse->tr_origtime < 4504 tp->tr_origtime) 4505 tptouse = tp; 4506 break; 4507 4508 case TRAP_TYPE_PRIO: 4509 if ( TRAP_NONPRIO & tp->tr_flags) { 4510 if (tptouse == NULL || 4511 ((TRAP_INUSE & 4512 tptouse->tr_flags) && 4513 tptouse->tr_origtime < 4514 tp->tr_origtime)) 4515 tptouse = tp; 4516 } 4517 break; 4518 4519 case TRAP_TYPE_NONPRIO: 4520 break; 4521 } 4522 } 4523 } 4524 4525 /* 4526 * If we don't have room for him return an error. 4527 */ 4528 if (tptouse == NULL) 4529 return (0); 4530 4531 /* 4532 * Set up this structure for him. 4533 */ 4534 tptouse->tr_settime = tptouse->tr_origtime = current_time; 4535 tptouse->tr_count = tptouse->tr_resets = 0; 4536 tptouse->tr_sequence = 1; 4537 tptouse->tr_addr = *raddr; 4538 tptouse->tr_localaddr = linter; 4539 tptouse->tr_version = (u_char) version; 4540 tptouse->tr_flags = TRAP_INUSE; 4541 if (traptype == TRAP_TYPE_CONFIG) 4542 tptouse->tr_flags |= TRAP_CONFIGURED; 4543 else if (traptype == TRAP_TYPE_NONPRIO) 4544 tptouse->tr_flags |= TRAP_NONPRIO; 4545 num_ctl_traps++; 4546 return (1); 4547 } 4548 4549 4550 /* 4551 * ctlclrtrap - called to clear a trap 4552 */ 4553 int 4554 ctlclrtrap( 4555 sockaddr_u *raddr, 4556 struct interface *linter, 4557 int traptype 4558 ) 4559 { 4560 register struct ctl_trap *tp; 4561 4562 if ((tp = ctlfindtrap(raddr, linter)) == NULL) 4563 return (0); 4564 4565 if (tp->tr_flags & TRAP_CONFIGURED 4566 && traptype != TRAP_TYPE_CONFIG) 4567 return (0); 4568 4569 tp->tr_flags = 0; 4570 num_ctl_traps--; 4571 return (1); 4572 } 4573 4574 4575 /* 4576 * ctlfindtrap - find a trap given the remote and local addresses 4577 */ 4578 static struct ctl_trap * 4579 ctlfindtrap( 4580 sockaddr_u *raddr, 4581 struct interface *linter 4582 ) 4583 { 4584 size_t n; 4585 4586 for (n = 0; n < COUNTOF(ctl_traps); n++) 4587 if ((ctl_traps[n].tr_flags & TRAP_INUSE) 4588 && ADDR_PORT_EQ(raddr, &ctl_traps[n].tr_addr) 4589 && (linter == ctl_traps[n].tr_localaddr)) 4590 return &ctl_traps[n]; 4591 4592 return NULL; 4593 } 4594 4595 4596 /* 4597 * report_event - report an event to the trappers 4598 */ 4599 void 4600 report_event( 4601 int err, /* error code */ 4602 struct peer *peer, /* peer structure pointer */ 4603 const char *str /* protostats string */ 4604 ) 4605 { 4606 char statstr[NTP_MAXSTRLEN]; 4607 int i; 4608 size_t len; 4609 4610 /* 4611 * Report the error to the protostats file, system log and 4612 * trappers. 4613 */ 4614 if (peer == NULL) { 4615 4616 /* 4617 * Discard a system report if the number of reports of 4618 * the same type exceeds the maximum. 4619 */ 4620 if (ctl_sys_last_event != (u_char)err) 4621 ctl_sys_num_events= 0; 4622 if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS) 4623 return; 4624 4625 ctl_sys_last_event = (u_char)err; 4626 ctl_sys_num_events++; 4627 snprintf(statstr, sizeof(statstr), 4628 "0.0.0.0 %04x %02x %s", 4629 ctlsysstatus(), err, eventstr(err)); 4630 if (str != NULL) { 4631 len = strlen(statstr); 4632 snprintf(statstr + len, sizeof(statstr) - len, 4633 " %s", str); 4634 } 4635 NLOG(NLOG_SYSEVENT) 4636 msyslog(LOG_INFO, "%s", statstr); 4637 } else { 4638 4639 /* 4640 * Discard a peer report if the number of reports of 4641 * the same type exceeds the maximum for that peer. 4642 */ 4643 const char * src; 4644 u_char errlast; 4645 4646 errlast = (u_char)err & ~PEER_EVENT; 4647 if (peer->last_event == errlast) 4648 peer->num_events = 0; 4649 if (peer->num_events >= CTL_PEER_MAXEVENTS) 4650 return; 4651 4652 peer->last_event = errlast; 4653 peer->num_events++; 4654 if (ISREFCLOCKADR(&peer->srcadr)) 4655 src = refnumtoa(&peer->srcadr); 4656 else 4657 src = stoa(&peer->srcadr); 4658 4659 snprintf(statstr, sizeof(statstr), 4660 "%s %04x %02x %s", src, 4661 ctlpeerstatus(peer), err, eventstr(err)); 4662 if (str != NULL) { 4663 len = strlen(statstr); 4664 snprintf(statstr + len, sizeof(statstr) - len, 4665 " %s", str); 4666 } 4667 NLOG(NLOG_PEEREVENT) 4668 msyslog(LOG_INFO, "%s", statstr); 4669 } 4670 record_proto_stats(statstr); 4671 #if DEBUG 4672 if (debug) 4673 printf("event at %lu %s\n", current_time, statstr); 4674 #endif 4675 4676 /* 4677 * If no trappers, return. 4678 */ 4679 if (num_ctl_traps <= 0) 4680 return; 4681 4682 /* 4683 * Set up the outgoing packet variables 4684 */ 4685 res_opcode = CTL_OP_ASYNCMSG; 4686 res_offset = 0; 4687 res_async = TRUE; 4688 res_authenticate = FALSE; 4689 datapt = rpkt.u.data; 4690 dataend = &rpkt.u.data[CTL_MAX_DATA_LEN]; 4691 if (!(err & PEER_EVENT)) { 4692 rpkt.associd = 0; 4693 rpkt.status = htons(ctlsysstatus()); 4694 4695 /* Include the core system variables and the list. */ 4696 for (i = 1; i <= CS_VARLIST; i++) 4697 ctl_putsys(i); 4698 } else { 4699 NTP_INSIST(peer != NULL); 4700 rpkt.associd = htons(peer->associd); 4701 rpkt.status = htons(ctlpeerstatus(peer)); 4702 4703 /* Dump it all. Later, maybe less. */ 4704 for (i = 1; i <= CP_MAX_NOAUTOKEY; i++) 4705 ctl_putpeer(i, peer); 4706 #ifdef REFCLOCK 4707 /* 4708 * for clock exception events: add clock variables to 4709 * reflect info on exception 4710 */ 4711 if (err == PEVNT_CLOCK) { 4712 struct refclockstat cs; 4713 struct ctl_var *kv; 4714 4715 cs.kv_list = NULL; 4716 refclock_control(&peer->srcadr, NULL, &cs); 4717 4718 ctl_puthex("refclockstatus", 4719 ctlclkstatus(&cs)); 4720 4721 for (i = 1; i <= CC_MAXCODE; i++) 4722 ctl_putclock(i, &cs, FALSE); 4723 for (kv = cs.kv_list; 4724 kv != NULL && !(EOV & kv->flags); 4725 kv++) 4726 if (DEF & kv->flags) 4727 ctl_putdata(kv->text, 4728 strlen(kv->text), 4729 FALSE); 4730 free_varlist(cs.kv_list); 4731 } 4732 #endif /* REFCLOCK */ 4733 } 4734 4735 /* 4736 * We're done, return. 4737 */ 4738 ctl_flushpkt(0); 4739 } 4740 4741 4742 /* 4743 * mprintf_event - printf-style varargs variant of report_event() 4744 */ 4745 int 4746 mprintf_event( 4747 int evcode, /* event code */ 4748 struct peer * p, /* may be NULL */ 4749 const char * fmt, /* msnprintf format */ 4750 ... 4751 ) 4752 { 4753 va_list ap; 4754 int rc; 4755 char msg[512]; 4756 4757 va_start(ap, fmt); 4758 rc = mvsnprintf(msg, sizeof(msg), fmt, ap); 4759 va_end(ap); 4760 report_event(evcode, p, msg); 4761 4762 return rc; 4763 } 4764 4765 4766 /* 4767 * ctl_clr_stats - clear stat counters 4768 */ 4769 void 4770 ctl_clr_stats(void) 4771 { 4772 ctltimereset = current_time; 4773 numctlreq = 0; 4774 numctlbadpkts = 0; 4775 numctlresponses = 0; 4776 numctlfrags = 0; 4777 numctlerrors = 0; 4778 numctlfrags = 0; 4779 numctltooshort = 0; 4780 numctlinputresp = 0; 4781 numctlinputfrag = 0; 4782 numctlinputerr = 0; 4783 numctlbadoffset = 0; 4784 numctlbadversion = 0; 4785 numctldatatooshort = 0; 4786 numctlbadop = 0; 4787 numasyncmsgs = 0; 4788 } 4789 4790 static u_short 4791 count_var( 4792 const struct ctl_var *k 4793 ) 4794 { 4795 u_int c; 4796 4797 if (NULL == k) 4798 return 0; 4799 4800 c = 0; 4801 while (!(EOV & (k++)->flags)) 4802 c++; 4803 4804 NTP_ENSURE(c <= USHRT_MAX); 4805 return (u_short)c; 4806 } 4807 4808 4809 char * 4810 add_var( 4811 struct ctl_var **kv, 4812 u_long size, 4813 u_short def 4814 ) 4815 { 4816 u_short c; 4817 struct ctl_var *k; 4818 char * buf; 4819 4820 c = count_var(*kv); 4821 *kv = erealloc(*kv, (c + 2) * sizeof(**kv)); 4822 k = *kv; 4823 buf = emalloc(size); 4824 k[c].code = c; 4825 k[c].text = buf; 4826 k[c].flags = def; 4827 k[c + 1].code = 0; 4828 k[c + 1].text = NULL; 4829 k[c + 1].flags = EOV; 4830 4831 return buf; 4832 } 4833 4834 4835 void 4836 set_var( 4837 struct ctl_var **kv, 4838 const char *data, 4839 u_long size, 4840 u_short def 4841 ) 4842 { 4843 struct ctl_var *k; 4844 const char *s; 4845 const char *t; 4846 char *td; 4847 4848 if (NULL == data || !size) 4849 return; 4850 4851 k = *kv; 4852 if (k != NULL) { 4853 while (!(EOV & k->flags)) { 4854 if (NULL == k->text) { 4855 td = emalloc(size); 4856 memcpy(td, data, size); 4857 k->text = td; 4858 k->flags = def; 4859 return; 4860 } else { 4861 s = data; 4862 t = k->text; 4863 while (*t != '=' && *s == *t) { 4864 s++; 4865 t++; 4866 } 4867 if (*s == *t && ((*t == '=') || !*t)) { 4868 td = erealloc((void *)(intptr_t)k->text, size); 4869 memcpy(td, data, size); 4870 k->text = td; 4871 k->flags = def; 4872 return; 4873 } 4874 } 4875 k++; 4876 } 4877 } 4878 td = add_var(kv, size, def); 4879 memcpy(td, data, size); 4880 } 4881 4882 4883 void 4884 set_sys_var( 4885 const char *data, 4886 u_long size, 4887 u_short def 4888 ) 4889 { 4890 set_var(&ext_sys_var, data, size, def); 4891 } 4892 4893 4894 /* 4895 * get_ext_sys_var() retrieves the value of a user-defined variable or 4896 * NULL if the variable has not been setvar'd. 4897 */ 4898 const char * 4899 get_ext_sys_var(const char *tag) 4900 { 4901 struct ctl_var * v; 4902 size_t c; 4903 const char * val; 4904 4905 val = NULL; 4906 c = strlen(tag); 4907 for (v = ext_sys_var; !(EOV & v->flags); v++) { 4908 if (NULL != v->text && !memcmp(tag, v->text, c)) { 4909 if ('=' == v->text[c]) { 4910 val = v->text + c + 1; 4911 break; 4912 } else if ('\0' == v->text[c]) { 4913 val = ""; 4914 break; 4915 } 4916 } 4917 } 4918 4919 return val; 4920 } 4921 4922 4923 void 4924 free_varlist( 4925 struct ctl_var *kv 4926 ) 4927 { 4928 struct ctl_var *k; 4929 if (kv) { 4930 for (k = kv; !(k->flags & EOV); k++) 4931 free((void *)(intptr_t)k->text); 4932 free((void *)kv); 4933 } 4934 } 4935