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