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