1 /* $NetBSD: ntp_control.c,v 1.4 2011/08/16 05:15:21 christos Exp $ */ 2 3 /* 4 * ntp_control.c - respond to control messages and send async traps 5 */ 6 7 #ifdef HAVE_CONFIG_H 8 # include <config.h> 9 #endif 10 11 #include "ntpd.h" 12 #include "ntp_io.h" 13 #include "ntp_refclock.h" 14 #include "ntp_control.h" 15 #include "ntp_unixtime.h" 16 #include "ntp_stdlib.h" 17 #include "ntp_config.h" 18 #include "ntp_assert.h" 19 20 #include <stdio.h> 21 #include <ctype.h> 22 #include <signal.h> 23 #include <sys/stat.h> 24 25 #ifdef HAVE_NETINET_IN_H 26 #include <netinet/in.h> 27 #endif 28 #include <arpa/inet.h> 29 30 /* 31 * Structure to hold request procedure information 32 */ 33 34 struct ctl_proc { 35 short control_code; /* defined request code */ 36 #define NO_REQUEST (-1) 37 u_short flags; /* flags word */ 38 /* Only one flag. Authentication required or not. */ 39 #define NOAUTH 0 40 #define AUTH 1 41 void (*handler) (struct recvbuf *, int); /* handle request */ 42 }; 43 44 45 /* 46 * Request processing routines 47 */ 48 static void ctl_error (int); 49 #ifdef REFCLOCK 50 static u_short ctlclkstatus (struct refclockstat *); 51 #endif 52 static void ctl_flushpkt (int); 53 static void ctl_putdata (const char *, unsigned int, int); 54 static void ctl_putstr (const char *, const char *, 55 unsigned int); 56 static void ctl_putdbl (const char *, double); 57 static void ctl_putuint (const char *, u_long); 58 static void ctl_puthex (const char *, u_long); 59 static void ctl_putint (const char *, long); 60 static void ctl_putts (const char *, l_fp *); 61 static void ctl_putadr (const char *, u_int32, 62 sockaddr_u *); 63 static void ctl_putid (const char *, char *); 64 static void ctl_putarray (const char *, double *, int); 65 static void ctl_putsys (int); 66 static void ctl_putpeer (int, struct peer *); 67 static void ctl_putfs (const char *, tstamp_t); 68 #ifdef REFCLOCK 69 static void ctl_putclock (int, struct refclockstat *, int); 70 #endif /* REFCLOCK */ 71 static struct ctl_var *ctl_getitem (struct ctl_var *, char **); 72 static u_long count_var (struct ctl_var *); 73 static void control_unspec (struct recvbuf *, int); 74 static void read_status (struct recvbuf *, int); 75 static void read_variables (struct recvbuf *, int); 76 static void write_variables (struct recvbuf *, int); 77 static void read_clock_status (struct recvbuf *, int); 78 static void write_clock_status (struct recvbuf *, int); 79 static void set_trap (struct recvbuf *, int); 80 static void unset_trap (struct recvbuf *, int); 81 static void configure (struct recvbuf *, int); 82 static void save_config (struct recvbuf *, int); 83 static struct ctl_trap *ctlfindtrap (sockaddr_u *, 84 struct interface *); 85 86 static struct ctl_proc control_codes[] = { 87 { CTL_OP_UNSPEC, NOAUTH, control_unspec }, 88 { CTL_OP_READSTAT, NOAUTH, read_status }, 89 { CTL_OP_READVAR, NOAUTH, read_variables }, 90 { CTL_OP_WRITEVAR, AUTH, write_variables }, 91 { CTL_OP_READCLOCK, NOAUTH, read_clock_status }, 92 { CTL_OP_WRITECLOCK, NOAUTH, write_clock_status }, 93 { CTL_OP_SETTRAP, NOAUTH, set_trap }, 94 { CTL_OP_UNSETTRAP, NOAUTH, unset_trap }, 95 { CTL_OP_SAVECONFIG, AUTH, save_config }, 96 { CTL_OP_CONFIGURE, AUTH, configure }, 97 { NO_REQUEST, 0, NULL } 98 }; 99 100 /* 101 * System variable values. The array can be indexed by the variable 102 * index to find the textual name. 103 */ 104 static struct ctl_var sys_var[] = { 105 { 0, PADDING, "" }, /* 0 */ 106 { CS_LEAP, RW, "leap" }, /* 1 */ 107 { CS_STRATUM, RO, "stratum" }, /* 2 */ 108 { CS_PRECISION, RO, "precision" }, /* 3 */ 109 { CS_ROOTDELAY, RO, "rootdelay" }, /* 4 */ 110 { CS_ROOTDISPERSION, RO, "rootdisp" }, /* 5 */ 111 { CS_REFID, RO, "refid" }, /* 6 */ 112 { CS_REFTIME, RO, "reftime" }, /* 7 */ 113 { CS_POLL, RO, "tc" }, /* 8 */ 114 { CS_PEERID, RO, "peer" }, /* 9 */ 115 { CS_OFFSET, RO, "offset" }, /* 10 */ 116 { CS_DRIFT, RO, "frequency" }, /* 11 */ 117 { CS_JITTER, RO, "sys_jitter" }, /* 12 */ 118 { CS_ERROR, RO, "clk_jitter" }, /* 13 */ 119 { CS_CLOCK, RO, "clock" }, /* 14 */ 120 { CS_PROCESSOR, RO, "processor" }, /* 15 */ 121 { CS_SYSTEM, RO, "system" }, /* 16 */ 122 { CS_VERSION, RO, "version" }, /* 17 */ 123 { CS_STABIL, RO, "clk_wander" }, /* 18 */ 124 { CS_VARLIST, RO, "sys_var_list" }, /* 19 */ 125 { CS_TAI, RO, "tai" }, /* 20 */ 126 { CS_LEAPTAB, RO, "leapsec" }, /* 21 */ 127 { CS_LEAPEND, RO, "expire" }, /* 22 */ 128 { CS_RATE, RO, "mintc" }, /* 23 */ 129 #ifdef OPENSSL 130 { CS_FLAGS, RO, "flags" }, /* 24 */ 131 { CS_HOST, RO, "host" }, /* 25 */ 132 { CS_PUBLIC, RO, "update" }, /* 26 */ 133 { CS_CERTIF, RO, "cert" }, /* 27 */ 134 { CS_SIGNATURE, RO, "signature" }, /* 28 */ 135 { CS_REVTIME, RO, "until" }, /* 29 */ 136 { CS_GROUP, RO, "group" }, /* 30 */ 137 { CS_DIGEST, RO, "digest" }, /* 31 */ 138 #endif /* OPENSSL */ 139 { 0, EOV, "" } /* 24/3 2*/ 140 }; 141 142 static struct ctl_var *ext_sys_var = (struct ctl_var *)0; 143 144 /* 145 * System variables we print by default (in fuzzball order, 146 * more-or-less) 147 */ 148 static u_char def_sys_var[] = { 149 CS_VERSION, 150 CS_PROCESSOR, 151 CS_SYSTEM, 152 CS_LEAP, 153 CS_STRATUM, 154 CS_PRECISION, 155 CS_ROOTDELAY, 156 CS_ROOTDISPERSION, 157 CS_REFID, 158 CS_REFTIME, 159 CS_CLOCK, 160 CS_PEERID, 161 CS_POLL, 162 CS_RATE, 163 CS_OFFSET, 164 CS_DRIFT, 165 CS_JITTER, 166 CS_ERROR, 167 CS_STABIL, 168 CS_TAI, 169 CS_LEAPTAB, 170 CS_LEAPEND, 171 #ifdef OPENSSL 172 CS_HOST, 173 CS_GROUP, 174 CS_FLAGS, 175 CS_DIGEST, 176 CS_SIGNATURE, 177 CS_PUBLIC, 178 CS_CERTIF, 179 #endif /* OPENSSL */ 180 0 181 }; 182 183 184 /* 185 * Peer variable list 186 */ 187 static struct ctl_var peer_var[] = { 188 { 0, PADDING, "" }, /* 0 */ 189 { CP_CONFIG, RO, "config" }, /* 1 */ 190 { CP_AUTHENABLE, RO, "authenable" }, /* 2 */ 191 { CP_AUTHENTIC, RO, "authentic" }, /* 3 */ 192 { CP_SRCADR, RO, "srcadr" }, /* 4 */ 193 { CP_SRCPORT, RO, "srcport" }, /* 5 */ 194 { CP_DSTADR, RO, "dstadr" }, /* 6 */ 195 { CP_DSTPORT, RO, "dstport" }, /* 7 */ 196 { CP_LEAP, RO, "leap" }, /* 8 */ 197 { CP_HMODE, RO, "hmode" }, /* 9 */ 198 { CP_STRATUM, RO, "stratum" }, /* 10 */ 199 { CP_PPOLL, RO, "ppoll" }, /* 11 */ 200 { CP_HPOLL, RO, "hpoll" }, /* 12 */ 201 { CP_PRECISION, RO, "precision" }, /* 13 */ 202 { CP_ROOTDELAY, RO, "rootdelay" }, /* 14 */ 203 { CP_ROOTDISPERSION, RO, "rootdisp" }, /* 15 */ 204 { CP_REFID, RO, "refid" }, /* 16 */ 205 { CP_REFTIME, RO, "reftime" }, /* 17 */ 206 { CP_ORG, RO, "org" }, /* 18 */ 207 { CP_REC, RO, "rec" }, /* 19 */ 208 { CP_XMT, RO, "xleave" }, /* 20 */ 209 { CP_REACH, RO, "reach" }, /* 21 */ 210 { CP_UNREACH, RO, "unreach" }, /* 22 */ 211 { CP_TIMER, RO, "timer" }, /* 23 */ 212 { CP_DELAY, RO, "delay" }, /* 24 */ 213 { CP_OFFSET, RO, "offset" }, /* 25 */ 214 { CP_JITTER, RO, "jitter" }, /* 26 */ 215 { CP_DISPERSION, RO, "dispersion" }, /* 27 */ 216 { CP_KEYID, RO, "keyid" }, /* 28 */ 217 { CP_FILTDELAY, RO, "filtdelay=" }, /* 29 */ 218 { CP_FILTOFFSET, RO, "filtoffset=" }, /* 30 */ 219 { CP_PMODE, RO, "pmode" }, /* 31 */ 220 { CP_RECEIVED, RO, "received"}, /* 32 */ 221 { CP_SENT, RO, "sent" }, /* 33 */ 222 { CP_FILTERROR, RO, "filtdisp=" }, /* 34 */ 223 { CP_FLASH, RO, "flash" }, /* 35 */ 224 { CP_TTL, RO, "ttl" }, /* 36 */ 225 { CP_VARLIST, RO, "peer_var_list" }, /* 37 */ 226 { CP_IN, RO, "in" }, /* 38 */ 227 { CP_OUT, RO, "out" }, /* 39 */ 228 { CP_RATE, RO, "headway" }, /* 40 */ 229 { CP_BIAS, RO, "bias" }, /* 41 */ 230 #ifdef OPENSSL 231 { CP_FLAGS, RO, "flags" }, /* 42 */ 232 { CP_HOST, RO, "host" }, /* 43 */ 233 { CP_VALID, RO, "valid" }, /* 44 */ 234 { CP_INITSEQ, RO, "initsequence" }, /* 45 */ 235 { CP_INITKEY, RO, "initkey" }, /* 46 */ 236 { CP_INITTSP, RO, "timestamp" }, /* 47 */ 237 { CP_SIGNATURE, RO, "signature" }, /* 48 */ 238 #endif /* OPENSSL */ 239 { 0, EOV, "" } /* 42/49 */ 240 }; 241 242 243 /* 244 * Peer variables we print by default 245 */ 246 static u_char def_peer_var[] = { 247 CP_SRCADR, 248 CP_SRCPORT, 249 CP_DSTADR, 250 CP_DSTPORT, 251 CP_OUT, 252 CP_IN, 253 CP_LEAP, 254 CP_STRATUM, 255 CP_PRECISION, 256 CP_ROOTDELAY, 257 CP_ROOTDISPERSION, 258 CP_REFID, 259 CP_REFTIME, 260 CP_REC, 261 CP_REACH, 262 CP_UNREACH, 263 CP_HMODE, 264 CP_PMODE, 265 CP_HPOLL, 266 CP_PPOLL, 267 CP_RATE, 268 CP_FLASH, 269 CP_KEYID, 270 CP_TTL, 271 CP_OFFSET, 272 CP_DELAY, 273 CP_DISPERSION, 274 CP_JITTER, 275 CP_XMT, 276 CP_BIAS, 277 CP_FILTDELAY, 278 CP_FILTOFFSET, 279 CP_FILTERROR, 280 #ifdef OPENSSL 281 CP_HOST, 282 CP_FLAGS, 283 CP_SIGNATURE, 284 CP_VALID, 285 CP_INITSEQ, 286 #endif /* OPENSSL */ 287 0 288 }; 289 290 291 #ifdef REFCLOCK 292 /* 293 * Clock variable list 294 */ 295 static struct ctl_var clock_var[] = { 296 { 0, PADDING, "" }, /* 0 */ 297 { CC_TYPE, RO, "type" }, /* 1 */ 298 { CC_TIMECODE, RO, "timecode" }, /* 2 */ 299 { CC_POLL, RO, "poll" }, /* 3 */ 300 { CC_NOREPLY, RO, "noreply" }, /* 4 */ 301 { CC_BADFORMAT, RO, "badformat" }, /* 5 */ 302 { CC_BADDATA, RO, "baddata" }, /* 6 */ 303 { CC_FUDGETIME1, RO, "fudgetime1" }, /* 7 */ 304 { CC_FUDGETIME2, RO, "fudgetime2" }, /* 8 */ 305 { CC_FUDGEVAL1, RO, "stratum" }, /* 9 */ 306 { CC_FUDGEVAL2, RO, "refid" }, /* 10 */ 307 { CC_FLAGS, RO, "flags" }, /* 11 */ 308 { CC_DEVICE, RO, "device" }, /* 12 */ 309 { CC_VARLIST, RO, "clock_var_list" }, /* 13 */ 310 { 0, EOV, "" } /* 14 */ 311 }; 312 313 314 /* 315 * Clock variables printed by default 316 */ 317 static u_char def_clock_var[] = { 318 CC_DEVICE, 319 CC_TYPE, /* won't be output if device = known */ 320 CC_TIMECODE, 321 CC_POLL, 322 CC_NOREPLY, 323 CC_BADFORMAT, 324 CC_BADDATA, 325 CC_FUDGETIME1, 326 CC_FUDGETIME2, 327 CC_FUDGEVAL1, 328 CC_FUDGEVAL2, 329 CC_FLAGS, 330 0 331 }; 332 #endif 333 334 335 /* 336 * System and processor definitions. 337 */ 338 #ifndef HAVE_UNAME 339 # ifndef STR_SYSTEM 340 # define STR_SYSTEM "UNIX" 341 # endif 342 # ifndef STR_PROCESSOR 343 # define STR_PROCESSOR "unknown" 344 # endif 345 346 static char str_system[] = STR_SYSTEM; 347 static char str_processor[] = STR_PROCESSOR; 348 #else 349 # include <sys/utsname.h> 350 static struct utsname utsnamebuf; 351 #endif /* HAVE_UNAME */ 352 353 /* 354 * Trap structures. We only allow a few of these, and send a copy of 355 * each async message to each live one. Traps time out after an hour, it 356 * is up to the trap receipient to keep resetting it to avoid being 357 * timed out. 358 */ 359 /* ntp_request.c */ 360 struct ctl_trap ctl_trap[CTL_MAXTRAPS]; 361 int num_ctl_traps; 362 363 /* 364 * Type bits, for ctlsettrap() call. 365 */ 366 #define TRAP_TYPE_CONFIG 0 /* used by configuration code */ 367 #define TRAP_TYPE_PRIO 1 /* priority trap */ 368 #define TRAP_TYPE_NONPRIO 2 /* nonpriority trap */ 369 370 371 /* 372 * List relating reference clock types to control message time sources. 373 * Index by the reference clock type. This list will only be used iff 374 * the reference clock driver doesn't set peer->sstclktype to something 375 * different than CTL_SST_TS_UNSPEC. 376 */ 377 static u_char clocktypes[] = { 378 CTL_SST_TS_NTP, /* REFCLK_NONE (0) */ 379 CTL_SST_TS_LOCAL, /* REFCLK_LOCALCLOCK (1) */ 380 CTL_SST_TS_UHF, /* deprecated REFCLK_GPS_TRAK (2) */ 381 CTL_SST_TS_HF, /* REFCLK_WWV_PST (3) */ 382 CTL_SST_TS_LF, /* REFCLK_WWVB_SPECTRACOM (4) */ 383 CTL_SST_TS_UHF, /* REFCLK_TRUETIME (5) */ 384 CTL_SST_TS_UHF, /* REFCLK_GOES_TRAK (6) IRIG_AUDIO? */ 385 CTL_SST_TS_HF, /* REFCLK_CHU (7) */ 386 CTL_SST_TS_LF, /* REFCLOCK_PARSE (default) (8) */ 387 CTL_SST_TS_LF, /* REFCLK_GPS_MX4200 (9) */ 388 CTL_SST_TS_UHF, /* REFCLK_GPS_AS2201 (10) */ 389 CTL_SST_TS_UHF, /* REFCLK_GPS_ARBITER (11) */ 390 CTL_SST_TS_UHF, /* REFCLK_IRIG_TPRO (12) */ 391 CTL_SST_TS_ATOM, /* REFCLK_ATOM_LEITCH (13) */ 392 CTL_SST_TS_LF, /* deprecated REFCLK_MSF_EES (14) */ 393 CTL_SST_TS_NTP, /* not used (15) */ 394 CTL_SST_TS_UHF, /* REFCLK_IRIG_BANCOMM (16) */ 395 CTL_SST_TS_UHF, /* REFCLK_GPS_DATU (17) */ 396 CTL_SST_TS_TELEPHONE, /* REFCLK_NIST_ACTS (18) */ 397 CTL_SST_TS_HF, /* REFCLK_WWV_HEATH (19) */ 398 CTL_SST_TS_UHF, /* REFCLK_GPS_NMEA (20) */ 399 CTL_SST_TS_UHF, /* REFCLK_GPS_VME (21) */ 400 CTL_SST_TS_ATOM, /* REFCLK_ATOM_PPS (22) */ 401 CTL_SST_TS_NTP, /* not used (23) */ 402 CTL_SST_TS_NTP, /* not used (24) */ 403 CTL_SST_TS_NTP, /* not used (25) */ 404 CTL_SST_TS_UHF, /* REFCLK_GPS_HP (26) */ 405 CTL_SST_TS_TELEPHONE, /* REFCLK_ARCRON_MSF (27) */ 406 CTL_SST_TS_TELEPHONE, /* REFCLK_SHM (28) */ 407 CTL_SST_TS_UHF, /* REFCLK_PALISADE (29) */ 408 CTL_SST_TS_UHF, /* REFCLK_ONCORE (30) */ 409 CTL_SST_TS_UHF, /* REFCLK_JUPITER (31) */ 410 CTL_SST_TS_LF, /* REFCLK_CHRONOLOG (32) */ 411 CTL_SST_TS_LF, /* REFCLK_DUMBCLOCK (33) */ 412 CTL_SST_TS_LF, /* REFCLK_ULINK (34) */ 413 CTL_SST_TS_LF, /* REFCLK_PCF (35) */ 414 CTL_SST_TS_HF, /* REFCLK_WWV (36) */ 415 CTL_SST_TS_LF, /* REFCLK_FG (37) */ 416 CTL_SST_TS_UHF, /* REFCLK_HOPF_SERIAL (38) */ 417 CTL_SST_TS_UHF, /* REFCLK_HOPF_PCI (39) */ 418 CTL_SST_TS_LF, /* REFCLK_JJY (40) */ 419 CTL_SST_TS_UHF, /* REFCLK_TT560 (41) */ 420 CTL_SST_TS_UHF, /* REFCLK_ZYFER (42) */ 421 CTL_SST_TS_UHF, /* REFCLK_RIPENCC (43) */ 422 CTL_SST_TS_UHF, /* REFCLK_NEOCLOCK4X (44) */ 423 }; 424 425 426 /* 427 * Keyid used for authenticating write requests. 428 */ 429 keyid_t ctl_auth_keyid; 430 431 /* 432 * We keep track of the last error reported by the system internally 433 */ 434 static u_char ctl_sys_last_event; 435 static u_char ctl_sys_num_events; 436 437 438 /* 439 * Statistic counters to keep track of requests and responses. 440 */ 441 u_long ctltimereset; /* time stats reset */ 442 u_long numctlreq; /* number of requests we've received */ 443 u_long numctlbadpkts; /* number of bad control packets */ 444 u_long numctlresponses; /* number of resp packets sent with data */ 445 u_long numctlfrags; /* number of fragments sent */ 446 u_long numctlerrors; /* number of error responses sent */ 447 u_long numctltooshort; /* number of too short input packets */ 448 u_long numctlinputresp; /* number of responses on input */ 449 u_long numctlinputfrag; /* number of fragments on input */ 450 u_long numctlinputerr; /* number of input pkts with err bit set */ 451 u_long numctlbadoffset; /* number of input pkts with nonzero offset */ 452 u_long numctlbadversion; /* number of input pkts with unknown version */ 453 u_long numctldatatooshort; /* data too short for count */ 454 u_long numctlbadop; /* bad op code found in packet */ 455 u_long numasyncmsgs; /* number of async messages we've sent */ 456 457 /* 458 * Response packet used by these routines. Also some state information 459 * so that we can handle packet formatting within a common set of 460 * subroutines. Note we try to enter data in place whenever possible, 461 * but the need to set the more bit correctly means we occasionally 462 * use the extra buffer and copy. 463 */ 464 static struct ntp_control rpkt; 465 static u_char res_version; 466 static u_char res_opcode; 467 static associd_t res_associd; 468 static int res_offset; 469 static u_char * datapt; 470 static u_char * dataend; 471 static int datalinelen; 472 static int datanotbinflag; 473 static sockaddr_u *rmt_addr; 474 static struct interface *lcl_inter; 475 476 static u_char res_authenticate; 477 static u_char res_authokay; 478 static keyid_t res_keyid; 479 480 #define MAXDATALINELEN (72) 481 482 static u_char res_async; /* set to 1 if this is async trap response */ 483 484 /* 485 * Pointers for saving state when decoding request packets 486 */ 487 static char *reqpt; 488 static char *reqend; 489 490 /* 491 * init_control - initialize request data 492 */ 493 void 494 init_control(void) 495 { 496 int i; 497 498 #ifdef HAVE_UNAME 499 uname(&utsnamebuf); 500 #endif /* HAVE_UNAME */ 501 502 ctl_clr_stats(); 503 504 ctl_auth_keyid = 0; 505 ctl_sys_last_event = EVNT_UNSPEC; 506 ctl_sys_num_events = 0; 507 508 num_ctl_traps = 0; 509 for (i = 0; i < CTL_MAXTRAPS; i++) 510 ctl_trap[i].tr_flags = 0; 511 } 512 513 514 /* 515 * ctl_error - send an error response for the current request 516 */ 517 static void 518 ctl_error( 519 int errcode 520 ) 521 { 522 DPRINTF(3, ("sending control error %d\n", errcode)); 523 524 /* 525 * Fill in the fields. We assume rpkt.sequence and rpkt.associd 526 * have already been filled in. 527 */ 528 rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode & 529 CTL_OP_MASK)); 530 rpkt.status = htons((u_short) ((errcode & 0xff) << 8)); 531 rpkt.count = 0; 532 533 /* 534 * send packet and bump counters 535 */ 536 if (res_authenticate && sys_authenticate) { 537 int maclen; 538 539 *(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN) = 540 htonl(res_keyid); 541 maclen = authencrypt(res_keyid, (u_int32 *)&rpkt, 542 CTL_HEADER_LEN); 543 sendpkt(rmt_addr, lcl_inter, -2, (struct pkt *)&rpkt, 544 CTL_HEADER_LEN + maclen); 545 } else { 546 sendpkt(rmt_addr, lcl_inter, -3, (struct pkt *)&rpkt, 547 CTL_HEADER_LEN); 548 } 549 numctlerrors++; 550 } 551 552 /* 553 * save_config - Implements ntpq -c "saveconfig <filename>" 554 * Writes current configuration including any runtime 555 * changes by ntpq's :config or config-from-file 556 */ 557 void 558 save_config( 559 struct recvbuf *rbufp, 560 int restrict_mask 561 ) 562 { 563 char reply[128]; 564 #ifdef SAVECONFIG 565 char filespec[128]; 566 char filename[128]; 567 char fullpath[512]; 568 const char savedconfig_eq[] = "savedconfig="; 569 char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)]; 570 time_t now; 571 int fd; 572 FILE *fptr; 573 #endif 574 575 if (restrict_mask & RES_NOMODIFY) { 576 snprintf(reply, sizeof(reply), 577 "saveconfig prohibited by restrict ... nomodify"); 578 ctl_putdata(reply, strlen(reply), 0); 579 ctl_flushpkt(0); 580 msyslog(LOG_NOTICE, 581 "saveconfig from %s rejected due to nomodify restriction", 582 stoa(&rbufp->recv_srcadr)); 583 return; 584 } 585 586 #ifdef SAVECONFIG 587 if (NULL == saveconfigdir) { 588 snprintf(reply, sizeof(reply), 589 "saveconfig prohibited, no saveconfigdir configured"); 590 ctl_putdata(reply, strlen(reply), 0); 591 ctl_flushpkt(0); 592 msyslog(LOG_NOTICE, 593 "saveconfig from %s rejected, no saveconfigdir", 594 stoa(&rbufp->recv_srcadr)); 595 return; 596 } 597 598 if (0 == reqend - reqpt) 599 return; 600 601 strncpy(filespec, reqpt, sizeof(filespec)); 602 filespec[sizeof(filespec) - 1] = '\0'; 603 604 time(&now); 605 606 /* 607 * allow timestamping of the saved config filename with 608 * strftime() format such as: 609 * ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf" 610 * XXX: Nice feature, but not too safe. 611 */ 612 if (0 == strftime(filename, sizeof(filename), filespec, 613 localtime(&now))) 614 strncpy(filename, filespec, sizeof(filename)); 615 616 filename[sizeof(filename) - 1] = '\0'; 617 618 if (strchr(filename, '\\') || strchr(filename, '/')) { 619 snprintf(reply, sizeof(reply), 620 "saveconfig does not allow directory in filename"); 621 ctl_putdata(reply, strlen(reply), 0); 622 ctl_flushpkt(0); 623 msyslog(LOG_NOTICE, 624 "saveconfig with path from %s rejected", 625 stoa(&rbufp->recv_srcadr)); 626 return; 627 } 628 629 snprintf(fullpath, sizeof(fullpath), "%s%s", 630 saveconfigdir, filename); 631 632 fd = open(fullpath, O_CREAT | O_TRUNC | O_WRONLY, 633 S_IRUSR | S_IWUSR); 634 if (-1 == fd) 635 fptr = NULL; 636 else 637 fptr = fdopen(fd, "w"); 638 639 if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) { 640 snprintf(reply, sizeof(reply), 641 "Unable to save configuration to file %s", 642 filename); 643 msyslog(LOG_ERR, 644 "saveconfig %s from %s failed", filename, 645 stoa(&rbufp->recv_srcadr)); 646 } else { 647 snprintf(reply, sizeof(reply), 648 "Configuration saved to %s", filename); 649 msyslog(LOG_NOTICE, 650 "Configuration saved to %s (requested by %s)", 651 fullpath, stoa(&rbufp->recv_srcadr)); 652 /* 653 * save the output filename in system variable 654 * savedconfig, retrieved with: 655 * ntpq -c "rv 0 savedconfig" 656 */ 657 snprintf(savedconfig, sizeof(savedconfig), "%s%s", 658 savedconfig_eq, filename); 659 set_sys_var(savedconfig, strlen(savedconfig) + 1, RO); 660 } 661 662 if (NULL != fptr) 663 fclose(fptr); 664 #else /* !SAVECONFIG follows */ 665 snprintf(reply, sizeof(reply), 666 "saveconfig unavailable, configured with --disable-saveconfig"); 667 #endif 668 669 ctl_putdata(reply, strlen(reply), 0); 670 ctl_flushpkt(0); 671 } 672 673 674 /* 675 * process_control - process an incoming control message 676 */ 677 void 678 process_control( 679 struct recvbuf *rbufp, 680 int restrict_mask 681 ) 682 { 683 register struct ntp_control *pkt; 684 register int req_count; 685 register int req_data; 686 register struct ctl_proc *cc; 687 int properlen; 688 size_t maclen; 689 690 DPRINTF(3, ("in process_control()\n")); 691 692 /* 693 * Save the addresses for error responses 694 */ 695 numctlreq++; 696 rmt_addr = &rbufp->recv_srcadr; 697 lcl_inter = rbufp->dstadr; 698 pkt = (struct ntp_control *)&rbufp->recv_pkt; 699 700 /* 701 * If the length is less than required for the header, or 702 * it is a response or a fragment, ignore this. 703 */ 704 if (rbufp->recv_length < CTL_HEADER_LEN 705 || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR) 706 || pkt->offset != 0) { 707 DPRINTF(1, ("invalid format in control packet\n")); 708 if (rbufp->recv_length < CTL_HEADER_LEN) 709 numctltooshort++; 710 if (pkt->r_m_e_op & CTL_RESPONSE) 711 numctlinputresp++; 712 if (pkt->r_m_e_op & CTL_MORE) 713 numctlinputfrag++; 714 if (pkt->r_m_e_op & CTL_ERROR) 715 numctlinputerr++; 716 if (pkt->offset != 0) 717 numctlbadoffset++; 718 return; 719 } 720 res_version = PKT_VERSION(pkt->li_vn_mode); 721 if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) { 722 DPRINTF(1, ("unknown version %d in control packet\n", 723 res_version)); 724 numctlbadversion++; 725 return; 726 } 727 728 /* 729 * Pull enough data from the packet to make intelligent 730 * responses 731 */ 732 rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version, 733 MODE_CONTROL); 734 res_opcode = pkt->r_m_e_op; 735 rpkt.sequence = pkt->sequence; 736 rpkt.associd = pkt->associd; 737 rpkt.status = 0; 738 res_offset = 0; 739 res_associd = htons(pkt->associd); 740 res_async = 0; 741 res_authenticate = 0; 742 res_keyid = 0; 743 res_authokay = 0; 744 req_count = (int)ntohs(pkt->count); 745 datanotbinflag = 0; 746 datalinelen = 0; 747 datapt = rpkt.data; 748 dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); 749 750 if ((rbufp->recv_length & 0x3) != 0) 751 DPRINTF(3, ("Control packet length %d unrounded\n", 752 rbufp->recv_length)); 753 754 /* 755 * We're set up now. Make sure we've got at least enough 756 * incoming data space to match the count. 757 */ 758 req_data = rbufp->recv_length - CTL_HEADER_LEN; 759 if (req_data < req_count || rbufp->recv_length & 0x3) { 760 ctl_error(CERR_BADFMT); 761 numctldatatooshort++; 762 return; 763 } 764 765 properlen = req_count + CTL_HEADER_LEN; 766 /* round up proper len to a 8 octet boundary */ 767 768 properlen = (properlen + 7) & ~7; 769 maclen = rbufp->recv_length - properlen; 770 if ((rbufp->recv_length & 3) == 0 && 771 maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN && 772 sys_authenticate) { 773 res_authenticate = 1; 774 res_keyid = ntohl(*(u_int32 *)((u_char *)pkt + 775 properlen)); 776 777 DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n", 778 rbufp->recv_length, properlen, res_keyid, 779 maclen)); 780 781 if (!authistrusted(res_keyid)) 782 DPRINTF(3, ("invalid keyid %08x\n", res_keyid)); 783 else if (authdecrypt(res_keyid, (u_int32 *)pkt, 784 rbufp->recv_length - maclen, 785 maclen)) { 786 DPRINTF(3, ("authenticated okay\n")); 787 res_authokay = 1; 788 } else { 789 DPRINTF(3, ("authentication failed\n")); 790 res_keyid = 0; 791 } 792 } 793 794 /* 795 * Set up translate pointers 796 */ 797 reqpt = (char *)pkt->data; 798 reqend = reqpt + req_count; 799 800 /* 801 * Look for the opcode processor 802 */ 803 for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) { 804 if (cc->control_code == res_opcode) { 805 DPRINTF(3, ("opcode %d, found command handler\n", 806 res_opcode)); 807 if (cc->flags == AUTH 808 && (!res_authokay 809 || res_keyid != ctl_auth_keyid)) { 810 ctl_error(CERR_PERMISSION); 811 return; 812 } 813 (cc->handler)(rbufp, restrict_mask); 814 return; 815 } 816 } 817 818 /* 819 * Can't find this one, return an error. 820 */ 821 numctlbadop++; 822 ctl_error(CERR_BADOP); 823 return; 824 } 825 826 827 /* 828 * ctlpeerstatus - return a status word for this peer 829 */ 830 u_short 831 ctlpeerstatus( 832 register struct peer *peer 833 ) 834 { 835 u_short status; 836 837 status = peer->status; 838 if (!(peer->flags & FLAG_PREEMPT)) 839 status |= CTL_PST_CONFIG; 840 if (peer->keyid != 0) 841 status |= CTL_PST_AUTHENABLE; 842 if (peer->flags & FLAG_AUTHENTIC) 843 status |= CTL_PST_AUTHENTIC; 844 if (peer->reach != 0) 845 status |= CTL_PST_REACH; 846 if (peer->cast_flags & (MDF_BCAST | MDF_MCAST | MDF_ACAST)) 847 status |= CTL_PST_BCAST; 848 return (u_short)CTL_PEER_STATUS(status, peer->num_events, 849 peer->last_event); 850 } 851 852 853 /* 854 * ctlclkstatus - return a status word for this clock 855 */ 856 #ifdef REFCLOCK 857 static u_short 858 ctlclkstatus( 859 struct refclockstat *this_clock 860 ) 861 { 862 return (u_short)CTL_PEER_STATUS(0, this_clock->lastevent, 863 this_clock->currentstatus); 864 } 865 #endif 866 867 868 /* 869 * ctlsysstatus - return the system status word 870 */ 871 u_short 872 ctlsysstatus(void) 873 { 874 register u_char this_clock; 875 876 this_clock = CTL_SST_TS_UNSPEC; 877 #ifdef REFCLOCK 878 if (sys_peer != 0) { 879 if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC) { 880 this_clock = sys_peer->sstclktype; 881 } else { 882 if (sys_peer->refclktype < sizeof(clocktypes)) 883 this_clock = 884 clocktypes[sys_peer->refclktype]; 885 } 886 } 887 #else /* REFCLOCK */ 888 if (sys_peer != 0) 889 this_clock = CTL_SST_TS_NTP; 890 #endif /* REFCLOCK */ 891 return (u_short)CTL_SYS_STATUS(sys_leap, this_clock, 892 ctl_sys_num_events, ctl_sys_last_event); 893 } 894 895 896 /* 897 * ctl_flushpkt - write out the current packet and prepare 898 * another if necessary. 899 */ 900 static void 901 ctl_flushpkt( 902 int more 903 ) 904 { 905 int dlen; 906 int sendlen; 907 908 if (!more && datanotbinflag) { 909 /* 910 * Big hack, output a trailing \r\n 911 */ 912 *datapt++ = '\r'; 913 *datapt++ = '\n'; 914 } 915 dlen = datapt - (u_char *)rpkt.data; 916 sendlen = dlen + CTL_HEADER_LEN; 917 918 /* 919 * Pad to a multiple of 32 bits 920 */ 921 while (sendlen & 0x3) { 922 *datapt++ = '\0'; 923 sendlen++; 924 } 925 926 /* 927 * Fill in the packet with the current info 928 */ 929 rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode & 930 CTL_OP_MASK)); 931 rpkt.count = htons((u_short) dlen); 932 rpkt.offset = htons( (u_short) res_offset); 933 if (res_async) { 934 register int i; 935 936 for (i = 0; i < CTL_MAXTRAPS; i++) { 937 if (ctl_trap[i].tr_flags & TRAP_INUSE) { 938 rpkt.li_vn_mode = 939 PKT_LI_VN_MODE(sys_leap, 940 ctl_trap[i].tr_version, 941 MODE_CONTROL); 942 rpkt.sequence = 943 htons(ctl_trap[i].tr_sequence); 944 sendpkt(&ctl_trap[i].tr_addr, 945 ctl_trap[i].tr_localaddr, -4, 946 (struct pkt *)&rpkt, sendlen); 947 if (!more) 948 ctl_trap[i].tr_sequence++; 949 numasyncmsgs++; 950 } 951 } 952 } else { 953 if (res_authenticate && sys_authenticate) { 954 int maclen; 955 int totlen = sendlen; 956 keyid_t keyid = htonl(res_keyid); 957 958 /* 959 * If we are going to authenticate, then there 960 * is an additional requirement that the MAC 961 * begin on a 64 bit boundary. 962 */ 963 while (totlen & 7) { 964 *datapt++ = '\0'; 965 totlen++; 966 } 967 memcpy(datapt, &keyid, sizeof keyid); 968 maclen = authencrypt(res_keyid, 969 (u_int32 *)&rpkt, totlen); 970 sendpkt(rmt_addr, lcl_inter, -5, 971 (struct pkt *)&rpkt, totlen + maclen); 972 } else { 973 sendpkt(rmt_addr, lcl_inter, -6, 974 (struct pkt *)&rpkt, sendlen); 975 } 976 if (more) 977 numctlfrags++; 978 else 979 numctlresponses++; 980 } 981 982 /* 983 * Set us up for another go around. 984 */ 985 res_offset += dlen; 986 datapt = (u_char *)rpkt.data; 987 } 988 989 990 /* 991 * ctl_putdata - write data into the packet, fragmenting and starting 992 * another if this one is full. 993 */ 994 static void 995 ctl_putdata( 996 const char *dp, 997 unsigned int dlen, 998 int bin /* set to 1 when data is binary */ 999 ) 1000 { 1001 int overhead; 1002 1003 overhead = 0; 1004 if (!bin) { 1005 datanotbinflag = 1; 1006 overhead = 3; 1007 if (datapt != rpkt.data) { 1008 *datapt++ = ','; 1009 datalinelen++; 1010 if ((dlen + datalinelen + 1) >= MAXDATALINELEN) 1011 { 1012 *datapt++ = '\r'; 1013 *datapt++ = '\n'; 1014 datalinelen = 0; 1015 } else { 1016 *datapt++ = ' '; 1017 datalinelen++; 1018 } 1019 } 1020 } 1021 1022 /* 1023 * Save room for trailing junk 1024 */ 1025 if (dlen + overhead + datapt > dataend) { 1026 /* 1027 * Not enough room in this one, flush it out. 1028 */ 1029 ctl_flushpkt(CTL_MORE); 1030 } 1031 memmove((char *)datapt, dp, (unsigned)dlen); 1032 datapt += dlen; 1033 datalinelen += dlen; 1034 } 1035 1036 1037 /* 1038 * ctl_putstr - write a tagged string into the response packet 1039 */ 1040 static void 1041 ctl_putstr( 1042 const char *tag, 1043 const char *data, 1044 unsigned int len 1045 ) 1046 { 1047 register char *cp; 1048 register const char *cq; 1049 char buffer[400]; 1050 1051 cp = buffer; 1052 cq = tag; 1053 while (*cq != '\0') 1054 *cp++ = *cq++; 1055 if (len > 0) { 1056 *cp++ = '='; 1057 *cp++ = '"'; 1058 if (len > (sizeof(buffer) - (cp - buffer) - 1)) 1059 len = sizeof(buffer) - (cp - buffer) - 1; 1060 memmove(cp, data, (unsigned)len); 1061 cp += len; 1062 *cp++ = '"'; 1063 } 1064 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1065 } 1066 1067 1068 /* 1069 * ctl_putdbl - write a tagged, signed double into the response packet 1070 */ 1071 static void 1072 ctl_putdbl( 1073 const char *tag, 1074 double ts 1075 ) 1076 { 1077 register char *cp; 1078 register const char *cq; 1079 char buffer[200]; 1080 1081 cp = buffer; 1082 cq = tag; 1083 while (*cq != '\0') 1084 *cp++ = *cq++; 1085 *cp++ = '='; 1086 (void)sprintf(cp, "%.3f", ts); 1087 while (*cp != '\0') 1088 cp++; 1089 ctl_putdata(buffer, (unsigned)(cp - buffer), 0); 1090 } 1091 1092 /* 1093 * ctl_putuint - write a tagged unsigned integer into the response 1094 */ 1095 static void 1096 ctl_putuint( 1097 const char *tag, 1098 u_long uval 1099 ) 1100 { 1101 register char *cp; 1102 register const char *cq; 1103 char buffer[200]; 1104 1105 cp = buffer; 1106 cq = tag; 1107 while (*cq != '\0') 1108 *cp++ = *cq++; 1109 1110 *cp++ = '='; 1111 (void) sprintf(cp, "%lu", uval); 1112 while (*cp != '\0') 1113 cp++; 1114 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1115 } 1116 1117 /* 1118 * ctl_putfs - write a decoded filestamp into the response 1119 */ 1120 static void 1121 ctl_putfs( 1122 const char *tag, 1123 tstamp_t uval 1124 ) 1125 { 1126 register char *cp; 1127 register const char *cq; 1128 char buffer[200]; 1129 struct tm *tm = NULL; 1130 time_t fstamp; 1131 1132 cp = buffer; 1133 cq = tag; 1134 while (*cq != '\0') 1135 *cp++ = *cq++; 1136 1137 *cp++ = '='; 1138 fstamp = uval - JAN_1970; 1139 tm = gmtime(&fstamp); 1140 if (tm == NULL) 1141 return; 1142 1143 sprintf(cp, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 1144 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); 1145 while (*cp != '\0') 1146 cp++; 1147 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1148 } 1149 1150 1151 /* 1152 * ctl_puthex - write a tagged unsigned integer, in hex, into the 1153 * response 1154 */ 1155 static void 1156 ctl_puthex( 1157 const char *tag, 1158 u_long uval 1159 ) 1160 { 1161 register char *cp; 1162 register const char *cq; 1163 char buffer[200]; 1164 1165 cp = buffer; 1166 cq = tag; 1167 while (*cq != '\0') 1168 *cp++ = *cq++; 1169 1170 *cp++ = '='; 1171 (void) sprintf(cp, "0x%lx", uval); 1172 while (*cp != '\0') 1173 cp++; 1174 ctl_putdata(buffer,(unsigned)( cp - buffer ), 0); 1175 } 1176 1177 1178 /* 1179 * ctl_putint - write a tagged signed integer into the response 1180 */ 1181 static void 1182 ctl_putint( 1183 const char *tag, 1184 long ival 1185 ) 1186 { 1187 register char *cp; 1188 register const char *cq; 1189 char buffer[200]; 1190 1191 cp = buffer; 1192 cq = tag; 1193 while (*cq != '\0') 1194 *cp++ = *cq++; 1195 1196 *cp++ = '='; 1197 (void) sprintf(cp, "%ld", ival); 1198 while (*cp != '\0') 1199 cp++; 1200 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1201 } 1202 1203 1204 /* 1205 * ctl_putts - write a tagged timestamp, in hex, into the response 1206 */ 1207 static void 1208 ctl_putts( 1209 const char *tag, 1210 l_fp *ts 1211 ) 1212 { 1213 register char *cp; 1214 register const char *cq; 1215 char buffer[200]; 1216 1217 cp = buffer; 1218 cq = tag; 1219 while (*cq != '\0') 1220 *cp++ = *cq++; 1221 1222 *cp++ = '='; 1223 (void) sprintf(cp, "0x%08lx.%08lx", ts->l_ui & 0xffffffffUL, 1224 ts->l_uf & 0xffffffffUL); 1225 while (*cp != '\0') 1226 cp++; 1227 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1228 } 1229 1230 1231 /* 1232 * ctl_putadr - write an IP address into the response 1233 */ 1234 static void 1235 ctl_putadr( 1236 const char *tag, 1237 u_int32 addr32, 1238 sockaddr_u *addr 1239 ) 1240 { 1241 register char *cp; 1242 register const char *cq; 1243 char buffer[200]; 1244 1245 cp = buffer; 1246 cq = tag; 1247 while (*cq != '\0') 1248 *cp++ = *cq++; 1249 1250 *cp++ = '='; 1251 if (addr == NULL) 1252 cq = numtoa(addr32); 1253 else 1254 cq = stoa(addr); 1255 while (*cq != '\0') 1256 *cp++ = *cq++; 1257 ctl_putdata(buffer, (unsigned)(cp - buffer), 0); 1258 } 1259 1260 /* 1261 * ctl_putid - write a tagged clock ID into the response 1262 */ 1263 static void 1264 ctl_putid( 1265 const char *tag, 1266 char *id 1267 ) 1268 { 1269 register char *cp; 1270 register const char *cq; 1271 char buffer[200]; 1272 1273 cp = buffer; 1274 cq = tag; 1275 while (*cq != '\0') 1276 *cp++ = *cq++; 1277 1278 *cp++ = '='; 1279 cq = id; 1280 while (*cq != '\0' && (cq - id) < 4) 1281 *cp++ = *cq++; 1282 ctl_putdata(buffer, (unsigned)( cp - buffer ), 0); 1283 } 1284 1285 1286 /* 1287 * ctl_putarray - write a tagged eight element double array into the response 1288 */ 1289 static void 1290 ctl_putarray( 1291 const char *tag, 1292 double *arr, 1293 int start 1294 ) 1295 { 1296 register char *cp; 1297 register const char *cq; 1298 char buffer[200]; 1299 int i; 1300 cp = buffer; 1301 cq = tag; 1302 while (*cq != '\0') 1303 *cp++ = *cq++; 1304 i = start; 1305 do { 1306 if (i == 0) 1307 i = NTP_SHIFT; 1308 i--; 1309 (void)sprintf(cp, " %.2f", arr[i] * 1e3); 1310 while (*cp != '\0') 1311 cp++; 1312 } while(i != start); 1313 ctl_putdata(buffer, (unsigned)(cp - buffer), 0); 1314 } 1315 1316 1317 /* 1318 * ctl_putsys - output a system variable 1319 */ 1320 static void 1321 ctl_putsys( 1322 int varid 1323 ) 1324 { 1325 l_fp tmp; 1326 char str[256]; 1327 #ifdef OPENSSL 1328 struct cert_info *cp; 1329 char cbuf[256]; 1330 #endif /* OPENSSL */ 1331 1332 switch (varid) { 1333 1334 case CS_LEAP: 1335 ctl_putuint(sys_var[CS_LEAP].text, sys_leap); 1336 break; 1337 1338 case CS_STRATUM: 1339 ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum); 1340 break; 1341 1342 case CS_PRECISION: 1343 ctl_putint(sys_var[CS_PRECISION].text, sys_precision); 1344 break; 1345 1346 case CS_ROOTDELAY: 1347 ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay * 1348 1e3); 1349 break; 1350 1351 case CS_ROOTDISPERSION: 1352 ctl_putdbl(sys_var[CS_ROOTDISPERSION].text, 1353 sys_rootdisp * 1e3); 1354 break; 1355 1356 case CS_REFID: 1357 if (sys_stratum > 1 && sys_stratum < STRATUM_UNSPEC) 1358 ctl_putadr(sys_var[CS_REFID].text, sys_refid, NULL); 1359 else 1360 ctl_putid(sys_var[CS_REFID].text, 1361 (char *)&sys_refid); 1362 break; 1363 1364 case CS_REFTIME: 1365 ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime); 1366 break; 1367 1368 case CS_POLL: 1369 ctl_putuint(sys_var[CS_POLL].text, sys_poll); 1370 break; 1371 1372 case CS_PEERID: 1373 if (sys_peer == NULL) 1374 ctl_putuint(sys_var[CS_PEERID].text, 0); 1375 else 1376 ctl_putuint(sys_var[CS_PEERID].text, 1377 sys_peer->associd); 1378 break; 1379 1380 case CS_OFFSET: 1381 ctl_putdbl(sys_var[CS_OFFSET].text, last_offset * 1e3); 1382 break; 1383 1384 case CS_DRIFT: 1385 ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6); 1386 break; 1387 1388 case CS_JITTER: 1389 ctl_putdbl(sys_var[CS_JITTER].text, sys_jitter * 1e3); 1390 break; 1391 1392 case CS_ERROR: 1393 ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3); 1394 break; 1395 1396 case CS_CLOCK: 1397 get_systime(&tmp); 1398 ctl_putts(sys_var[CS_CLOCK].text, &tmp); 1399 break; 1400 1401 case CS_PROCESSOR: 1402 #ifndef HAVE_UNAME 1403 ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor, 1404 sizeof(str_processor) - 1); 1405 #else 1406 ctl_putstr(sys_var[CS_PROCESSOR].text, 1407 utsnamebuf.machine, strlen(utsnamebuf.machine)); 1408 #endif /* HAVE_UNAME */ 1409 break; 1410 1411 case CS_SYSTEM: 1412 #ifndef HAVE_UNAME 1413 ctl_putstr(sys_var[CS_SYSTEM].text, str_system, 1414 sizeof(str_system) - 1); 1415 #else 1416 sprintf(str, "%s/%s", utsnamebuf.sysname, utsnamebuf.release); 1417 ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str)); 1418 #endif /* HAVE_UNAME */ 1419 break; 1420 1421 case CS_VERSION: 1422 ctl_putstr(sys_var[CS_VERSION].text, Version, 1423 strlen(Version)); 1424 break; 1425 1426 case CS_STABIL: 1427 ctl_putdbl(sys_var[CS_STABIL].text, clock_stability * 1428 1e6); 1429 break; 1430 1431 case CS_VARLIST: 1432 { 1433 char buf[CTL_MAX_DATA_LEN]; 1434 register char *s, *t, *be; 1435 register const char *ss; 1436 register int i; 1437 register struct ctl_var *k; 1438 1439 s = buf; 1440 be = buf + sizeof(buf); 1441 if (s + strlen(sys_var[CS_VARLIST].text) + 4 > be) 1442 break; /* really long var name */ 1443 1444 snprintf(s, sizeof(buf), "%s=\"", 1445 sys_var[CS_VARLIST].text); 1446 s += strlen(s); 1447 t = s; 1448 for (k = sys_var; !(k->flags & EOV); k++) { 1449 if (k->flags & PADDING) 1450 continue; 1451 i = strlen(k->text); 1452 if (s+i+1 >= be) 1453 break; 1454 1455 if (s != t) 1456 *s++ = ','; 1457 memcpy(s, k->text, i); 1458 s += i; 1459 } 1460 1461 for (k = ext_sys_var; k && !(k->flags & EOV); 1462 k++) { 1463 if (k->flags & PADDING) 1464 continue; 1465 1466 ss = k->text; 1467 if (!ss) 1468 continue; 1469 1470 while (*ss && *ss != '=') 1471 ss++; 1472 i = ss - k->text; 1473 if (s + i + 1 >= be) 1474 break; 1475 1476 if (s != t) 1477 *s++ = ','; 1478 memcpy(s, k->text, 1479 (unsigned)i); 1480 s += i; 1481 } 1482 if (s+2 >= be) 1483 break; 1484 1485 *s++ = '"'; 1486 *s = '\0'; 1487 1488 ctl_putdata(buf, (unsigned)( s - buf ), 1489 0); 1490 } 1491 break; 1492 1493 case CS_TAI: 1494 if (sys_tai > 0) 1495 ctl_putuint(sys_var[CS_TAI].text, sys_tai); 1496 break; 1497 1498 case CS_LEAPTAB: 1499 if (leap_sec > 0) 1500 ctl_putfs(sys_var[CS_LEAPTAB].text, 1501 leap_sec); 1502 break; 1503 1504 case CS_LEAPEND: 1505 if (leap_expire > 0) 1506 ctl_putfs(sys_var[CS_LEAPEND].text, 1507 leap_expire); 1508 break; 1509 1510 case CS_RATE: 1511 ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll); 1512 break; 1513 1514 #ifdef OPENSSL 1515 case CS_FLAGS: 1516 if (crypto_flags) 1517 ctl_puthex(sys_var[CS_FLAGS].text, 1518 crypto_flags); 1519 break; 1520 1521 case CS_DIGEST: 1522 if (crypto_flags) { 1523 strcpy(str, OBJ_nid2ln(crypto_nid)); 1524 ctl_putstr(sys_var[CS_DIGEST].text, str, 1525 strlen(str)); 1526 } 1527 break; 1528 1529 case CS_SIGNATURE: 1530 if (crypto_flags) { 1531 const EVP_MD *dp; 1532 1533 dp = EVP_get_digestbynid(crypto_flags >> 16); 1534 strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp))); 1535 ctl_putstr(sys_var[CS_SIGNATURE].text, str, 1536 strlen(str)); 1537 } 1538 break; 1539 1540 case CS_HOST: 1541 if (sys_hostname != NULL) 1542 ctl_putstr(sys_var[CS_HOST].text, sys_hostname, 1543 strlen(sys_hostname)); 1544 break; 1545 1546 case CS_GROUP: 1547 if (sys_groupname != NULL) 1548 ctl_putstr(sys_var[CS_GROUP].text, sys_groupname, 1549 strlen(sys_groupname)); 1550 break; 1551 1552 case CS_CERTIF: 1553 for (cp = cinfo; cp != NULL; cp = cp->link) { 1554 snprintf(cbuf, sizeof(cbuf), "%s %s 0x%x", 1555 cp->subject, cp->issuer, cp->flags); 1556 ctl_putstr(sys_var[CS_CERTIF].text, cbuf, 1557 strlen(cbuf)); 1558 ctl_putfs(sys_var[CS_REVTIME].text, cp->last); 1559 } 1560 break; 1561 1562 case CS_PUBLIC: 1563 if (hostval.tstamp != 0) 1564 ctl_putfs(sys_var[CS_PUBLIC].text, 1565 ntohl(hostval.tstamp)); 1566 break; 1567 #endif /* OPENSSL */ 1568 } 1569 } 1570 1571 1572 /* 1573 * ctl_putpeer - output a peer variable 1574 */ 1575 static void 1576 ctl_putpeer( 1577 int varid, 1578 struct peer *peer 1579 ) 1580 { 1581 int temp; 1582 #ifdef OPENSSL 1583 char str[256]; 1584 struct autokey *ap; 1585 #endif /* OPENSSL */ 1586 1587 switch (varid) { 1588 1589 case CP_CONFIG: 1590 ctl_putuint(peer_var[CP_CONFIG].text, 1591 (unsigned)((peer->flags & FLAG_PREEMPT) == 0)); 1592 break; 1593 1594 case CP_AUTHENABLE: 1595 ctl_putuint(peer_var[CP_AUTHENABLE].text, 1596 (unsigned)(peer->keyid != 0)); 1597 break; 1598 1599 case CP_AUTHENTIC: 1600 ctl_putuint(peer_var[CP_AUTHENTIC].text, 1601 (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0)); 1602 break; 1603 1604 case CP_SRCADR: 1605 ctl_putadr(peer_var[CP_SRCADR].text, 0, 1606 &peer->srcadr); 1607 break; 1608 1609 case CP_SRCPORT: 1610 ctl_putuint(peer_var[CP_SRCPORT].text, 1611 ntohs(((struct sockaddr_in*)&peer->srcadr)->sin_port)); 1612 break; 1613 1614 case CP_DSTADR: 1615 if (peer->dstadr) { 1616 ctl_putadr(peer_var[CP_DSTADR].text, 0, 1617 &(peer->dstadr->sin)); 1618 } else { 1619 ctl_putadr(peer_var[CP_DSTADR].text, 0, 1620 NULL); 1621 } 1622 break; 1623 1624 case CP_DSTPORT: 1625 ctl_putuint(peer_var[CP_DSTPORT].text, 1626 (u_long)(peer->dstadr ? 1627 ntohs(((struct sockaddr_in*)&peer->dstadr->sin)->sin_port) : 0)); 1628 break; 1629 1630 case CP_IN: 1631 if (peer->r21 > 0) 1632 ctl_putdbl(peer_var[CP_IN].text, 1633 peer->r21 / 1e3); 1634 break; 1635 1636 case CP_OUT: 1637 if (peer->r34 >0) 1638 ctl_putdbl(peer_var[CP_OUT].text, 1639 peer->r34 / 1e3); 1640 break; 1641 1642 case CP_RATE: 1643 ctl_putuint(peer_var[CP_RATE].text, peer->throttle); 1644 break; 1645 1646 case CP_LEAP: 1647 ctl_putuint(peer_var[CP_LEAP].text, peer->leap); 1648 break; 1649 1650 case CP_HMODE: 1651 ctl_putuint(peer_var[CP_HMODE].text, peer->hmode); 1652 break; 1653 1654 case CP_STRATUM: 1655 ctl_putuint(peer_var[CP_STRATUM].text, peer->stratum); 1656 break; 1657 1658 case CP_PPOLL: 1659 ctl_putuint(peer_var[CP_PPOLL].text, peer->ppoll); 1660 break; 1661 1662 case CP_HPOLL: 1663 ctl_putuint(peer_var[CP_HPOLL].text, peer->hpoll); 1664 break; 1665 1666 case CP_PRECISION: 1667 ctl_putint(peer_var[CP_PRECISION].text, 1668 peer->precision); 1669 break; 1670 1671 case CP_ROOTDELAY: 1672 ctl_putdbl(peer_var[CP_ROOTDELAY].text, 1673 peer->rootdelay * 1e3); 1674 break; 1675 1676 case CP_ROOTDISPERSION: 1677 ctl_putdbl(peer_var[CP_ROOTDISPERSION].text, 1678 peer->rootdisp * 1e3); 1679 break; 1680 1681 case CP_REFID: 1682 if (peer->flags & FLAG_REFCLOCK) { 1683 ctl_putid(peer_var[CP_REFID].text, 1684 (char *)&peer->refid); 1685 } else { 1686 if (peer->stratum > 1 && peer->stratum < 1687 STRATUM_UNSPEC) 1688 ctl_putadr(peer_var[CP_REFID].text, 1689 peer->refid, NULL); 1690 else 1691 ctl_putid(peer_var[CP_REFID].text, 1692 (char *)&peer->refid); 1693 } 1694 break; 1695 1696 case CP_REFTIME: 1697 ctl_putts(peer_var[CP_REFTIME].text, &peer->reftime); 1698 break; 1699 1700 case CP_ORG: 1701 ctl_putts(peer_var[CP_ORG].text, &peer->aorg); 1702 break; 1703 1704 case CP_REC: 1705 ctl_putts(peer_var[CP_REC].text, &peer->dst); 1706 break; 1707 1708 case CP_XMT: 1709 if (peer->xleave != 0) 1710 ctl_putdbl(peer_var[CP_XMT].text, peer->xleave * 1711 1e3); 1712 break; 1713 1714 case CP_BIAS: 1715 if (peer->bias != 0) 1716 ctl_putdbl(peer_var[CP_BIAS].text, peer->bias * 1717 1e3); 1718 break; 1719 1720 case CP_REACH: 1721 ctl_puthex(peer_var[CP_REACH].text, peer->reach); 1722 break; 1723 1724 case CP_FLASH: 1725 temp = peer->flash; 1726 ctl_puthex(peer_var[CP_FLASH].text, temp); 1727 break; 1728 1729 case CP_TTL: 1730 if (peer->ttl > 0) 1731 ctl_putint(peer_var[CP_TTL].text, 1732 sys_ttl[peer->ttl]); 1733 break; 1734 1735 case CP_UNREACH: 1736 ctl_putuint(peer_var[CP_UNREACH].text, peer->unreach); 1737 break; 1738 1739 case CP_TIMER: 1740 ctl_putuint(peer_var[CP_TIMER].text, 1741 peer->nextdate - current_time); 1742 break; 1743 1744 case CP_DELAY: 1745 ctl_putdbl(peer_var[CP_DELAY].text, peer->delay * 1e3); 1746 break; 1747 1748 case CP_OFFSET: 1749 ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset * 1750 1e3); 1751 break; 1752 1753 case CP_JITTER: 1754 ctl_putdbl(peer_var[CP_JITTER].text, peer->jitter * 1755 1e3); 1756 break; 1757 1758 case CP_DISPERSION: 1759 ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp * 1760 1e3); 1761 break; 1762 1763 case CP_KEYID: 1764 if (peer->keyid > NTP_MAXKEY) 1765 ctl_puthex(peer_var[CP_KEYID].text, 1766 peer->keyid); 1767 else 1768 ctl_putuint(peer_var[CP_KEYID].text, 1769 peer->keyid); 1770 break; 1771 1772 case CP_FILTDELAY: 1773 ctl_putarray(peer_var[CP_FILTDELAY].text, 1774 peer->filter_delay, (int)peer->filter_nextpt); 1775 break; 1776 1777 case CP_FILTOFFSET: 1778 ctl_putarray(peer_var[CP_FILTOFFSET].text, 1779 peer->filter_offset, (int)peer->filter_nextpt); 1780 break; 1781 1782 case CP_FILTERROR: 1783 ctl_putarray(peer_var[CP_FILTERROR].text, 1784 peer->filter_disp, (int)peer->filter_nextpt); 1785 break; 1786 1787 case CP_PMODE: 1788 ctl_putuint(peer_var[CP_PMODE].text, peer->pmode); 1789 break; 1790 1791 case CP_RECEIVED: 1792 ctl_putuint(peer_var[CP_RECEIVED].text, peer->received); 1793 break; 1794 1795 case CP_SENT: 1796 ctl_putuint(peer_var[CP_SENT].text, peer->sent); 1797 break; 1798 1799 case CP_VARLIST: 1800 { 1801 char buf[CTL_MAX_DATA_LEN]; 1802 register char *s, *t, *be; 1803 register int i; 1804 register struct ctl_var *k; 1805 1806 s = buf; 1807 be = buf + sizeof(buf); 1808 if (s + strlen(peer_var[CP_VARLIST].text) + 4 > be) 1809 break; /* really long var name */ 1810 1811 snprintf(s, sizeof(buf), "%s=\"", 1812 peer_var[CP_VARLIST].text); 1813 s += strlen(s); 1814 t = s; 1815 for (k = peer_var; !(k->flags & EOV); k++) { 1816 if (k->flags & PADDING) 1817 continue; 1818 1819 i = strlen(k->text); 1820 if (s + i + 1 >= be) 1821 break; 1822 1823 if (s != t) 1824 *s++ = ','; 1825 memcpy(s, k->text, i); 1826 s += i; 1827 } 1828 if (s+2 >= be) 1829 break; 1830 1831 *s++ = '"'; 1832 *s = '\0'; 1833 ctl_putdata(buf, (unsigned)(s - buf), 0); 1834 } 1835 break; 1836 #ifdef OPENSSL 1837 case CP_FLAGS: 1838 if (peer->crypto) 1839 ctl_puthex(peer_var[CP_FLAGS].text, peer->crypto); 1840 break; 1841 1842 case CP_SIGNATURE: 1843 if (peer->crypto) { 1844 const EVP_MD *dp; 1845 1846 dp = EVP_get_digestbynid(peer->crypto >> 16); 1847 strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp))); 1848 ctl_putstr(peer_var[CP_SIGNATURE].text, str, 1849 strlen(str)); 1850 } 1851 break; 1852 1853 case CP_HOST: 1854 if (peer->subject != NULL) 1855 ctl_putstr(peer_var[CP_HOST].text, 1856 peer->subject, strlen(peer->subject)); 1857 break; 1858 1859 case CP_VALID: /* not used */ 1860 break; 1861 1862 case CP_INITSEQ: 1863 if ((ap = (struct autokey *)peer->recval.ptr) == NULL) 1864 break; 1865 1866 ctl_putint(peer_var[CP_INITSEQ].text, ap->seq); 1867 ctl_puthex(peer_var[CP_INITKEY].text, ap->key); 1868 ctl_putfs(peer_var[CP_INITTSP].text, 1869 ntohl(peer->recval.tstamp)); 1870 break; 1871 #endif /* OPENSSL */ 1872 } 1873 } 1874 1875 1876 #ifdef REFCLOCK 1877 /* 1878 * ctl_putclock - output clock variables 1879 */ 1880 static void 1881 ctl_putclock( 1882 int varid, 1883 struct refclockstat *clock_stat, 1884 int mustput 1885 ) 1886 { 1887 switch(varid) { 1888 1889 case CC_TYPE: 1890 if (mustput || clock_stat->clockdesc == NULL 1891 || *(clock_stat->clockdesc) == '\0') { 1892 ctl_putuint(clock_var[CC_TYPE].text, clock_stat->type); 1893 } 1894 break; 1895 case CC_TIMECODE: 1896 ctl_putstr(clock_var[CC_TIMECODE].text, 1897 clock_stat->p_lastcode, 1898 (unsigned)clock_stat->lencode); 1899 break; 1900 1901 case CC_POLL: 1902 ctl_putuint(clock_var[CC_POLL].text, clock_stat->polls); 1903 break; 1904 1905 case CC_NOREPLY: 1906 ctl_putuint(clock_var[CC_NOREPLY].text, 1907 clock_stat->noresponse); 1908 break; 1909 1910 case CC_BADFORMAT: 1911 ctl_putuint(clock_var[CC_BADFORMAT].text, 1912 clock_stat->badformat); 1913 break; 1914 1915 case CC_BADDATA: 1916 ctl_putuint(clock_var[CC_BADDATA].text, 1917 clock_stat->baddata); 1918 break; 1919 1920 case CC_FUDGETIME1: 1921 if (mustput || (clock_stat->haveflags & CLK_HAVETIME1)) 1922 ctl_putdbl(clock_var[CC_FUDGETIME1].text, 1923 clock_stat->fudgetime1 * 1e3); 1924 break; 1925 1926 case CC_FUDGETIME2: 1927 if (mustput || (clock_stat->haveflags & CLK_HAVETIME2)) ctl_putdbl(clock_var[CC_FUDGETIME2].text, 1928 clock_stat->fudgetime2 * 1e3); 1929 break; 1930 1931 case CC_FUDGEVAL1: 1932 if (mustput || (clock_stat->haveflags & CLK_HAVEVAL1)) 1933 ctl_putint(clock_var[CC_FUDGEVAL1].text, 1934 clock_stat->fudgeval1); 1935 break; 1936 1937 case CC_FUDGEVAL2: 1938 if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) { 1939 if (clock_stat->fudgeval1 > 1) 1940 ctl_putadr(clock_var[CC_FUDGEVAL2].text, 1941 (u_int32)clock_stat->fudgeval2, NULL); 1942 else 1943 ctl_putid(clock_var[CC_FUDGEVAL2].text, 1944 (char *)&clock_stat->fudgeval2); 1945 } 1946 break; 1947 1948 case CC_FLAGS: 1949 if (mustput || (clock_stat->haveflags & (CLK_HAVEFLAG1 | 1950 CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4))) 1951 ctl_putuint(clock_var[CC_FLAGS].text, 1952 clock_stat->flags); 1953 break; 1954 1955 case CC_DEVICE: 1956 if (clock_stat->clockdesc == NULL || 1957 *(clock_stat->clockdesc) == '\0') { 1958 if (mustput) 1959 ctl_putstr(clock_var[CC_DEVICE].text, 1960 "", 0); 1961 } else { 1962 ctl_putstr(clock_var[CC_DEVICE].text, 1963 clock_stat->clockdesc, 1964 strlen(clock_stat->clockdesc)); 1965 } 1966 break; 1967 1968 case CC_VARLIST: 1969 { 1970 char buf[CTL_MAX_DATA_LEN]; 1971 register char *s, *t, *be; 1972 register const char *ss; 1973 register int i; 1974 register struct ctl_var *k; 1975 1976 s = buf; 1977 be = buf + sizeof(buf); 1978 if (s + strlen(clock_var[CC_VARLIST].text) + 4 > 1979 be) 1980 break; /* really long var name */ 1981 1982 snprintf(s, sizeof(buf), "%s=\"", 1983 clock_var[CC_VARLIST].text); 1984 s += strlen(s); 1985 t = s; 1986 1987 for (k = clock_var; !(k->flags & EOV); k++) { 1988 if (k->flags & PADDING) 1989 continue; 1990 1991 i = strlen(k->text); 1992 if (s + i + 1 >= be) 1993 break; 1994 1995 if (s != t) 1996 *s++ = ','; 1997 memcpy(s, k->text, i); 1998 s += i; 1999 } 2000 2001 for (k = clock_stat->kv_list; k && !(k->flags & 2002 EOV); k++) { 2003 if (k->flags & PADDING) 2004 continue; 2005 2006 ss = k->text; 2007 if (!ss) 2008 continue; 2009 2010 while (*ss && *ss != '=') 2011 ss++; 2012 i = ss - k->text; 2013 if (s+i+1 >= be) 2014 break; 2015 2016 if (s != t) 2017 *s++ = ','; 2018 memcpy(s, k->text, (unsigned)i); 2019 s += i; 2020 *s = '\0'; 2021 } 2022 if (s+2 >= be) 2023 break; 2024 2025 *s++ = '"'; 2026 *s = '\0'; 2027 ctl_putdata(buf, (unsigned)( s - buf ), 0); 2028 } 2029 break; 2030 } 2031 } 2032 #endif 2033 2034 2035 2036 /* 2037 * ctl_getitem - get the next data item from the incoming packet 2038 */ 2039 static struct ctl_var * 2040 ctl_getitem( 2041 struct ctl_var *var_list, 2042 char **data 2043 ) 2044 { 2045 register struct ctl_var *v; 2046 register char *cp, *dp; 2047 register const char *tp; 2048 static struct ctl_var eol = { 0, EOV, NULL }; 2049 static char buf[128]; 2050 2051 /* 2052 * Delete leading commas and white space 2053 */ 2054 while (reqpt < reqend && (*reqpt == ',' || 2055 isspace((unsigned char)*reqpt))) 2056 reqpt++; 2057 if (reqpt >= reqend) 2058 return (0); 2059 2060 if (var_list == (struct ctl_var *)0) 2061 return (&eol); 2062 2063 /* 2064 * Look for a first character match on the tag. If we find 2065 * one, see if it is a full match. 2066 */ 2067 v = var_list; 2068 cp = reqpt; 2069 while (!(v->flags & EOV)) { 2070 if (!(v->flags & PADDING) && *cp == *(v->text)) { 2071 tp = v->text; 2072 while (*tp != '\0' && *tp != '=' && cp < 2073 reqend && *cp == *tp) { 2074 cp++; 2075 tp++; 2076 } 2077 if ((*tp == '\0') || (*tp == '=')) { 2078 while (cp < reqend && isspace((unsigned char)*cp)) 2079 cp++; 2080 if (cp == reqend || *cp == ',') { 2081 buf[0] = '\0'; 2082 *data = buf; 2083 if (cp < reqend) 2084 cp++; 2085 reqpt = cp; 2086 return v; 2087 } 2088 if (*cp == '=') { 2089 cp++; 2090 dp = buf; 2091 while (cp < reqend && isspace((unsigned char)*cp)) 2092 cp++; 2093 while (cp < reqend && *cp != ',') { 2094 *dp++ = *cp++; 2095 if (dp >= buf + sizeof(buf)) { 2096 ctl_error(CERR_BADFMT); 2097 numctlbadpkts++; 2098 #if 0 /* Avoid possible DOS attack */ 2099 /* If we get a smarter msyslog we can re-enable this */ 2100 msyslog(LOG_WARNING, 2101 "Possible 'ntpdx' exploit from %s:%d (possibly spoofed)\n", 2102 stoa(rmt_addr), SRCPORT(rmt_addr) 2103 ); 2104 #endif 2105 return (0); 2106 } 2107 } 2108 if (cp < reqend) 2109 cp++; 2110 *dp-- = '\0'; 2111 while (dp >= buf) { 2112 if (!isspace((unsigned int)(*dp))) 2113 break; 2114 *dp-- = '\0'; 2115 } 2116 reqpt = cp; 2117 *data = buf; 2118 return (v); 2119 } 2120 } 2121 cp = reqpt; 2122 } 2123 v++; 2124 } 2125 return v; 2126 } 2127 2128 2129 /* 2130 * control_unspec - response to an unspecified op-code 2131 */ 2132 /*ARGSUSED*/ 2133 static void 2134 control_unspec( 2135 struct recvbuf *rbufp, 2136 int restrict_mask 2137 ) 2138 { 2139 struct peer *peer; 2140 2141 /* 2142 * What is an appropriate response to an unspecified op-code? 2143 * I return no errors and no data, unless a specified assocation 2144 * doesn't exist. 2145 */ 2146 if (res_associd != 0) { 2147 if ((peer = findpeerbyassoc(res_associd)) == 0) { 2148 ctl_error(CERR_BADASSOC); 2149 return; 2150 } 2151 rpkt.status = htons(ctlpeerstatus(peer)); 2152 } else { 2153 rpkt.status = htons(ctlsysstatus()); 2154 } 2155 ctl_flushpkt(0); 2156 } 2157 2158 2159 /* 2160 * read_status - return either a list of associd's, or a particular 2161 * peer's status. 2162 */ 2163 /*ARGSUSED*/ 2164 static void 2165 read_status( 2166 struct recvbuf *rbufp, 2167 int restrict_mask 2168 ) 2169 { 2170 register int i; 2171 register struct peer *peer; 2172 u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)]; 2173 2174 #ifdef DEBUG 2175 if (debug > 2) 2176 printf("read_status: ID %d\n", res_associd); 2177 #endif 2178 /* 2179 * Two choices here. If the specified association ID is 2180 * zero we return all known assocation ID's. Otherwise 2181 * we return a bunch of stuff about the particular peer. 2182 */ 2183 if (res_associd == 0) { 2184 register int n; 2185 2186 n = 0; 2187 rpkt.status = htons(ctlsysstatus()); 2188 for (i = 0; i < NTP_HASH_SIZE; i++) { 2189 for (peer = assoc_hash[i]; peer != 0; 2190 peer = peer->ass_next) { 2191 ass_stat[n++] = htons(peer->associd); 2192 ass_stat[n++] = 2193 htons(ctlpeerstatus(peer)); 2194 if (n == 2195 CTL_MAX_DATA_LEN/sizeof(u_short)) { 2196 ctl_putdata((char *)ass_stat, 2197 n * sizeof(u_short), 1); 2198 n = 0; 2199 } 2200 } 2201 } 2202 2203 if (n != 0) 2204 ctl_putdata((char *)ass_stat, n * 2205 sizeof(u_short), 1); 2206 ctl_flushpkt(0); 2207 } else { 2208 peer = findpeerbyassoc(res_associd); 2209 if (peer == 0) { 2210 ctl_error(CERR_BADASSOC); 2211 } else { 2212 register u_char *cp; 2213 2214 rpkt.status = htons(ctlpeerstatus(peer)); 2215 if (res_authokay) 2216 peer->num_events = 0; 2217 /* 2218 * For now, output everything we know about the 2219 * peer. May be more selective later. 2220 */ 2221 for (cp = def_peer_var; *cp != 0; cp++) 2222 ctl_putpeer((int)*cp, peer); 2223 ctl_flushpkt(0); 2224 } 2225 } 2226 } 2227 2228 2229 /* 2230 * read_variables - return the variables the caller asks for 2231 */ 2232 /*ARGSUSED*/ 2233 static void 2234 read_variables( 2235 struct recvbuf *rbufp, 2236 int restrict_mask 2237 ) 2238 { 2239 register struct ctl_var *v; 2240 register int i; 2241 char *valuep; 2242 u_char *wants; 2243 unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE + 2244 1) : (CP_MAXCODE + 1); 2245 if (res_associd == 0) { 2246 /* 2247 * Wants system variables. Figure out which he wants 2248 * and give them to him. 2249 */ 2250 rpkt.status = htons(ctlsysstatus()); 2251 if (res_authokay) 2252 ctl_sys_num_events = 0; 2253 gotvar += count_var(ext_sys_var); 2254 wants = (u_char *)emalloc(gotvar); 2255 memset((char *)wants, 0, gotvar); 2256 gotvar = 0; 2257 while ((v = ctl_getitem(sys_var, &valuep)) != 0) { 2258 if (v->flags & EOV) { 2259 if ((v = ctl_getitem(ext_sys_var, 2260 &valuep)) != 0) { 2261 if (v->flags & EOV) { 2262 ctl_error(CERR_UNKNOWNVAR); 2263 free((char *)wants); 2264 return; 2265 } 2266 wants[CS_MAXCODE + 1 + 2267 v->code] = 1; 2268 gotvar = 1; 2269 continue; 2270 } else { 2271 break; /* shouldn't happen ! */ 2272 } 2273 } 2274 wants[v->code] = 1; 2275 gotvar = 1; 2276 } 2277 if (gotvar) { 2278 for (i = 1; i <= CS_MAXCODE; i++) 2279 if (wants[i]) 2280 ctl_putsys(i); 2281 for (i = 0; ext_sys_var && 2282 !(ext_sys_var[i].flags & EOV); i++) 2283 if (wants[i + CS_MAXCODE + 1]) 2284 ctl_putdata(ext_sys_var[i].text, 2285 strlen(ext_sys_var[i].text), 2286 0); 2287 } else { 2288 register u_char *cs; 2289 register struct ctl_var *kv; 2290 2291 for (cs = def_sys_var; *cs != 0; cs++) 2292 ctl_putsys((int)*cs); 2293 for (kv = ext_sys_var; kv && !(kv->flags & EOV); 2294 kv++) 2295 if (kv->flags & DEF) 2296 ctl_putdata(kv->text, 2297 strlen(kv->text), 0); 2298 } 2299 free((char *)wants); 2300 } else { 2301 register struct peer *peer; 2302 2303 /* 2304 * Wants info for a particular peer. See if we know 2305 * the guy. 2306 */ 2307 peer = findpeerbyassoc(res_associd); 2308 if (peer == 0) { 2309 ctl_error(CERR_BADASSOC); 2310 return; 2311 } 2312 rpkt.status = htons(ctlpeerstatus(peer)); 2313 if (res_authokay) 2314 peer->num_events = 0; 2315 wants = (u_char *)emalloc(gotvar); 2316 memset((char*)wants, 0, gotvar); 2317 gotvar = 0; 2318 while ((v = ctl_getitem(peer_var, &valuep)) != 0) { 2319 if (v->flags & EOV) { 2320 ctl_error(CERR_UNKNOWNVAR); 2321 free((char *)wants); 2322 return; 2323 } 2324 wants[v->code] = 1; 2325 gotvar = 1; 2326 } 2327 if (gotvar) { 2328 for (i = 1; i <= CP_MAXCODE; i++) 2329 if (wants[i]) 2330 ctl_putpeer(i, peer); 2331 } else { 2332 register u_char *cp; 2333 2334 for (cp = def_peer_var; *cp != 0; cp++) 2335 ctl_putpeer((int)*cp, peer); 2336 } 2337 free((char *)wants); 2338 } 2339 ctl_flushpkt(0); 2340 } 2341 2342 2343 /* 2344 * write_variables - write into variables. We only allow leap bit 2345 * writing this way. 2346 */ 2347 /*ARGSUSED*/ 2348 static void 2349 write_variables( 2350 struct recvbuf *rbufp, 2351 int restrict_mask 2352 ) 2353 { 2354 register struct ctl_var *v; 2355 register int ext_var; 2356 char *valuep; 2357 long val = 0; 2358 2359 /* 2360 * If he's trying to write into a peer tell him no way 2361 */ 2362 if (res_associd != 0) { 2363 ctl_error(CERR_PERMISSION); 2364 return; 2365 } 2366 2367 /* 2368 * Set status 2369 */ 2370 rpkt.status = htons(ctlsysstatus()); 2371 2372 /* 2373 * Look through the variables. Dump out at the first sign of 2374 * trouble. 2375 */ 2376 while ((v = ctl_getitem(sys_var, &valuep)) != 0) { 2377 ext_var = 0; 2378 if (v->flags & EOV) { 2379 if ((v = ctl_getitem(ext_sys_var, &valuep)) != 2380 0) { 2381 if (v->flags & EOV) { 2382 ctl_error(CERR_UNKNOWNVAR); 2383 return; 2384 } 2385 ext_var = 1; 2386 } else { 2387 break; 2388 } 2389 } 2390 if (!(v->flags & CAN_WRITE)) { 2391 ctl_error(CERR_PERMISSION); 2392 return; 2393 } 2394 if (!ext_var && (*valuep == '\0' || !atoint(valuep, 2395 &val))) { 2396 ctl_error(CERR_BADFMT); 2397 return; 2398 } 2399 if (!ext_var && (val & ~LEAP_NOTINSYNC) != 0) { 2400 ctl_error(CERR_BADVALUE); 2401 return; 2402 } 2403 2404 if (ext_var) { 2405 char *s = (char *)emalloc(strlen(v->text) + 2406 strlen(valuep) + 2); 2407 const char *t; 2408 char *tt = s; 2409 2410 t = v->text; 2411 while (*t && *t != '=') 2412 *tt++ = *t++; 2413 2414 *tt++ = '='; 2415 strcat(tt, valuep); 2416 set_sys_var(s, strlen(s)+1, v->flags); 2417 free(s); 2418 } else { 2419 /* 2420 * This one seems sane. Save it. 2421 */ 2422 switch(v->code) { 2423 2424 case CS_LEAP: 2425 default: 2426 ctl_error(CERR_UNSPEC); /* really */ 2427 return; 2428 } 2429 } 2430 } 2431 2432 /* 2433 * If we got anything, do it. xxx nothing to do *** 2434 */ 2435 /* 2436 if (leapind != ~0 || leapwarn != ~0) { 2437 if (!leap_setleap((int)leapind, (int)leapwarn)) { 2438 ctl_error(CERR_PERMISSION); 2439 return; 2440 } 2441 } 2442 */ 2443 ctl_flushpkt(0); 2444 } 2445 2446 /* 2447 * configure() processes ntpq :config/config-from-file, allowing 2448 * generic runtime reconfiguration. 2449 */ 2450 static void configure( 2451 struct recvbuf *rbufp, 2452 int restrict_mask 2453 ) 2454 { 2455 int data_count, retval, replace_nl; 2456 2457 /* I haven't yet implemented changes to an existing association. 2458 * Hence check if the association id is 0 2459 */ 2460 if (res_associd != 0) { 2461 ctl_error(CERR_BADVALUE); 2462 return; 2463 } 2464 2465 if (restrict_mask & RES_NOMODIFY) { 2466 snprintf(remote_config.err_msg, 2467 sizeof(remote_config.err_msg), 2468 "runtime configuration prohibited by restrict ... nomodify"); 2469 ctl_putdata(remote_config.err_msg, 2470 strlen(remote_config.err_msg), 0); 2471 ctl_flushpkt(0); 2472 msyslog(LOG_NOTICE, 2473 "runtime config from %s rejected due to nomodify restriction", 2474 stoa(&rbufp->recv_srcadr)); 2475 return; 2476 } 2477 2478 /* Initialize the remote config buffer */ 2479 data_count = reqend - reqpt; 2480 memcpy(remote_config.buffer, reqpt, data_count); 2481 if (data_count > 0 2482 && '\n' != remote_config.buffer[data_count - 1]) 2483 remote_config.buffer[data_count++] = '\n'; 2484 remote_config.buffer[data_count] = '\0'; 2485 remote_config.pos = 0; 2486 remote_config.err_pos = 0; 2487 remote_config.no_errors = 0; 2488 2489 /* do not include terminating newline in log */ 2490 if (data_count > 0 2491 && '\n' == remote_config.buffer[data_count - 1]) { 2492 remote_config.buffer[data_count - 1] = '\0'; 2493 replace_nl = 1; 2494 } else 2495 replace_nl = 0; 2496 2497 DPRINTF(1, ("Got Remote Configuration Command: %s\n", 2498 remote_config.buffer)); 2499 msyslog(LOG_NOTICE, "%s config: %s", 2500 stoa(&rbufp->recv_srcadr), 2501 remote_config.buffer); 2502 2503 if (replace_nl) 2504 remote_config.buffer[data_count - 1] = '\n'; 2505 2506 config_remotely(&rbufp->recv_srcadr); 2507 2508 /* 2509 * Check if errors were reported. If not, output 'Config 2510 * Succeeded'. Else output the error count. It would be nice 2511 * to output any parser error messages. 2512 */ 2513 if (0 == remote_config.no_errors) { 2514 retval = snprintf(remote_config.err_msg, 2515 sizeof(remote_config.err_msg), 2516 "Config Succeeded"); 2517 if (retval > 0) 2518 remote_config.err_pos += retval; 2519 } 2520 2521 ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0); 2522 ctl_flushpkt(0); 2523 2524 DPRINTF(1, ("Reply: %s\n", remote_config.err_msg)); 2525 2526 if (remote_config.no_errors > 0) 2527 msyslog(LOG_NOTICE, "%d error in %s config", 2528 remote_config.no_errors, 2529 stoa(&rbufp->recv_srcadr)); 2530 } 2531 2532 2533 /* 2534 * read_clock_status - return clock radio status 2535 */ 2536 /*ARGSUSED*/ 2537 static void 2538 read_clock_status( 2539 struct recvbuf *rbufp, 2540 int restrict_mask 2541 ) 2542 { 2543 #ifndef REFCLOCK 2544 /* 2545 * If no refclock support, no data to return 2546 */ 2547 ctl_error(CERR_BADASSOC); 2548 #else 2549 register struct ctl_var *v; 2550 register int i; 2551 register struct peer *peer; 2552 char *valuep; 2553 u_char *wants; 2554 unsigned int gotvar; 2555 struct refclockstat clock_stat; 2556 2557 if (res_associd == 0) { 2558 2559 /* 2560 * Find a clock for this jerk. If the system peer 2561 * is a clock use it, else search the hash tables 2562 * for one. 2563 */ 2564 if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK)) 2565 { 2566 peer = sys_peer; 2567 } else { 2568 peer = 0; 2569 for (i = 0; peer == 0 && i < NTP_HASH_SIZE; i++) { 2570 for (peer = assoc_hash[i]; peer != 0; 2571 peer = peer->ass_next) { 2572 if (peer->flags & FLAG_REFCLOCK) 2573 break; 2574 } 2575 } 2576 if (peer == 0) { 2577 ctl_error(CERR_BADASSOC); 2578 return; 2579 } 2580 } 2581 } else { 2582 peer = findpeerbyassoc(res_associd); 2583 if (peer == 0 || !(peer->flags & FLAG_REFCLOCK)) { 2584 ctl_error(CERR_BADASSOC); 2585 return; 2586 } 2587 } 2588 2589 /* 2590 * If we got here we have a peer which is a clock. Get his 2591 * status. 2592 */ 2593 clock_stat.kv_list = (struct ctl_var *)0; 2594 refclock_control(&peer->srcadr, (struct refclockstat *)0, 2595 &clock_stat); 2596 2597 /* 2598 * Look for variables in the packet. 2599 */ 2600 rpkt.status = htons(ctlclkstatus(&clock_stat)); 2601 gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list); 2602 wants = (u_char *)emalloc(gotvar); 2603 memset((char*)wants, 0, gotvar); 2604 gotvar = 0; 2605 while ((v = ctl_getitem(clock_var, &valuep)) != 0) { 2606 if (v->flags & EOV) { 2607 if ((v = ctl_getitem(clock_stat.kv_list, 2608 &valuep)) != 0) { 2609 if (v->flags & EOV) { 2610 ctl_error(CERR_UNKNOWNVAR); 2611 free((char*)wants); 2612 free_varlist(clock_stat.kv_list); 2613 return; 2614 } 2615 wants[CC_MAXCODE + 1 + v->code] = 1; 2616 gotvar = 1; 2617 continue; 2618 } else { 2619 break; /* shouldn't happen ! */ 2620 } 2621 } 2622 wants[v->code] = 1; 2623 gotvar = 1; 2624 } 2625 2626 if (gotvar) { 2627 for (i = 1; i <= CC_MAXCODE; i++) 2628 if (wants[i]) 2629 ctl_putclock(i, &clock_stat, 1); 2630 for (i = 0; clock_stat.kv_list && 2631 !(clock_stat.kv_list[i].flags & EOV); i++) 2632 if (wants[i + CC_MAXCODE + 1]) 2633 ctl_putdata(clock_stat.kv_list[i].text, 2634 strlen(clock_stat.kv_list[i].text), 2635 0); 2636 } else { 2637 register u_char *cc; 2638 register struct ctl_var *kv; 2639 2640 for (cc = def_clock_var; *cc != 0; cc++) 2641 ctl_putclock((int)*cc, &clock_stat, 0); 2642 for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); 2643 kv++) 2644 if (kv->flags & DEF) 2645 ctl_putdata(kv->text, strlen(kv->text), 2646 0); 2647 } 2648 2649 free((char*)wants); 2650 free_varlist(clock_stat.kv_list); 2651 2652 ctl_flushpkt(0); 2653 #endif 2654 } 2655 2656 2657 /* 2658 * write_clock_status - we don't do this 2659 */ 2660 /*ARGSUSED*/ 2661 static void 2662 write_clock_status( 2663 struct recvbuf *rbufp, 2664 int restrict_mask 2665 ) 2666 { 2667 ctl_error(CERR_PERMISSION); 2668 } 2669 2670 /* 2671 * Trap support from here on down. We send async trap messages when the 2672 * upper levels report trouble. Traps can by set either by control 2673 * messages or by configuration. 2674 */ 2675 /* 2676 * set_trap - set a trap in response to a control message 2677 */ 2678 static void 2679 set_trap( 2680 struct recvbuf *rbufp, 2681 int restrict_mask 2682 ) 2683 { 2684 int traptype; 2685 2686 /* 2687 * See if this guy is allowed 2688 */ 2689 if (restrict_mask & RES_NOTRAP) { 2690 ctl_error(CERR_PERMISSION); 2691 return; 2692 } 2693 2694 /* 2695 * Determine his allowed trap type. 2696 */ 2697 traptype = TRAP_TYPE_PRIO; 2698 if (restrict_mask & RES_LPTRAP) 2699 traptype = TRAP_TYPE_NONPRIO; 2700 2701 /* 2702 * Call ctlsettrap() to do the work. Return 2703 * an error if it can't assign the trap. 2704 */ 2705 if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype, 2706 (int)res_version)) 2707 ctl_error(CERR_NORESOURCE); 2708 ctl_flushpkt(0); 2709 } 2710 2711 2712 /* 2713 * unset_trap - unset a trap in response to a control message 2714 */ 2715 static void 2716 unset_trap( 2717 struct recvbuf *rbufp, 2718 int restrict_mask 2719 ) 2720 { 2721 int traptype; 2722 2723 /* 2724 * We don't prevent anyone from removing his own trap unless the 2725 * trap is configured. Note we also must be aware of the 2726 * possibility that restriction flags were changed since this 2727 * guy last set his trap. Set the trap type based on this. 2728 */ 2729 traptype = TRAP_TYPE_PRIO; 2730 if (restrict_mask & RES_LPTRAP) 2731 traptype = TRAP_TYPE_NONPRIO; 2732 2733 /* 2734 * Call ctlclrtrap() to clear this out. 2735 */ 2736 if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype)) 2737 ctl_error(CERR_BADASSOC); 2738 ctl_flushpkt(0); 2739 } 2740 2741 2742 /* 2743 * ctlsettrap - called to set a trap 2744 */ 2745 int 2746 ctlsettrap( 2747 sockaddr_u *raddr, 2748 struct interface *linter, 2749 int traptype, 2750 int version 2751 ) 2752 { 2753 register struct ctl_trap *tp; 2754 register struct ctl_trap *tptouse; 2755 2756 /* 2757 * See if we can find this trap. If so, we only need update 2758 * the flags and the time. 2759 */ 2760 if ((tp = ctlfindtrap(raddr, linter)) != NULL) { 2761 switch (traptype) { 2762 2763 case TRAP_TYPE_CONFIG: 2764 tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED; 2765 break; 2766 2767 case TRAP_TYPE_PRIO: 2768 if (tp->tr_flags & TRAP_CONFIGURED) 2769 return (1); /* don't change anything */ 2770 tp->tr_flags = TRAP_INUSE; 2771 break; 2772 2773 case TRAP_TYPE_NONPRIO: 2774 if (tp->tr_flags & TRAP_CONFIGURED) 2775 return (1); /* don't change anything */ 2776 tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO; 2777 break; 2778 } 2779 tp->tr_settime = current_time; 2780 tp->tr_resets++; 2781 return (1); 2782 } 2783 2784 /* 2785 * First we heard of this guy. Try to find a trap structure 2786 * for him to use, clearing out lesser priority guys if we 2787 * have to. Clear out anyone who's expired while we're at it. 2788 */ 2789 tptouse = NULL; 2790 for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) { 2791 if ((tp->tr_flags & TRAP_INUSE) && 2792 !(tp->tr_flags & TRAP_CONFIGURED) && 2793 ((tp->tr_settime + CTL_TRAPTIME) > current_time)) { 2794 tp->tr_flags = 0; 2795 num_ctl_traps--; 2796 } 2797 if (!(tp->tr_flags & TRAP_INUSE)) { 2798 tptouse = tp; 2799 } else if (!(tp->tr_flags & TRAP_CONFIGURED)) { 2800 switch (traptype) { 2801 2802 case TRAP_TYPE_CONFIG: 2803 if (tptouse == NULL) { 2804 tptouse = tp; 2805 break; 2806 } 2807 if (tptouse->tr_flags & TRAP_NONPRIO && 2808 !(tp->tr_flags & TRAP_NONPRIO)) 2809 break; 2810 2811 if (!(tptouse->tr_flags & TRAP_NONPRIO) 2812 && tp->tr_flags & TRAP_NONPRIO) { 2813 tptouse = tp; 2814 break; 2815 } 2816 if (tptouse->tr_origtime < 2817 tp->tr_origtime) 2818 tptouse = tp; 2819 break; 2820 2821 case TRAP_TYPE_PRIO: 2822 if (tp->tr_flags & TRAP_NONPRIO) { 2823 if (tptouse == NULL || 2824 (tptouse->tr_flags & 2825 TRAP_INUSE && 2826 tptouse->tr_origtime < 2827 tp->tr_origtime)) 2828 tptouse = tp; 2829 } 2830 break; 2831 2832 case TRAP_TYPE_NONPRIO: 2833 break; 2834 } 2835 } 2836 } 2837 2838 /* 2839 * If we don't have room for him return an error. 2840 */ 2841 if (tptouse == NULL) 2842 return (0); 2843 2844 /* 2845 * Set up this structure for him. 2846 */ 2847 tptouse->tr_settime = tptouse->tr_origtime = current_time; 2848 tptouse->tr_count = tptouse->tr_resets = 0; 2849 tptouse->tr_sequence = 1; 2850 tptouse->tr_addr = *raddr; 2851 tptouse->tr_localaddr = linter; 2852 tptouse->tr_version = (u_char) version; 2853 tptouse->tr_flags = TRAP_INUSE; 2854 if (traptype == TRAP_TYPE_CONFIG) 2855 tptouse->tr_flags |= TRAP_CONFIGURED; 2856 else if (traptype == TRAP_TYPE_NONPRIO) 2857 tptouse->tr_flags |= TRAP_NONPRIO; 2858 num_ctl_traps++; 2859 return (1); 2860 } 2861 2862 2863 /* 2864 * ctlclrtrap - called to clear a trap 2865 */ 2866 int 2867 ctlclrtrap( 2868 sockaddr_u *raddr, 2869 struct interface *linter, 2870 int traptype 2871 ) 2872 { 2873 register struct ctl_trap *tp; 2874 2875 if ((tp = ctlfindtrap(raddr, linter)) == NULL) 2876 return (0); 2877 2878 if (tp->tr_flags & TRAP_CONFIGURED 2879 && traptype != TRAP_TYPE_CONFIG) 2880 return (0); 2881 2882 tp->tr_flags = 0; 2883 num_ctl_traps--; 2884 return (1); 2885 } 2886 2887 2888 /* 2889 * ctlfindtrap - find a trap given the remote and local addresses 2890 */ 2891 static struct ctl_trap * 2892 ctlfindtrap( 2893 sockaddr_u *raddr, 2894 struct interface *linter 2895 ) 2896 { 2897 register struct ctl_trap *tp; 2898 2899 for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) { 2900 if ((tp->tr_flags & TRAP_INUSE) 2901 && (NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr)) 2902 && SOCK_EQ(raddr, &tp->tr_addr) 2903 && (linter == tp->tr_localaddr) ) 2904 return (tp); 2905 } 2906 return (struct ctl_trap *)NULL; 2907 } 2908 2909 2910 /* 2911 * report_event - report an event to the trappers 2912 */ 2913 void 2914 report_event( 2915 int err, /* error code */ 2916 struct peer *peer, /* peer structure pointer */ 2917 const char *str /* protostats string */ 2918 ) 2919 { 2920 char statstr[NTP_MAXSTRLEN]; 2921 int i; 2922 size_t len; 2923 2924 /* 2925 * Report the error to the protostats file, system log and 2926 * trappers. 2927 */ 2928 if (peer == NULL) { 2929 2930 /* 2931 * Discard a system report if the number of reports of 2932 * the same type exceeds the maximum. 2933 */ 2934 if (ctl_sys_last_event != (u_char)err) 2935 ctl_sys_num_events= 0; 2936 if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS) 2937 return; 2938 2939 ctl_sys_last_event = (u_char)err; 2940 ctl_sys_num_events++; 2941 snprintf(statstr, NTP_MAXSTRLEN, 2942 "0.0.0.0 %04x %02x %s", 2943 ctlsysstatus(), err, eventstr(err)); 2944 if (str != NULL) { 2945 len = strlen(statstr); 2946 snprintf(statstr + len, sizeof(statstr) - len, 2947 " %s", str); 2948 } 2949 NLOG(NLOG_SYSEVENT) 2950 msyslog(LOG_INFO, "%s", statstr); 2951 } else { 2952 2953 /* 2954 * Discard a peer report if the number of reports of 2955 * the same type exceeds the maximum for that peer. 2956 */ 2957 char *src; 2958 u_char errlast; 2959 2960 errlast = (u_char)err & ~PEER_EVENT; 2961 if (peer->last_event == errlast) 2962 peer->num_events = 0; 2963 if (peer->num_events >= CTL_PEER_MAXEVENTS) 2964 return; 2965 2966 peer->last_event = errlast; 2967 peer->num_events++; 2968 if (ISREFCLOCKADR(&peer->srcadr)) 2969 src = refnumtoa(&peer->srcadr); 2970 else 2971 src = stoa(&peer->srcadr); 2972 2973 snprintf(statstr, NTP_MAXSTRLEN, 2974 "%s %04x %02x %s", src, 2975 ctlpeerstatus(peer), err, eventstr(err)); 2976 if (str != NULL) { 2977 len = strlen(statstr); 2978 snprintf(statstr + len, sizeof(statstr) - len, 2979 " %s", str); 2980 } 2981 NLOG(NLOG_PEEREVENT) 2982 msyslog(LOG_INFO, "%s", statstr); 2983 } 2984 record_proto_stats(statstr); 2985 #if DEBUG 2986 if (debug) 2987 printf("event at %lu %s\n", current_time, statstr); 2988 #endif 2989 2990 /* 2991 * If no trappers, return. 2992 */ 2993 if (num_ctl_traps <= 0) 2994 return; 2995 2996 /* 2997 * Set up the outgoing packet variables 2998 */ 2999 res_opcode = CTL_OP_ASYNCMSG; 3000 res_offset = 0; 3001 res_async = 1; 3002 res_authenticate = 0; 3003 datapt = rpkt.data; 3004 dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); 3005 if (!(err & PEER_EVENT)) { 3006 rpkt.associd = 0; 3007 rpkt.status = htons(ctlsysstatus()); 3008 3009 /* 3010 * For now, put everything we know about system 3011 * variables. Don't send crypto strings. 3012 */ 3013 for (i = 1; i <= CS_MAXCODE; i++) { 3014 #ifdef OPENSSL 3015 if (i > CS_VARLIST) 3016 continue; 3017 #endif /* OPENSSL */ 3018 ctl_putsys(i); 3019 } 3020 } else { 3021 NTP_INSIST(peer != NULL); 3022 rpkt.associd = htons(peer->associd); 3023 rpkt.status = htons(ctlpeerstatus(peer)); 3024 3025 /* 3026 * Dump it all. Later, maybe less. 3027 */ 3028 for (i = 1; i <= CP_MAXCODE; i++) { 3029 #ifdef OPENSSL 3030 if (i > CP_VARLIST) 3031 continue; 3032 #endif /* OPENSSL */ 3033 ctl_putpeer(i, peer); 3034 } 3035 #ifdef REFCLOCK 3036 /* 3037 * for clock exception events: add clock variables to 3038 * reflect info on exception 3039 */ 3040 if (err == PEVNT_CLOCK) { 3041 struct refclockstat clock_stat; 3042 struct ctl_var *kv; 3043 3044 clock_stat.kv_list = (struct ctl_var *)0; 3045 refclock_control(&peer->srcadr, 3046 (struct refclockstat *)0, &clock_stat); 3047 3048 ctl_puthex("refclockstatus", 3049 ctlclkstatus(&clock_stat)); 3050 3051 for (i = 1; i <= CC_MAXCODE; i++) 3052 ctl_putclock(i, &clock_stat, 0); 3053 for (kv = clock_stat.kv_list; kv && 3054 !(kv->flags & EOV); kv++) 3055 if (kv->flags & DEF) 3056 ctl_putdata(kv->text, 3057 strlen(kv->text), 0); 3058 free_varlist(clock_stat.kv_list); 3059 } 3060 #endif /* REFCLOCK */ 3061 } 3062 3063 /* 3064 * We're done, return. 3065 */ 3066 ctl_flushpkt(0); 3067 } 3068 3069 3070 /* 3071 * ctl_clr_stats - clear stat counters 3072 */ 3073 void 3074 ctl_clr_stats(void) 3075 { 3076 ctltimereset = current_time; 3077 numctlreq = 0; 3078 numctlbadpkts = 0; 3079 numctlresponses = 0; 3080 numctlfrags = 0; 3081 numctlerrors = 0; 3082 numctlfrags = 0; 3083 numctltooshort = 0; 3084 numctlinputresp = 0; 3085 numctlinputfrag = 0; 3086 numctlinputerr = 0; 3087 numctlbadoffset = 0; 3088 numctlbadversion = 0; 3089 numctldatatooshort = 0; 3090 numctlbadop = 0; 3091 numasyncmsgs = 0; 3092 } 3093 3094 static u_long 3095 count_var( 3096 struct ctl_var *k 3097 ) 3098 { 3099 register u_long c; 3100 3101 if (!k) 3102 return (0); 3103 3104 c = 0; 3105 while (!(k++->flags & EOV)) 3106 c++; 3107 return (c); 3108 } 3109 3110 char * 3111 add_var( 3112 struct ctl_var **kv, 3113 u_long size, 3114 u_short def 3115 ) 3116 { 3117 register u_long c; 3118 register struct ctl_var *k; 3119 3120 c = count_var(*kv); 3121 3122 k = *kv; 3123 *kv = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var)); 3124 if (k) { 3125 memmove((char *)*kv, (char *)k, 3126 sizeof(struct ctl_var)*c); 3127 free((char *)k); 3128 } 3129 (*kv)[c].code = (u_short) c; 3130 (*kv)[c].text = (char *)emalloc(size); 3131 (*kv)[c].flags = def; 3132 (*kv)[c+1].code = 0; 3133 (*kv)[c+1].text = (char *)0; 3134 (*kv)[c+1].flags = EOV; 3135 return (char *)(intptr_t)(*kv)[c].text; 3136 } 3137 3138 void 3139 set_var( 3140 struct ctl_var **kv, 3141 const char *data, 3142 u_long size, 3143 u_short def 3144 ) 3145 { 3146 register struct ctl_var *k; 3147 register const char *s; 3148 register const char *t; 3149 char *td; 3150 3151 if (!data || !size) 3152 return; 3153 3154 k = *kv; 3155 if (k != NULL) { 3156 while (!(k->flags & EOV)) { 3157 s = data; 3158 t = k->text; 3159 if (t) { 3160 while (*t != '=' && *s - *t == 0) { 3161 s++; 3162 t++; 3163 } 3164 if (*s == *t && ((*t == '=') || !*t)) { 3165 free((void *)(intptr_t)k->text); 3166 td = (char *)emalloc(size); 3167 memmove(td, data, size); 3168 k->text =td; 3169 k->flags = def; 3170 return; 3171 } 3172 } else { 3173 td = (char *)emalloc(size); 3174 memmove(td, data, size); 3175 k->text = td; 3176 k->flags = def; 3177 return; 3178 } 3179 k++; 3180 } 3181 } 3182 td = add_var(kv, size, def); 3183 memmove(td, data, size); 3184 } 3185 3186 void 3187 set_sys_var( 3188 const char *data, 3189 u_long size, 3190 u_short def 3191 ) 3192 { 3193 set_var(&ext_sys_var, data, size, def); 3194 } 3195 3196 void 3197 free_varlist( 3198 struct ctl_var *kv 3199 ) 3200 { 3201 struct ctl_var *k; 3202 if (kv) { 3203 for (k = kv; !(k->flags & EOV); k++) 3204 free((void *)(intptr_t)k->text); 3205 free((void *)kv); 3206 } 3207 } 3208