1/* 2 * ntptimeset - get/set the time via ntp 3 * 4 * GOAL: 5 * The goal of ntptime is to set the current time on system startup 6 * to the best possible time using the network very wisely. It is assumed 7 * that after a resonable time has been sett then ntp daemon will 8 * maintain it. 9 * 10 * PROBLEM DOMAIN: 11 * We have three sets of issues related to acheiving the goal. The first 12 * issue is using the network when normal traffic is happening or when 13 * the entire network world is recovering from a campus wide power failure 14 * and is restarting. The second issue is the class of machine whether it 15 * is a user's office workstation being handled by an uneducated user or 16 * a server computer being handled by a trained operations staff. The third 17 * issue is whether the ratio of people to computers and whether the 18 * environment is stable and viable or not. 19 * 20 * NETWORK USAGE: 21 * The first issue of using the network wisely is a question of whether 22 * the network load and time server load and state are normal. If things 23 * are normal ntptime can do what ntpdate does of sending out 4 packets 24 * quickly to each server (new transmit done with each ack). However 25 * if network or time load is high then this scheme will simply contribute 26 * to problems. Given we have minimal state, we simply weight lost packets 27 * significantly and make sure we throttle output as much as possible 28 * without performance lost for quick startups. 29 * 30 * TRAINING AND KNOWLEDGE: 31 * The second issue of uneducated user of a office workstation versus a 32 * trained operation staff of a server machine translates into simply an 33 * issue of untrained and trained users. 34 * 35 * The training issue implies that for the sake of the users involved in the 36 * handling of their office workstation, problems and options should be 37 * communicated simply and effectively and not in terse expert related 38 * descriptions without possible options to be taken. The operator's training 39 * and education enables them to deal with either type of communication and 40 * control. 41 * 42 * AUTOMATION AND MANUAL CONTROL: 43 * The last issue boils down to a design problem. If the design tends to go 44 * into a manual mode when the environment is non-viable then one person 45 * handling many computers all at the same time will be heavily impacted. On 46 * the other hand, if the design tends to be automatic and does not indicate 47 * a way for the user to take over control then the computer will be 48 * unavailable for the user until the proble is resolved by someone else or 49 * the user. 50 * 51 * NOTE: Please do not have this program print out every minute some line, 52 * of output. If this happens and the environment is in trouble then 53 * many pages of paper on many different machines will be filled up. 54 * Save some tress in your lifetime. 55 * 56 * CONCLUSION: 57 * The behavior of the program derived from these three issues should be 58 * that during normal situations it quickly sets the time and allow the 59 * system to startup. 60 * 61 * However during abnormal conditions as detected by unresponsive servers, 62 * out-of-sync or bad responses and other detections, it should print out 63 * a simple but clear message and continue in a mellow way to get the best 64 * possible time. It may never get the time and if so should also indicate 65 * this. 66 * 67 * Rudy Nedved 68 * 18-May-1993 69 * 70 **************************************************************** 71 * 72 * Much of the above is confusing or no longer relevant. For example, 73 * it is rare these days for a machine's console to be a printing terminal, 74 * so the comment about saving trees doesn't mean much. Nonetheless, 75 * the basic principles still stand: 76 * 77 * - Work automatically, without human control or intervention. To 78 * this end, we use the same configuration file as ntpd itself, so 79 * you don't have to specify servers or other information on the 80 * command line. We also recognize that sometimes we won't be able 81 * to contact any servers, and give up in that event instead of 82 * hanging forever. 83 * 84 * - Behave in a sane way, both internally and externally, even in the 85 * face of insane conditions. That means we back off quickly when 86 * we don't hear a response, to avoid network congestion. Like 87 * ntpd, we verify responses from several servers before accepting 88 * the new time data. 89 * 90 * However, we don't assume that the local clock is right, or even 91 * close, because it might not be at boot time, and we want to catch 92 * and correct that situation. This behaviour has saved us in several 93 * instances. On HP-UX 9.0x, there used to be a bug in adjtimed which 94 * would cause the time to be set to some wild value, making the machine 95 * essentially unusable (we use Kerberos authentication pervasively, 96 * and it requires workstations and servers to have a time within five 97 * minutes of the Kerberos server). We also have problems on PC's 98 * running both Linux and some Microsoft OS -- they tend to disagree 99 * on what the BIOS clock should say, and who should update it, and 100 * when. On those systems, we not only run ntptimeset at boot, we 101 * also reset the BIOS clock based on the result, so the correct 102 * time will be retained across reboots. 103 * 104 * For these reasons, and others, we have continued to use this tool 105 * rather than ntpdate. It is run automatically at boot time on every 106 * workstation and server in our facility. 107 * 108 * In the past, we called this program 'ntptime'. Unfortunately, the 109 * ntp v4 distribution also includes a program with that name. In 110 * order to avoid confusion, we have renamed our program 'ntptimeset', 111 * which more accurately describes what it does. 112 * 113 * Jeffrey T. Hutzelman (N3NHS) <jhutz+@cmu.edu> 114 * School of Computer Science - Research Computing Facility 115 * Carnegie Mellon University - Pittsburgh, PA 116 * 16-Aug-1999 117 * 118 */ 119 120#ifdef HAVE_CONFIG_H 121# include <config.h> 122#endif 123 124#include "ntp_machine.h" 125#include "ntp_fp.h" 126#include "ntp.h" 127#include "ntp_io.h" 128#include "iosignal.h" 129#include "ntp_unixtime.h" 130#include "ntpdate.h" 131#include "ntp_string.h" 132#include "ntp_syslog.h" 133#include "ntp_select.h" 134#include "ntp_stdlib.h" 135 136#ifdef HAVE_UNISTD_H 137# include <unistd.h> 138#endif 139 140#include <stdio.h> 141#include <signal.h> 142#include <ctype.h> 143#ifndef SYS_WINNT 144# ifdef HAVE_SYS_SIGNAL_H 145# include <sys/signal.h> 146# else 147# include <signal.h> 148# endif 149# include <sys/ioctl.h> 150#endif /* SYS_WINNT */ 151 152#ifdef HAVE_SYS_RESOURCE_H 153# include <sys/resource.h> 154#endif /* HAVE_SYS_RESOURCE_H */ 155 156#ifdef SYS_VXWORKS 157# include "ioLib.h" 158# include "sockLib.h" 159# include "timers.h" 160#endif 161 162#include "recvbuff.h" 163 164#ifdef SYS_WINNT 165# define TARGET_RESOLUTION 1 /* Try for 1-millisecond accuracy 166 on Windows NT timers. */ 167#pragma comment(lib, "winmm") 168#endif /* SYS_WINNT */ 169 170/* 171 * Scheduling priority we run at 172 */ 173#ifndef SYS_VXWORKS 174# define NTPDATE_PRIO (-12) 175#else 176# define NTPDATE_PRIO (100) 177#endif 178 179#if defined(HAVE_TIMER_SETTIME) || defined (HAVE_TIMER_CREATE) 180/* POSIX TIMERS - vxWorks doesn't have itimer - casey */ 181static timer_t ntpdate_timerid; 182#endif 183 184/* 185 * Compatibility stuff for Version 2 186 */ 187#define NTP_MAXSKW 0x28f /* 0.01 sec in fp format */ 188#define NTP_MINDIST 0x51f /* 0.02 sec in fp format */ 189#define NTP_INFIN 15 /* max stratum, infinity a la Bellman-Ford */ 190#define NTP_MAXWGT (8*FP_SECOND) /* maximum select weight 8 seconds */ 191#define NTP_MAXLIST 5 /* maximum select list size */ 192#define PEER_SHIFT 8 /* 8 suitable for crystal time base */ 193 194/* 195 * Debugging flag 196 */ 197volatile int debug = 0; 198 199/* 200 * File descriptor masks etc. for call to select 201 */ 202int fd; 203fd_set fdmask; 204 205/* 206 * Initializing flag. All async routines watch this and only do their 207 * thing when it is clear. 208 */ 209int initializing = 1; 210 211/* 212 * Alarm flag. Set when an alarm occurs 213 */ 214volatile int alarm_flag = 0; 215 216/* 217 * Set the time if valid time determined 218 */ 219int set_time = 0; 220 221/* 222 * transmission rate control 223 */ 224#define MINTRANSMITS (3) /* minimum total packets per server */ 225#define MAXXMITCOUNT (2) /* maximum packets per time interrupt */ 226 227/* 228 * time setting constraints 229 */ 230#define DESIREDDISP (4*FP_SECOND) /* desired dispersion, (fp 4) */ 231int max_period = DEFMAXPERIOD; 232int min_servers = DEFMINSERVERS; 233int min_valid = DEFMINVALID; 234 235/* 236 * counters related to time setting constraints 237 */ 238int contacted = 0; /* # of servers we have sent to */ 239int responding = 0; /* servers responding */ 240int validcount = 0; /* servers with valid time */ 241int valid_n_low = 0; /* valid time servers with low dispersion */ 242 243/* 244 * Unpriviledged port flag. 245 */ 246int unpriv_port = 0; 247 248/* 249 * Program name. 250 */ 251char *progname; 252 253/* 254 * Systemwide parameters and flags 255 */ 256struct server **sys_servers; /* the server list */ 257int sys_numservers = 0; /* number of servers to poll */ 258int sys_authenticate = 0; /* true when authenticating */ 259u_int32 sys_authkey = 0; /* set to authentication key in use */ 260u_long sys_authdelay = 0; /* authentication delay */ 261 262/* 263 * The current internal time 264 */ 265u_long current_time = 0; 266 267/* 268 * File of encryption keys 269 */ 270 271#ifndef KEYFILE 272# ifndef SYS_WINNT 273#define KEYFILE "/etc/ntp.keys" 274# else 275#define KEYFILE "%windir%\\ntp.keys" 276# endif /* SYS_WINNT */ 277#endif /* KEYFILE */ 278 279#ifndef SYS_WINNT 280const char *key_file = KEYFILE; 281#else 282char key_file_storage[MAX_PATH+1], *key_file ; 283#endif /* SYS_WINNT */ 284 285/* 286 * total packet counts 287 */ 288u_long total_xmit = 0; 289u_long total_recv = 0; 290 291/* 292 * Miscellaneous flags 293 */ 294int verbose = 0; 295#define HORRIBLEOK 3 /* how many packets to let out */ 296int horrible = 0; /* how many packets we drop for testing */ 297int secondhalf = 0; /* second half of timeout period */ 298int printmsg = 0; /* print time response analysis */ 299 300/* 301 * The half time and finish time in internal time 302 */ 303u_long half_time = 0; 304u_long finish_time = 0; 305 306 307int ntptimesetmain P((int argc, char *argv[])); 308static void analysis P((int final)); 309static int have_enough P((void)); 310static void transmit P((register struct server *server)); 311static void receive P((struct recvbuf *rbufp)); 312static void clock_filter P((register struct server *server, s_fp d, l_fp *c)); 313static void clock_count P((void)); 314static struct server *clock_select P((void)); 315static void set_local_clock P((void)); 316static struct server *findserver P((struct sockaddr_in *addr)); 317static void timer P((void)); 318#ifndef SYS_WINNT 319static RETSIGTYPE alarming P((int sig)); 320#endif /* SYS_WINNT */ 321static void init_alarm P((void)); 322static void init_io P((void)); 323static int sendpkt P((struct sockaddr_in *dest, struct pkt *pkt, int len)); 324 void input_handler P((l_fp *xts)); 325static void printserver P((register struct server *pp, FILE *fp)); 326#if !defined(HAVE_VSPRINTF) 327int vsprintf P((char *str, const char *fmt, va_list ap)); 328#endif 329 330#ifdef HAVE_SIGNALED_IO 331extern void wait_for_signal P((void)); 332extern void unblock_io_and_alarm P((void)); 333extern void block_io_and_alarm P((void)); 334#endif 335 336 337#ifdef NO_MAIN_ALLOWED 338CALL(ntptimeset,"ntptimeset",ntptimesetmain); 339 340void clear_globals() 341{ 342 /* 343 * Debugging flag 344 */ 345 debug = 0; 346 347 ntp_optind = 0; 348 349 /* 350 * Initializing flag. All async routines watch this and only do their 351 * thing when it is clear. 352 */ 353 initializing = 1; 354 355 /* 356 * Alarm flag. Set when an alarm occurs 357 */ 358 alarm_flag = 0; 359 360 /* 361 * Unpriviledged port flag. 362 */ 363 unpriv_port = 0; 364 365 /* 366 * Systemwide parameters and flags 367 */ 368 sys_numservers = 0; /* number of servers to poll */ 369 sys_authenticate = 0; /* true when authenticating */ 370 sys_authkey = 0; /* set to authentication key in use */ 371 sys_authdelay = 0; /* authentication delay */ 372 373 /* 374 * The current internal time 375 */ 376 current_time = 0; 377 378 verbose = 0; 379} 380#endif /* NO_MAIN_ALLOWED */ 381 382/* 383 * Main program. Initialize us and loop waiting for I/O and/or 384 * timer expiries. 385 */ 386#ifndef NO_MAIN_ALLOWED 387int 388main( 389 int argc, 390 char *argv[] 391 ) 392{ 393 return ntptimesetmain(argc, argv); 394} 395#endif /* NO_MAIN_ALLOWED */ 396 397 398int 399ntptimesetmain( 400 int argc, 401 char *argv[] 402 ) 403{ 404 int was_alarmed; 405 int tot_recvbufs; 406 struct recvbuf *rbuf; 407 l_fp tmp; 408 int errflg; 409 int c; 410 extern char *ntp_optarg; 411 extern int ntp_optind; 412 int ltmp; 413 char *cfgpath; 414 415#ifdef SYS_WINNT 416 HANDLE process_handle; 417 418 wVersionRequested = MAKEWORD(1,1); 419 if (WSAStartup(wVersionRequested, &wsaData)) { 420 msyslog(LOG_ERR, "No useable winsock.dll: %m"); 421 exit(1); 422 } 423#endif /* SYS_WINNT */ 424 425#ifdef NO_MAIN_ALLOWED 426 clear_globals(); 427#endif 428 429 errflg = 0; 430 cfgpath = 0; 431 progname = argv[0]; 432 syslogit = 0; 433 434 /* 435 * Decode argument list 436 */ 437 while ((c = ntp_getopt(argc, argv, "a:c:de:slt:uvHS:V:")) != EOF) 438 switch (c) 439 { 440 case 'a': 441 c = atoi(ntp_optarg); 442 sys_authenticate = 1; 443 sys_authkey = c; 444 break; 445 case 'c': 446 cfgpath = ntp_optarg; 447 break; 448 case 'd': 449 ++debug; 450 break; 451 case 'e': 452 if (!atolfp(ntp_optarg, &tmp) 453 || tmp.l_ui != 0) { 454 (void) fprintf(stderr, 455 "%s: encryption delay %s is unlikely\n", 456 progname, ntp_optarg); 457 errflg++; 458 } else { 459 sys_authdelay = tmp.l_uf; 460 } 461 break; 462 case 's': 463 set_time = 1; 464 break; 465 case 'l': 466 syslogit = 1; 467 break; 468 case 't': 469 ltmp = atoi(ntp_optarg); 470 if (ltmp <= 0) { 471 (void) fprintf(stderr, 472 "%s: maximum time period (%d) is invalid\n", 473 progname, ltmp); 474 errflg++; 475 } 476 else 477 max_period = ltmp; 478 break; 479 case 'u': 480 unpriv_port = 1; 481 break; 482 case 'v': 483 ++verbose; 484 break; 485 case 'H': 486 horrible++; 487 break; 488 case 'S': 489 ltmp = atoi(ntp_optarg); 490 if (ltmp <= 0) { 491 (void) fprintf(stderr, 492 "%s: minimum responding (%d) is invalid\n", 493 progname, ltmp); 494 errflg++; 495 } 496 else 497 min_servers = ltmp; 498 break; 499 case 'V': 500 ltmp = atoi(ntp_optarg); 501 if (ltmp <= 0) { 502 (void) fprintf(stderr, 503 "%s: minimum valid (%d) is invalid\n", 504 progname, ltmp); 505 errflg++; 506 } 507 else 508 min_valid = ltmp; 509 break; 510 case '?': 511 ++errflg; 512 break; 513 default: 514 break; 515 } 516 517 518 if (errflg || ntp_optind < argc) { 519 fprintf(stderr,"usage: %s [switches...]\n",progname); 520 fprintf(stderr," -v (verbose)\n"); 521 fprintf(stderr," -c path (set config file path)\n"); 522 fprintf(stderr," -a key (authenticate using key)\n"); 523 fprintf(stderr," -e delay (authentication delay)\n"); 524 fprintf(stderr," -S num (# of servers that must respond)\n"); 525 fprintf(stderr," -V num (# of servers that must valid)\n"); 526 fprintf(stderr," -s (set the time based if okay)\n"); 527 fprintf(stderr," -t secs (time period before ending)\n"); 528 fprintf(stderr," -l (use syslog facility)\n"); 529 fprintf(stderr," -u (use unprivileged port)\n"); 530 fprintf(stderr," -H (drop packets for debugging)\n"); 531 fprintf(stderr," -d (debug output)\n"); 532 exit(2); 533 } 534 535 /* 536 * Logging. Open the syslog if we have to 537 */ 538 if (syslogit) { 539#if !defined (SYS_WINNT) && !defined (SYS_VXWORKS) && !defined SYS_CYGWIN32 540# ifndef LOG_DAEMON 541 openlog("ntptimeset", LOG_PID); 542# else 543 544# ifndef LOG_NTP 545# define LOG_NTP LOG_DAEMON 546# endif 547 openlog("ntptimeset", LOG_PID | LOG_NDELAY, LOG_NTP); 548 if (debug) 549 setlogmask(LOG_UPTO(LOG_DEBUG)); 550 else 551 setlogmask(LOG_UPTO(LOG_INFO)); 552# endif /* LOG_DAEMON */ 553#endif /* SYS_WINNT */ 554 } 555 556 if (debug || verbose) 557 msyslog(LOG_INFO, "%s", Version); 558 559 if (horrible) 560 msyslog(LOG_INFO, "Dropping %d out of %d packets", 561 horrible,horrible+HORRIBLEOK); 562 /* 563 * Add servers we are going to be polling 564 */ 565 loadservers(cfgpath); 566 567 if (sys_numservers < min_servers) { 568 msyslog(LOG_ERR, "Found %d servers, require %d servers", 569 sys_numservers,min_servers); 570 exit(2); 571 } 572 573 /* 574 * determine when we will end at least 575 */ 576 finish_time = max_period * TIMER_HZ; 577 half_time = finish_time >> 1; 578 579 /* 580 * Initialize the time of day routines and the I/O subsystem 581 */ 582 if (sys_authenticate) { 583 init_auth(); 584#ifdef SYS_WINNT 585 if (!key_file) key_file = KEYFILE; 586 if (!ExpandEnvironmentStrings(key_file, key_file_storage, MAX_PATH)) 587 { 588 msyslog(LOG_ERR, "ExpandEnvironmentStrings(%s) failed: %m\n", 589 key_file); 590 } else { 591 key_file = key_file_storage; 592 } 593#endif /* SYS_WINNT */ 594 595 if (!authreadkeys(key_file)) { 596 msyslog(LOG_ERR, "no key file, exiting"); 597 exit(1); 598 } 599 if (!authistrusted(sys_authkey)) { 600 char buf[10]; 601 602 (void) sprintf(buf, "%lu", (unsigned long)sys_authkey); 603 msyslog(LOG_ERR, "authentication key %s unknown", buf); 604 exit(1); 605 } 606 } 607 init_io(); 608 init_alarm(); 609 610 /* 611 * Set the priority. 612 */ 613#ifdef SYS_VXWORKS 614 taskPrioritySet( taskIdSelf(), NTPDATE_PRIO); 615#endif 616#if defined(HAVE_ATT_NICE) 617 nice (NTPDATE_PRIO); 618#endif 619#if defined(HAVE_BSD_NICE) 620 (void) setpriority(PRIO_PROCESS, 0, NTPDATE_PRIO); 621#endif 622#ifdef SYS_WINNT 623 process_handle = GetCurrentProcess(); 624 if (!SetPriorityClass(process_handle, (DWORD) REALTIME_PRIORITY_CLASS)) { 625 msyslog(LOG_ERR, "SetPriorityClass failed: %m"); 626 } 627#endif /* SYS_WINNT */ 628 629 initializing = 0; 630 631 /* 632 * Use select() on all on all input fd's for unlimited 633 * time. select() will terminate on SIGALARM or on the 634 * reception of input. Using select() means we can't do 635 * robust signal handling and we get a potential race 636 * between checking for alarms and doing the select(). 637 * Mostly harmless, I think. 638 * Keep going until we have enough information, or time is up. 639 */ 640 /* On VMS, I suspect that select() can't be interrupted 641 * by a "signal" either, so I take the easy way out and 642 * have select() time out after one second. 643 * System clock updates really aren't time-critical, 644 * and - lacking a hardware reference clock - I have 645 * yet to learn about anything else that is. 646 */ 647 was_alarmed = 0; 648 while (finish_time > current_time) { 649#if !defined(HAVE_SIGNALED_IO) 650 fd_set rdfdes; 651 int nfound; 652#elif defined(HAVE_SIGNALED_IO) 653 block_io_and_alarm(); 654#endif 655 656 tot_recvbufs = full_recvbuffs(); /* get received buffers */ 657 if (printmsg) { 658 printmsg = 0; 659 analysis(0); 660 } 661 if (alarm_flag) { /* alarmed? */ 662 was_alarmed = 1; 663 alarm_flag = 0; 664 } 665 666 if (!was_alarmed && tot_recvbufs > 0) { 667 /* 668 * Nothing to do. Wait for something. 669 */ 670#ifndef HAVE_SIGNALED_IO 671 rdfdes = fdmask; 672# if defined(VMS) || defined(SYS_VXWORKS) 673 /* make select() wake up after one second */ 674 { 675 struct timeval t1; 676 677 t1.tv_sec = 1; t1.tv_usec = 0; 678 nfound = select(fd+1, &rdfdes, (fd_set *)0, 679 (fd_set *)0, &t1); 680 } 681# else 682 nfound = select(fd+1, &rdfdes, (fd_set *)0, 683 (fd_set *)0, (struct timeval *)0); 684# endif /* VMS */ 685 if (nfound > 0) { 686 l_fp ts; 687 get_systime(&ts); 688 (void)input_handler(&ts); 689 } 690 else if (nfound == -1 && errno != EINTR) 691 msyslog(LOG_ERR, "select() error: %m"); 692 else if (debug) { 693# if !defined SYS_VXWORKS && !defined SYS_CYGWIN32 /* to unclutter log */ 694 msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound); 695# endif 696 } 697#else /* HAVE_SIGNALED_IO */ 698 699 wait_for_signal(); 700#endif /* HAVE_SIGNALED_IO */ 701 if (alarm_flag) /* alarmed? */ 702 { 703 was_alarmed = 1; 704 alarm_flag = 0; 705 } 706 tot_recvbufs = full_recvbuffs(); /* get received buffers */ 707 } 708#ifdef HAVE_SIGNALED_IO 709 unblock_io_and_alarm(); 710#endif /* HAVE_SIGNALED_IO */ 711 712 /* 713 * Out here, signals are unblocked. Call timer routine 714 * to process expiry. 715 */ 716 if (was_alarmed) 717 { 718 timer(); 719 was_alarmed = 0; 720 } 721 722 /* 723 * Call the data procedure to handle each received 724 * packet. 725 */ 726 rbuf = get_full_recv_buffer(); 727 while (rbuf != NULL) 728 { 729 receive(rbuf); 730 freerecvbuf(rbuf); 731 rbuf = get_full_recv_buffer(); 732 } 733 734 /* 735 * Do we have enough information to stop now? 736 */ 737 if (have_enough()) 738 break; /* time to end */ 739 740 /* 741 * Go around again 742 */ 743 } 744 745 /* 746 * adjust the clock and exit accordingly 747 */ 748 set_local_clock(); 749 750 /* 751 * if we get here then we are in trouble 752 */ 753 return(1); 754} 755 756 757/* 758 * analysis - print a message indicating what is happening with time service 759 * must mimic have_enough() procedure. 760 */ 761static void 762analysis( 763 int final 764 ) 765{ 766 if (contacted < sys_numservers) { 767 printf("%d servers of %d have been probed with %d packets\n", 768 contacted,sys_numservers,MINTRANSMITS); 769 return; 770 } 771 if (!responding) { 772 printf("No response from any of %d servers, network problem?\n", 773 sys_numservers); 774 return; 775 } 776 else if (responding < min_servers) { 777 printf("%d servers out of %d responding, need at least %d.\n", 778 responding, sys_numservers, min_servers); 779 return; 780 } 781 if (!validcount) { 782 printf("%d servers responding but none have valid time\n", 783 responding); 784 return; 785 } 786 else if (validcount < min_valid) { 787 printf("%d servers responding, %d are valid, need %d valid\n", 788 responding,validcount,min_valid); 789 return; 790 } 791 if (!final && valid_n_low != validcount) { 792 printf("%d valid servers but only %d have low dispersion\n", 793 validcount,valid_n_low); 794 return; 795 } 796} 797 798 799/* have_enough - see if we have enough information to terminate probing 800 */ 801static int 802have_enough(void) 803{ 804 /* have we contacted all servers yet? */ 805 if (contacted < sys_numservers) 806 return 0; /* no...try some more */ 807 808 /* have we got at least minimum servers responding? */ 809 if (responding < min_servers) 810 return 0; /* no...try some more */ 811 812 /* count the clocks */ 813 (void) clock_count(); 814 815 /* have we got at least minimum valid clocks? */ 816 if (validcount <= 0 || validcount < min_valid) 817 return 0; /* no...try some more */ 818 819 /* do we have all valid servers with low dispersion */ 820 if (!secondhalf && valid_n_low != validcount) 821 return 0; 822 823 /* if we get into the secondhalf then we ignore dispersion */ 824 825 /* all conditions have been met...end */ 826 return 1; 827} 828 829 830/* 831 * transmit - transmit a packet to the given server, or mark it completed. 832 * This is called by the timeout routine and by the receive 833 * procedure. 834 */ 835static void 836transmit( 837 register struct server *server 838 ) 839{ 840 struct pkt xpkt; 841 int timeout; 842 843 if (debug > 2) 844 printf("transmit(%s)\n", ntoa(&server->srcadr)); 845 846 if ((server->reach & 01) == 0) { 847 l_fp ts; 848 /* 849 * Last message to this server timed out. Shift 850 * zeros into the filter. 851 */ 852 L_CLR(&ts); 853 clock_filter(server, 0, &ts); 854 } 855 856 /* 857 * shift reachable register over 858 */ 859 server->reach <<= 1; 860 861 /* 862 * If we're here, send another message to the server. Fill in 863 * the packet and let 'er rip. 864 */ 865 xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, 866 server->version, MODE_CLIENT); 867 xpkt.stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); 868 xpkt.ppoll = NTP_MINPOLL; 869 xpkt.precision = NTPDATE_PRECISION; 870 xpkt.rootdelay = htonl(NTPDATE_DISTANCE); 871 xpkt.rootdispersion = htonl(NTPDATE_DISP); 872 xpkt.refid = htonl(NTPDATE_REFID); 873 L_CLR(&xpkt.reftime); 874 L_CLR(&xpkt.org); 875 L_CLR(&xpkt.rec); 876 877 /* 878 * Determine whether to authenticate or not. If so, 879 * fill in the extended part of the packet and do it. 880 * If not, just timestamp it and send it away. 881 */ 882 if (sys_authenticate) { 883 int len; 884 885 xpkt.exten[0] = htonl(sys_authkey); 886 get_systime(&server->xmt); 887 L_ADDUF(&server->xmt, sys_authdelay); 888 HTONL_FP(&server->xmt, &xpkt.xmt); 889 len = authencrypt(sys_authkey, (u_int32 *)&xpkt, LEN_PKT_NOMAC); 890 if (sendpkt(&(server->srcadr), &xpkt, (int)(LEN_PKT_NOMAC + len))) { 891 if (debug > 1) 892 printf("failed transmit auth to %s\n", 893 ntoa(&(server->srcadr))); 894 return; 895 } 896 897 if (debug > 1) 898 printf("transmit auth to %s\n", 899 ntoa(&(server->srcadr))); 900 } else { 901 get_systime(&(server->xmt)); 902 HTONL_FP(&server->xmt, &xpkt.xmt); 903 if (sendpkt(&(server->srcadr), &xpkt, LEN_PKT_NOMAC)) { 904 if (debug > 1) 905 printf("failed transmit to %s\n", 906 ntoa(&(server->srcadr))); 907 return; 908 } 909 910 if (debug > 1) 911 printf("transmit to %s\n", ntoa(&(server->srcadr))); 912 } 913 914 /* 915 * count transmits, record contacted count and set transmit time 916 */ 917 if (++server->xmtcnt == MINTRANSMITS) 918 contacted++; 919 server->last_xmit = current_time; 920 921 /* 922 * determine timeout for this packet. The more packets we send 923 * to the host, the slower we get. If the host indicates that 924 * it is not "sane" then we expect even less. 925 */ 926 if (server->xmtcnt < MINTRANSMITS) { 927 /* we have not sent enough */ 928 timeout = TIMER_HZ; /* 1 second probe */ 929 } 930 else if (server->rcvcnt <= 0) { 931 /* we have heard nothing */ 932 if (secondhalf) 933 timeout = TIMER_HZ<<4; /* 16 second probe */ 934 else 935 timeout = TIMER_HZ<<3; /* 8 second probe */ 936 } 937 else { 938 /* if we have low dispersion then probe infrequently */ 939 if (server->dispersion <= DESIREDDISP) 940 timeout = TIMER_HZ<<4; /* 16 second probe */ 941 /* if the server is not in sync then let it alone */ 942 else if (server->leap == LEAP_NOTINSYNC) 943 timeout = TIMER_HZ<<4; /* 16 second probe */ 944 /* if the server looks broken ignore it */ 945 else if (server->org.l_ui < server->reftime.l_ui) 946 timeout = TIMER_HZ<<5; /* 32 second probe */ 947 else if (secondhalf) 948 timeout = TIMER_HZ<<2; /* 4 second probe */ 949 else 950 timeout = TIMER_HZ<<1; /* 2 second probe */ 951 } 952 953 /* 954 * set next transmit time based on timeout 955 */ 956 server->event_time = current_time + timeout; 957} 958 959 960/* 961 * receive - receive and process an incoming frame 962 */ 963static void 964receive( 965 struct recvbuf *rbufp 966 ) 967{ 968 register struct pkt *rpkt; 969 register struct server *server; 970 register s_fp di; 971 l_fp t10, t23; 972 l_fp org; 973 l_fp rec; 974 l_fp ci; 975 int has_mac; 976 int is_authentic; 977 978 if (debug > 2) 979 printf("receive(%s)\n", ntoa(&rbufp->srcadr)); 980 /* 981 * Check to see if the packet basically looks like something 982 * intended for us. 983 */ 984 if (rbufp->recv_length == LEN_PKT_NOMAC) 985 has_mac = 0; 986 else if (rbufp->recv_length >= LEN_PKT_NOMAC) 987 has_mac = 1; 988 else { 989 if (debug > 2) 990 printf("receive: packet length %d\n", 991 rbufp->recv_length); 992 return; /* funny length packet */ 993 } 994 995 rpkt = &(rbufp->recv_pkt); 996 if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION || 997 PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) { 998 if (debug > 1) 999 printf("receive: bad version %d\n", 1000 PKT_VERSION(rpkt->li_vn_mode)); 1001 return; 1002 } 1003 1004 if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER 1005 && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) 1006 || rpkt->stratum >=STRATUM_UNSPEC) { 1007 if (debug > 1) 1008 printf("receive: mode %d stratum %d\n", 1009 PKT_MODE(rpkt->li_vn_mode), rpkt->stratum); 1010 return; 1011 } 1012 1013 /* 1014 * So far, so good. See if this is from a server we know. 1015 */ 1016 server = findserver(&(rbufp->srcadr)); 1017 if (server == NULL) { 1018 if (debug > 1) 1019 printf("receive: server not found\n"); 1020 return; 1021 } 1022 1023 /* 1024 * Decode the org timestamp and make sure we're getting a response 1025 * to our last request. 1026 */ 1027 NTOHL_FP(&rpkt->org, &org); 1028 if (!L_ISEQU(&org, &server->xmt)) { 1029 if (debug > 1) 1030 printf("receive: pkt.org and peer.xmt differ\n"); 1031 return; 1032 } 1033 1034 /* 1035 * Check out the authenticity if we're doing that. 1036 */ 1037 if (!sys_authenticate) 1038 is_authentic = 1; 1039 else { 1040 is_authentic = 0; 1041 1042 if (debug > 3) 1043 printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n", 1044 (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey, 1045 (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt, 1046 LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC))); 1047 1048 if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey && 1049 authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC, 1050 (int)(rbufp->recv_length - LEN_PKT_NOMAC))) 1051 is_authentic = 1; 1052 if (debug) 1053 printf("receive: authentication %s\n", 1054 is_authentic ? "passed" : "failed"); 1055 } 1056 server->trust <<= 1; 1057 if (!is_authentic) 1058 server->trust |= 1; 1059 1060 /* 1061 * Looks good. Record info from the packet. 1062 */ 1063 server->leap = PKT_LEAP(rpkt->li_vn_mode); 1064 server->stratum = PKT_TO_STRATUM(rpkt->stratum); 1065 server->precision = rpkt->precision; 1066 server->rootdelay = ntohl(rpkt->rootdelay); 1067 server->rootdispersion = ntohl(rpkt->rootdispersion); 1068 server->refid = rpkt->refid; 1069 NTOHL_FP(&rpkt->reftime, &server->reftime); 1070 NTOHL_FP(&rpkt->rec, &rec); 1071 NTOHL_FP(&rpkt->xmt, &server->org); 1072 1073 /* 1074 * count this guy as responding 1075 */ 1076 server->reach |= 1; 1077 if (server->rcvcnt++ == 0) 1078 responding++; 1079 1080 /* 1081 * Make sure the server is at least somewhat sane. If not, ignore 1082 * it for later. 1083 */ 1084 if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) { 1085 if (debug > 1) 1086 printf("receive: pkt insane\n"); 1087 return; 1088 } 1089 1090 /* 1091 * Calculate the round trip delay (di) and the clock offset (ci). 1092 * We use the equations (reordered from those in the spec): 1093 * 1094 * d = (t2 - t3) - (t1 - t0) 1095 * c = ((t2 - t3) + (t1 - t0)) / 2 1096 */ 1097 t10 = server->org; /* pkt.xmt == t1 */ 1098 L_SUB(&t10, &rbufp->recv_time); /* recv_time == t0*/ 1099 1100 t23 = rec; /* pkt.rec == t2 */ 1101 L_SUB(&t23, &org); /* pkt->org == t3 */ 1102 1103 /* now have (t2 - t3) and (t0 - t1). Calculate (ci) and (di) */ 1104 ci = t10; 1105 L_ADD(&ci, &t23); 1106 L_RSHIFT(&ci); 1107 1108 /* 1109 * Calculate di in t23 in full precision, then truncate 1110 * to an s_fp. 1111 */ 1112 L_SUB(&t23, &t10); 1113 di = LFPTOFP(&t23); 1114 1115 if (debug > 3) 1116 printf("offset: %s, delay %s\n", lfptoa(&ci, 6), fptoa(di, 5)); 1117 1118 di += (FP_SECOND >> (-(int)NTPDATE_PRECISION)) 1119 + (FP_SECOND >> (-(int)server->precision)) + NTP_MAXSKW; 1120 1121 if (di <= 0) { /* value still too raunchy to use? */ 1122 L_CLR(&ci); 1123 di = 0; 1124 } else { 1125 di = max(di, NTP_MINDIST); 1126 } 1127 1128 1129 /* 1130 * This one is valid. Give it to clock_filter(), 1131 */ 1132 clock_filter(server, di, &ci); 1133 if (debug > 1) 1134 printf("receive from %s\n", ntoa(&rbufp->srcadr)); 1135 1136 /* 1137 * See if we should goes the transmission. If not return now 1138 * otherwise have the next event time be shortened 1139 */ 1140 if (server->stratum <= NTP_INFIN) 1141 return; /* server does not have a stratum */ 1142 if (server->leap == LEAP_NOTINSYNC) 1143 return; /* just booted server or out of sync */ 1144 if (!L_ISHIS(&server->org, &server->reftime)) 1145 return; /* broken host */ 1146 if (server->trust != 0) 1147 return; /* can not trust it */ 1148 1149 if (server->dispersion < DESIREDDISP) 1150 return; /* we have the desired dispersion */ 1151 1152 server->event_time -= (TIMER_HZ+1); 1153} 1154 1155 1156/* 1157 * clock_filter - add clock sample, determine a server's delay, dispersion 1158 * and offset 1159 */ 1160static void 1161clock_filter( 1162 register struct server *server, 1163 s_fp di, 1164 l_fp *c 1165 ) 1166{ 1167 register int i, j; 1168 int ord[NTP_SHIFT]; 1169 1170 /* 1171 * Insert sample and increment nextpt 1172 */ 1173 1174 i = server->filter_nextpt; 1175 server->filter_delay[i] = di; 1176 server->filter_offset[i] = *c; 1177 server->filter_soffset[i] = LFPTOFP(c); 1178 server->filter_nextpt++; 1179 if (server->filter_nextpt >= NTP_SHIFT) 1180 server->filter_nextpt = 0; 1181 1182 /* 1183 * Sort indices into increasing delay order 1184 */ 1185 for (i = 0; i < NTP_SHIFT; i++) 1186 ord[i] = i; 1187 1188 for (i = 0; i < (NTP_SHIFT-1); i++) { 1189 for (j = i+1; j < NTP_SHIFT; j++) { 1190 if (server->filter_delay[ord[j]] == 0) 1191 continue; 1192 if (server->filter_delay[ord[i]] == 0 1193 || (server->filter_delay[ord[i]] 1194 > server->filter_delay[ord[j]])) { 1195 register int tmp; 1196 1197 tmp = ord[i]; 1198 ord[i] = ord[j]; 1199 ord[j] = tmp; 1200 } 1201 } 1202 } 1203 1204 /* 1205 * Now compute the dispersion, and assign values to delay and 1206 * offset. If there are no samples in the register, delay and 1207 * offset go to zero and dispersion is set to the maximum. 1208 */ 1209 if (server->filter_delay[ord[0]] == 0) { 1210 server->delay = 0; 1211 L_CLR(&server->offset); 1212 server->soffset = 0; 1213 server->dispersion = PEER_MAXDISP; 1214 } else { 1215 register s_fp d; 1216 1217 server->delay = server->filter_delay[ord[0]]; 1218 server->offset = server->filter_offset[ord[0]]; 1219 server->soffset = LFPTOFP(&server->offset); 1220 server->dispersion = 0; 1221 for (i = 1; i < NTP_SHIFT; i++) { 1222 if (server->filter_delay[ord[i]] == 0) 1223 d = PEER_MAXDISP; 1224 else { 1225 d = server->filter_soffset[ord[i]] 1226 - server->filter_soffset[ord[0]]; 1227 if (d < 0) 1228 d = -d; 1229 if (d > PEER_MAXDISP) 1230 d = PEER_MAXDISP; 1231 } 1232 /* 1233 * XXX This *knows* PEER_FILTER is 1/2 1234 */ 1235 server->dispersion += (u_fp)(d) >> i; 1236 } 1237 } 1238 /* 1239 * We're done 1240 */ 1241} 1242 1243 1244/* clock_count - count the clock sources we have 1245 */ 1246static void 1247clock_count(void) 1248{ 1249 register struct server *server; 1250 register int n; 1251 1252 /* reset counts */ 1253 validcount = valid_n_low = 0; 1254 1255 /* go through the list of servers and count the clocks we believe 1256 * and that have low dispersion 1257 */ 1258 for (n = 0; n < sys_numservers; n++) { 1259 server = sys_servers[n]; 1260 if (server->delay == 0) { 1261 continue; /* no data */ 1262 } 1263 if (server->stratum > NTP_INFIN) { 1264 continue; /* stratum no good */ 1265 } 1266 if (server->delay > NTP_MAXWGT) { 1267 continue; /* too far away */ 1268 } 1269 if (server->leap == LEAP_NOTINSYNC) 1270 continue; /* he's in trouble */ 1271 if (!L_ISHIS(&server->org, &server->reftime)) { 1272 continue; /* very broken host */ 1273 } 1274 if ((server->org.l_ui - server->reftime.l_ui) >= NTP_MAXAGE) { 1275 continue; /* too long without sync */ 1276 } 1277 if (server->trust != 0) { 1278 continue; 1279 } 1280 1281 /* 1282 * This one is a valid time source.. 1283 */ 1284 validcount++; 1285 1286 /* 1287 * See if this one has a okay low dispersion 1288 */ 1289 if (server->dispersion <= DESIREDDISP) 1290 valid_n_low++; 1291 } 1292 1293 if (debug > 1) 1294 printf("have %d, valid %d, low %d\n", 1295 responding, validcount, valid_n_low); 1296} 1297 1298 1299/* 1300 * clock_select - select the pick-of-the-litter clock from the samples 1301 * we've got. 1302 */ 1303static struct server * 1304clock_select(void) 1305{ 1306 register struct server *server; 1307 register int i; 1308 register int nlist; 1309 register s_fp d; 1310 register int j; 1311 register int n; 1312 s_fp local_threshold; 1313 struct server *server_list[NTP_MAXCLOCK]; 1314 u_fp server_badness[NTP_MAXCLOCK]; 1315 struct server *sys_server; 1316 1317 /* 1318 * This first chunk of code is supposed to go through all 1319 * servers we know about to find the NTP_MAXLIST servers which 1320 * are most likely to succeed. We run through the list 1321 * doing the sanity checks and trying to insert anyone who 1322 * looks okay. We are at all times aware that we should 1323 * only keep samples from the top two strata and we only need 1324 * NTP_MAXLIST of them. 1325 */ 1326 nlist = 0; /* none yet */ 1327 for (n = 0; n < sys_numservers; n++) { 1328 server = sys_servers[n]; 1329 if (server->delay == 0) 1330 continue; /* no data */ 1331 if (server->stratum > NTP_INFIN) 1332 continue; /* stratum no good */ 1333 if (server->delay > NTP_MAXWGT) { 1334 continue; /* too far away */ 1335 } 1336 if (server->leap == LEAP_NOTINSYNC) 1337 continue; /* he's in trouble */ 1338 if (!L_ISHIS(&server->org, &server->reftime)) { 1339 continue; /* very broken host */ 1340 } 1341 if ((server->org.l_ui - server->reftime.l_ui) 1342 >= NTP_MAXAGE) { 1343 continue; /* too long without sync */ 1344 } 1345 if (server->trust != 0) { 1346 continue; 1347 } 1348 1349 /* 1350 * This one seems sane. Find where he belongs 1351 * on the list. 1352 */ 1353 d = server->dispersion + server->dispersion; 1354 for (i = 0; i < nlist; i++) 1355 if (server->stratum <= server_list[i]->stratum) 1356 break; 1357 for ( ; i < nlist; i++) { 1358 if (server->stratum < server_list[i]->stratum) 1359 break; 1360 if (d < (s_fp) server_badness[i]) 1361 break; 1362 } 1363 1364 /* 1365 * If i points past the end of the list, this 1366 * guy is a loser, else stick him in. 1367 */ 1368 if (i >= NTP_MAXLIST) 1369 continue; 1370 for (j = nlist; j > i; j--) 1371 if (j < NTP_MAXLIST) { 1372 server_list[j] = server_list[j-1]; 1373 server_badness[j] 1374 = server_badness[j-1]; 1375 } 1376 1377 server_list[i] = server; 1378 server_badness[i] = d; 1379 if (nlist < NTP_MAXLIST) 1380 nlist++; 1381 } 1382 1383 /* 1384 * Got the five-or-less best. Cut the list where the number of 1385 * strata exceeds two. 1386 */ 1387 j = 0; 1388 for (i = 1; i < nlist; i++) 1389 if (server_list[i]->stratum > server_list[i-1]->stratum) 1390 if (++j == 2) { 1391 nlist = i; 1392 break; 1393 } 1394 1395 /* 1396 * Whew! What we should have by now is 0 to 5 candidates for 1397 * the job of syncing us. If we have none, we're out of luck. 1398 * If we have one, he's a winner. If we have more, do falseticker 1399 * detection. 1400 */ 1401 1402 if (nlist == 0) 1403 sys_server = 0; 1404 else if (nlist == 1) { 1405 sys_server = server_list[0]; 1406 } else { 1407 /* 1408 * Re-sort by stratum, bdelay estimate quality and 1409 * server.delay. 1410 */ 1411 for (i = 0; i < nlist-1; i++) 1412 for (j = i+1; j < nlist; j++) { 1413 if (server_list[i]->stratum 1414 < server_list[j]->stratum) 1415 break; /* already sorted by stratum */ 1416 if (server_list[i]->delay 1417 < server_list[j]->delay) 1418 continue; 1419 server = server_list[i]; 1420 server_list[i] = server_list[j]; 1421 server_list[j] = server; 1422 } 1423 1424 /* 1425 * Calculate the fixed part of the dispersion limit 1426 */ 1427 local_threshold = (FP_SECOND >> (-(int)NTPDATE_PRECISION)) 1428 + NTP_MAXSKW; 1429 1430 /* 1431 * Now drop samples until we're down to one. 1432 */ 1433 while (nlist > 1) { 1434 for (n = 0; n < nlist; n++) { 1435 server_badness[n] = 0; 1436 for (j = 0; j < nlist; j++) { 1437 if (j == n) /* with self? */ 1438 continue; 1439 d = server_list[j]->soffset 1440 - server_list[n]->soffset; 1441 if (d < 0) /* absolute value */ 1442 d = -d; 1443 /* 1444 * XXX This code *knows* that 1445 * NTP_SELECT is 3/4 1446 */ 1447 for (i = 0; i < j; i++) 1448 d = (d>>1) + (d>>2); 1449 server_badness[n] += d; 1450 } 1451 } 1452 1453 /* 1454 * We now have an array of nlist badness 1455 * coefficients. Find the badest. Find 1456 * the minimum precision while we're at 1457 * it. 1458 */ 1459 i = 0; 1460 n = server_list[0]->precision;; 1461 for (j = 1; j < nlist; j++) { 1462 if (server_badness[j] >= server_badness[i]) 1463 i = j; 1464 if (n > server_list[j]->precision) 1465 n = server_list[j]->precision; 1466 } 1467 1468 /* 1469 * i is the index of the server with the worst 1470 * dispersion. If his dispersion is less than 1471 * the threshold, stop now, else delete him and 1472 * continue around again. 1473 */ 1474 if (server_badness[i] < (local_threshold 1475 + (FP_SECOND >> (-n)))) 1476 break; 1477 for (j = i + 1; j < nlist; j++) 1478 server_list[j-1] = server_list[j]; 1479 nlist--; 1480 } 1481 1482 /* 1483 * What remains is a list of less than 5 servers. Take 1484 * the best. 1485 */ 1486 sys_server = server_list[0]; 1487 } 1488 1489 /* 1490 * That's it. Return our server. 1491 */ 1492 return sys_server; 1493} 1494 1495 1496/* 1497 * set_local_clock -- handle setting the local clock or displaying info. 1498 */ 1499static void 1500set_local_clock(void) 1501{ 1502 register int i; 1503 register struct server *server; 1504 time_t tmp; 1505 double dtemp; 1506 1507 /* 1508 * if setting time then print final analysis 1509 */ 1510 if (set_time) 1511 analysis(1); 1512 1513 /* 1514 * pick a clock 1515 */ 1516 server = clock_select(); 1517 1518 /* 1519 * do some display of information 1520 */ 1521 if (debug || verbose) { 1522 for (i = 0; i < sys_numservers; i++) 1523 printserver(sys_servers[i], stdout); 1524 if (debug) 1525 printf("packets sent %ld, received %ld\n", 1526 total_xmit, total_recv); 1527 } 1528 1529 /* 1530 * see if we have a server to set the time with 1531 */ 1532 if (server == 0) { 1533 if (!set_time || verbose) 1534 fprintf(stdout,"No servers available to sync time with\n"); 1535 exit(1); 1536 } 1537 1538 /* 1539 * we have a valid and selected time to use!!!!! 1540 */ 1541 1542 /* 1543 * if we are not setting the time then display offset and exit 1544 */ 1545 if (!set_time) { 1546 fprintf(stdout, 1547 "Your clock is off by %s seconds. (%s) [%ld/%ld]\n", 1548 lfptoa(&server->offset, 7), 1549 ntoa(&server->srcadr), 1550 total_xmit, total_recv); 1551 exit(0); 1552 } 1553 1554 /* 1555 * set the clock 1556 * XXX: Examine the more flexible approach used by ntpdate. 1557 * Note that a design consideration here is that we sometimes 1558 * _want_ to step the clock by a _huge_ amount in either 1559 * direction, because the local clock is completely bogus. 1560 * This condition must be recognized and dealt with, so 1561 * that we always get a good time when this completes. 1562 * -- jhutz+@cmu.edu, 16-Aug-1999 1563 */ 1564 LFPTOD(&server->offset, dtemp); 1565 step_systime(dtemp); 1566 time(&tmp); 1567 fprintf(stdout,"Time set to %.20s [%s %s %ld/%ld]\n", 1568 ctime(&tmp)+4, 1569 ntoa(&server->srcadr), 1570 lfptoa(&server->offset, 7), 1571 total_xmit, total_recv); 1572 exit(0); 1573} 1574 1575 1576/* 1577 * findserver - find a server in the list given its address 1578 */ 1579static struct server * 1580findserver( 1581 struct sockaddr_in *addr 1582 ) 1583{ 1584 register int i; 1585 register u_int32 netnum; 1586 1587 if (htons(addr->sin_port) != NTP_PORT) 1588 return 0; 1589 netnum = addr->sin_addr.s_addr; 1590 1591 for (i = 0; i < sys_numservers; i++) { 1592 if (netnum == sys_servers[i]->srcadr.sin_addr.s_addr) 1593 return sys_servers[i]; 1594 } 1595 return 0; 1596} 1597 1598 1599/* 1600 * timer - process a timer interrupt 1601 */ 1602static void 1603timer(void) 1604{ 1605 register int k; 1606 1607 /* 1608 * Bump the current idea of the time 1609 */ 1610 current_time++; 1611 1612 /* 1613 * see if we have reached half time 1614 */ 1615 if (current_time >= half_time && !secondhalf) { 1616 secondhalf++; 1617 if (debug) 1618 printf("\nSecond Half of Timeout!\n"); 1619 printmsg++; 1620 } 1621 1622 /* 1623 * We only want to send a few packets per transmit interrupt 1624 * to throttle things 1625 */ 1626 for(k = 0;k < MAXXMITCOUNT;k++) { 1627 register int i, oldi; 1628 register u_long oldxtime; 1629 1630 /* 1631 * We want to send a packet out for a server that has an 1632 * expired event time. However to be mellow about this, we only 1633 * use one expired event timer and to avoid starvation we use 1634 * the one with the oldest last transmit time. 1635 */ 1636 oldi = -1; 1637 oldxtime = 0; 1638 for (i = 0; i < sys_numservers; i++) { 1639 if (sys_servers[i]->event_time <= current_time) { 1640 if (oldi < 0 || oldxtime > sys_servers[i]->last_xmit) { 1641 oldxtime = sys_servers[i]->last_xmit; 1642 oldi = i; 1643 } 1644 } 1645 } 1646 if (oldi >= 0) 1647 transmit(sys_servers[oldi]); 1648 else 1649 break; /* no expired event */ 1650 } /* end of transmit loop */ 1651} 1652 1653 1654#ifndef SYS_WINNT 1655/* 1656 * alarming - record the occurance of an alarm interrupt 1657 */ 1658static RETSIGTYPE 1659alarming( 1660 int sig 1661 ) 1662#else 1663void CALLBACK 1664alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) 1665#endif /* SYS_WINNT */ 1666{ 1667 alarm_flag++; 1668} 1669 1670 1671/* 1672 * init_alarm - set up the timer interrupt 1673 */ 1674static void 1675init_alarm(void) 1676{ 1677#ifndef SYS_WINNT 1678# ifndef HAVE_TIMER_SETTIME 1679 struct itimerval itimer; 1680# else 1681 struct itimerspec ntpdate_itimer; 1682# endif 1683#else 1684 TIMECAPS tc; 1685 UINT wTimerRes, wTimerID; 1686# endif /* SYS_WINNT */ 1687#if defined SYS_CYGWIN32 || defined SYS_WINNT 1688 HANDLE hToken; 1689 TOKEN_PRIVILEGES tkp; 1690 DWORD dwUser = 0; 1691#endif /* SYS_WINNT */ 1692 1693 alarm_flag = 0; 1694 1695#ifndef SYS_WINNT 1696# if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) 1697 alarm_flag = 0; 1698 /* this code was put in as setitimer() is non existant this us the 1699 * POSIX "equivalents" setup - casey 1700 */ 1701 /* ntpdate_timerid is global - so we can kill timer later */ 1702 if (timer_create (CLOCK_REALTIME, NULL, &ntpdate_timerid) == 1703# ifdef SYS_VXWORKS 1704 ERROR 1705# else 1706 -1 1707# endif 1708 ) 1709 { 1710 fprintf (stderr, "init_alarm(): timer_create (...) FAILED\n"); 1711 return; 1712 } 1713 1714 /* TIMER_HZ = (5) 1715 * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) 1716 * seconds from now and they continue on every 1/TIMER_HZ seconds. 1717 */ 1718 (void) signal_no_reset(SIGALRM, alarming); 1719 ntpdate_itimer.it_interval.tv_sec = ntpdate_itimer.it_value.tv_sec = 0; 1720 ntpdate_itimer.it_interval.tv_nsec = 1000000000/TIMER_HZ; 1721 ntpdate_itimer.it_value.tv_nsec = 1000000000/(TIMER_HZ<<1); 1722 timer_settime(ntpdate_timerid, 0 /* !TIMER_ABSTIME */, &ntpdate_itimer, NULL); 1723# else 1724 /* 1725 * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) 1726 * seconds from now and they continue on every 1/TIMER_HZ seconds. 1727 */ 1728 (void) signal_no_reset(SIGALRM, alarming); 1729 itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0; 1730 itimer.it_interval.tv_usec = 1000000/TIMER_HZ; 1731 itimer.it_value.tv_usec = 1000000/(TIMER_HZ<<1); 1732 setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); 1733# endif 1734#if defined SYS_CYGWIN32 1735 /* 1736 * Get previleges needed for fiddling with the clock 1737 */ 1738 1739 /* get the current process token handle */ 1740 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { 1741 msyslog(LOG_ERR, "OpenProcessToken failed: %m"); 1742 exit(1); 1743 } 1744 /* get the LUID for system-time privilege. */ 1745 LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); 1746 tkp.PrivilegeCount = 1; /* one privilege to set */ 1747 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 1748 /* get set-time privilege for this process. */ 1749 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); 1750 /* cannot test return value of AdjustTokenPrivileges. */ 1751 if (GetLastError() != ERROR_SUCCESS) 1752 msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); 1753#endif 1754#else /* SYS_WINNT */ 1755 _tzset(); 1756 1757 /* 1758 * Get previleges needed for fiddling with the clock 1759 */ 1760 1761 /* get the current process token handle */ 1762 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { 1763 msyslog(LOG_ERR, "OpenProcessToken failed: %m"); 1764 exit(1); 1765 } 1766 /* get the LUID for system-time privilege. */ 1767 LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); 1768 tkp.PrivilegeCount = 1; /* one privilege to set */ 1769 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 1770 /* get set-time privilege for this process. */ 1771 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); 1772 /* cannot test return value of AdjustTokenPrivileges. */ 1773 if (GetLastError() != ERROR_SUCCESS) 1774 msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); 1775 1776 /* 1777 * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds 1778 * Under Win/NT, expiry of timer interval leads to invocation 1779 * of a callback function (on a different thread) rather than 1780 * generating an alarm signal 1781 */ 1782 1783 /* determine max and min resolution supported */ 1784 if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { 1785 msyslog(LOG_ERR, "timeGetDevCaps failed: %m"); 1786 exit(1); 1787 } 1788 wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax); 1789 /* establish the minimum timer resolution that we'll use */ 1790 timeBeginPeriod(wTimerRes); 1791 1792 /* start the timer event */ 1793 wTimerID = timeSetEvent( 1794 (UINT) (1000/TIMER_HZ), /* Delay */ 1795 wTimerRes, /* Resolution */ 1796 (LPTIMECALLBACK) alarming, /* Callback function */ 1797 (DWORD) dwUser, /* User data */ 1798 TIME_PERIODIC); /* Event type (periodic) */ 1799 if (wTimerID == 0) { 1800 msyslog(LOG_ERR, "timeSetEvent failed: %m"); 1801 exit(1); 1802 } 1803#endif /* SYS_WINNT */ 1804} 1805 1806 1807/* 1808 * init_io - initialize I/O data and open socket 1809 */ 1810static void 1811init_io(void) 1812{ 1813#ifdef SYS_WINNT 1814 WORD wVersionRequested; 1815 WSADATA wsaData; 1816 init_transmitbuff(); 1817#endif /* SYS_WINNT */ 1818 1819 /* 1820 * Init buffer free list and stat counters 1821 */ 1822 init_recvbuff(sys_numservers + 2); 1823 1824#if defined(HAVE_SIGNALED_IO) 1825 set_signal(); 1826#endif 1827 1828#ifdef SYS_WINNT 1829 wVersionRequested = MAKEWORD(1,1); 1830 if (WSAStartup(wVersionRequested, &wsaData)) 1831 { 1832 msyslog(LOG_ERR, "No useable winsock.dll: %m"); 1833 exit(1); 1834 } 1835#endif /* SYS_WINNT */ 1836 1837 BLOCKIO(); 1838 1839 /* create a datagram (UDP) socket */ 1840 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1841 msyslog(LOG_ERR, "socket() failed: %m"); 1842 exit(1); 1843 /*NOTREACHED*/ 1844 } 1845 1846 /* 1847 * bind the socket to the NTP port 1848 */ 1849 if (!debug && set_time && !unpriv_port) { 1850 struct sockaddr_in addr; 1851 1852 memset((char *)&addr, 0, sizeof addr); 1853 addr.sin_family = AF_INET; 1854 addr.sin_port = htons(NTP_PORT); 1855 addr.sin_addr.s_addr = htonl(INADDR_ANY); 1856 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 1857#ifndef SYS_WINNT 1858 if (errno == EADDRINUSE) 1859#else 1860 if (WSAGetLastError() == WSAEADDRINUSE) 1861#endif 1862 msyslog(LOG_ERR, 1863 "the NTP socket is in use, exiting"); 1864 else 1865 msyslog(LOG_ERR, "bind() fails: %m"); 1866 exit(1); 1867 } 1868 } 1869 1870 FD_ZERO(&fdmask); 1871 FD_SET(fd, &fdmask); 1872 1873 /* 1874 * set non-blocking, 1875 */ 1876 1877#ifdef USE_FIONBIO 1878 /* in vxWorks we use FIONBIO, but the others are defined for old systems, so 1879 * all hell breaks loose if we leave them defined 1880 */ 1881#undef O_NONBLOCK 1882#undef FNDELAY 1883#undef O_NDELAY 1884#endif 1885 1886#if defined(O_NONBLOCK) /* POSIX */ 1887 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) 1888 { 1889 msyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails: %m"); 1890 exit(1); 1891 /*NOTREACHED*/ 1892 } 1893#elif defined(FNDELAY) 1894 if (fcntl(fd, F_SETFL, FNDELAY) < 0) 1895 { 1896 msyslog(LOG_ERR, "fcntl(FNDELAY) fails: %m"); 1897 exit(1); 1898 /*NOTREACHED*/ 1899 } 1900#elif defined(O_NDELAY) /* generally the same as FNDELAY */ 1901 if (fcntl(fd, F_SETFL, O_NDELAY) < 0) 1902 { 1903 msyslog(LOG_ERR, "fcntl(O_NDELAY) fails: %m"); 1904 exit(1); 1905 /*NOTREACHED*/ 1906 } 1907#elif defined(FIONBIO) 1908 if ( 1909# if defined(VMS) 1910 (ioctl(fd,FIONBIO,&1) < 0) 1911# elif defined(SYS_WINNT) 1912 (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) 1913# else 1914 (ioctl(fd,FIONBIO,&on) < 0) 1915# endif 1916 ) 1917 { 1918 msyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m"); 1919 exit(1); 1920 /*NOTREACHED*/ 1921 } 1922#elif defined(FIOSNBIO) 1923 if (ioctl(fd,FIOSNBIO,&on) < 0) 1924 { 1925 msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails: %m"); 1926 exit(1); 1927 /*NOTREACHED*/ 1928 } 1929#else 1930# include "Bletch: Need non-blocking I/O!" 1931#endif 1932 1933#ifdef HAVE_SIGNALED_IO 1934 init_socket_sig(fd); 1935#endif /* not HAVE_SIGNALED_IO */ 1936 1937 UNBLOCKIO(); 1938} 1939 1940 1941/* 1942 * sendpkt - send a packet to the specified destination 1943 */ 1944static int 1945sendpkt( 1946 struct sockaddr_in *dest, 1947 struct pkt *pkt, 1948 int len 1949 ) 1950{ 1951 int cc; 1952 static int horriblecnt = 0; 1953#ifdef SYS_WINNT 1954 DWORD err; 1955#endif /* SYS_WINNT */ 1956 1957 total_xmit++; /* count it */ 1958 1959 if (horrible) { 1960 if (++horriblecnt > HORRIBLEOK) { 1961 if (debug > 3) 1962 printf("dropping send (%s)\n", ntoa(dest)); 1963 if (horriblecnt >= HORRIBLEOK+horrible) 1964 horriblecnt = 0; 1965 return 0; 1966 } 1967 } 1968 1969 1970 cc = sendto(fd, (char *)pkt, (size_t)len, 0, (struct sockaddr *)dest, 1971 sizeof(struct sockaddr_in)); 1972#ifndef SYS_WINNT 1973 if (cc == -1) { 1974 if (errno != EWOULDBLOCK && errno != ENOBUFS) 1975#else 1976 if (cc == SOCKET_ERROR) { 1977 err = WSAGetLastError(); 1978 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS) 1979#endif /* SYS_WINNT */ 1980 msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest)); 1981 return -1; 1982 } 1983 return 0; 1984} 1985 1986 1987/* 1988 * input_handler - receive packets asynchronously 1989 */ 1990void 1991input_handler(l_fp *xts) 1992{ 1993 register int n; 1994 register struct recvbuf *rb; 1995 struct timeval tvzero; 1996 int fromlen; 1997 fd_set fds; 1998 l_fp ts; 1999 ts = *xts; /* we ignore xts, but make the compiler happy */ 2000 2001 /* 2002 * Do a poll to see if we have data 2003 */ 2004 for (;;) { 2005 fds = fdmask; 2006 tvzero.tv_sec = tvzero.tv_usec = 0; 2007 n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero); 2008 2009 /* 2010 * If nothing to do, just return. If an error occurred, 2011 * complain and return. If we've got some, freeze a 2012 * timestamp. 2013 */ 2014 if (n == 0) 2015 return; 2016 else if (n == -1) { 2017 if (errno != EINTR) { 2018 msyslog(LOG_ERR, "select() error: %m"); 2019 } 2020 return; 2021 } 2022 get_systime(&ts); 2023 2024 /* 2025 * Get a buffer and read the frame. If we 2026 * haven't got a buffer, or this is received 2027 * on the wild card socket, just dump the packet. 2028 */ 2029 if (initializing || free_recvbuffs == 0) { 2030 char buf[100]; 2031 2032#ifndef SYS_WINNT 2033 (void) read(fd, buf, sizeof buf); 2034#else 2035 /* NT's _read does not operate on nonblocking sockets 2036 * either recvfrom or ReadFile() has to be used here. 2037 * ReadFile is used in [ntpd]ntp_intres() and ntpdc, 2038 * just to be different use recvfrom() here 2039 */ 2040 recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)0, NULL); 2041#endif /* SYS_WINNT */ 2042 continue; 2043 } 2044 2045 rb = get_free_recv_buffer(); 2046 2047 fromlen = sizeof(struct sockaddr_in); 2048 rb->recv_length = recvfrom(fd, (char *)&rb->recv_pkt, 2049 sizeof(rb->recv_pkt), 0, 2050 (struct sockaddr *)&rb->srcadr, &fromlen); 2051 if (rb->recv_length == -1) { 2052 freerecvbuf(rb); 2053 continue; 2054 } 2055 2056 /* 2057 * Got one. Mark how and when it got here, 2058 * put it on the full list. 2059 */ 2060 rb->recv_time = ts; 2061 add_full_recv_buffer(rb); 2062 total_recv++; /* count it */ 2063 } 2064} 2065 2066 2067/* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c */ 2068/* 2069 * printserver - print detail information for a server 2070 */ 2071static void 2072printserver( 2073 register struct server *pp, 2074 FILE *fp 2075 ) 2076{ 2077 register int i; 2078 char junk[5]; 2079 char *str; 2080 2081 if (!debug) { 2082 (void) fprintf(fp, 2083 "%-15s %d/%d %03o v%d s%d offset %9s delay %s disp %s\n", 2084 ntoa(&pp->srcadr), 2085 pp->xmtcnt,pp->rcvcnt,pp->reach, 2086 pp->version,pp->stratum, 2087 lfptoa(&pp->offset, 6), ufptoa(pp->delay, 5), 2088 ufptoa(pp->dispersion, 4)); 2089 return; 2090 } 2091 2092 (void) fprintf(fp, "server %s, port %d\n", 2093 ntoa(&pp->srcadr), ntohs(pp->srcadr.sin_port)); 2094 2095 (void) fprintf(fp, "stratum %d, precision %d, leap %c%c, trust %03o\n", 2096 pp->stratum, pp->precision, 2097 pp->leap & 0x2 ? '1' : '0', 2098 pp->leap & 0x1 ? '1' : '0', 2099 pp->trust); 2100 2101 if (pp->stratum == 1) { 2102 junk[4] = 0; 2103 memmove(junk, (char *)&pp->refid, 4); 2104 str = junk; 2105 } else { 2106 str = numtoa(pp->refid); 2107 } 2108 (void) fprintf(fp, 2109 "refid [%s], delay %s, dispersion %s\n", 2110 str, fptoa((s_fp)pp->delay, 5), 2111 ufptoa(pp->dispersion, 5)); 2112 2113 (void) fprintf(fp, "transmitted %d, received %d, reachable %03o\n", 2114 pp->xmtcnt, pp->rcvcnt, pp->reach); 2115 2116 (void) fprintf(fp, "reference time: %s\n", 2117 prettydate(&pp->reftime)); 2118 (void) fprintf(fp, "originate timestamp: %s\n", 2119 prettydate(&pp->org)); 2120 (void) fprintf(fp, "transmit timestamp: %s\n", 2121 prettydate(&pp->xmt)); 2122 2123 (void) fprintf(fp, "filter delay: "); 2124 for (i = 0; i < NTP_SHIFT; i++) { 2125 (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5)); 2126 if (i == (NTP_SHIFT>>1)-1) 2127 (void) fprintf(fp, "\n "); 2128 } 2129 (void) fprintf(fp, "\n"); 2130 2131 (void) fprintf(fp, "filter offset:"); 2132 for (i = 0; i < PEER_SHIFT; i++) { 2133 (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6)); 2134 if (i == (PEER_SHIFT>>1)-1) 2135 (void) fprintf(fp, "\n "); 2136 } 2137 (void) fprintf(fp, "\n"); 2138 2139 (void) fprintf(fp, "delay %s, dispersion %s\n", 2140 fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5)); 2141 2142 (void) fprintf(fp, "offset %s\n\n", 2143 lfptoa(&pp->offset, 6)); 2144} 2145 2146#if !defined(HAVE_VSPRINTF) 2147int 2148vsprintf( 2149 char *str, 2150 const char *fmt, 2151 va_list ap 2152 ) 2153{ 2154 FILE f; 2155 int len; 2156 2157 f._flag = _IOWRT+_IOSTRG; 2158 f._ptr = str; 2159 f._cnt = 32767; 2160 len = _doprnt(fmt, ap, &f); 2161 *f._ptr = 0; 2162 return (len); 2163} 2164#endif 2165