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