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