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