PageRenderTime 105ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/ntp/ntpdate/ntptimeset.c

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