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