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