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