/contrib/ntp/ntpd/refclock_local.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 258 lines · 110 code · 25 blank · 123 comment · 6 complexity · 2765899891e6b683c73f1940f25d2fa0 MD5 · raw file

  1. /*
  2. * refclock_local - local pseudo-clock driver
  3. *
  4. * wjm 17-aug-1995: add a hook for special treatment of VMS_LOCALUNIT
  5. */
  6. #ifdef HAVE_CONFIG_H
  7. #include <config.h>
  8. #endif
  9. #ifdef REFCLOCK
  10. #include "ntpd.h"
  11. #include "ntp_refclock.h"
  12. #include "ntp_stdlib.h"
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #ifdef KERNEL_PLL
  16. #include "ntp_syscall.h"
  17. #endif
  18. /*
  19. * This is a hack to allow a machine to use its own system clock as a
  20. * reference clock, i.e., to free-run using no outside clock discipline
  21. * source. This is useful if you want to use NTP in an isolated
  22. * environment with no radio clock or NIST modem available. Pick a
  23. * machine that you figure has a good clock oscillator and configure it
  24. * with this driver. Set the clock using the best means available, like
  25. * eyeball-and-wristwatch. Then, point all the other machines at this
  26. * one or use broadcast (not multicast) mode to distribute time.
  27. *
  28. * Another application for this driver is if you want to use a
  29. * particular server's clock as the clock of last resort when all other
  30. * normal synchronization sources have gone away. This is especially
  31. * useful if that server has an ovenized oscillator. For this you would
  32. * configure this driver at a higher stratum (say 5) to prevent the
  33. * server's stratum from falling below that.
  34. *
  35. * A third application for this driver is when an external discipline
  36. * source is available, such as the NIST "lockclock" program, which
  37. * synchronizes the local clock via a telephone modem and the NIST
  38. * Automated Computer Time Service (ACTS), or the Digital Time
  39. * Synchronization Service (DTSS), which runs on DCE machines. In this
  40. * case the stratum should be set at zero, indicating a bona fide
  41. * stratum-1 source. Exercise some caution with this, since there is no
  42. * easy way to telegraph via NTP that something might be wrong in the
  43. * discipline source itself. In the case of DTSS, the local clock can
  44. * have a rather large jitter, depending on the interval between
  45. * corrections and the intrinsic frequency error of the clock
  46. * oscillator. In extreme cases, this can cause clients to exceed the
  47. * 128-ms slew window and drop off the NTP subnet.
  48. *
  49. * THis driver includes provisions to telegraph synchronization state
  50. * and related variables by means of kernel variables with specially
  51. * modified kernels. This is done using the ntp_adjtime() syscall.
  52. * In the cases where another protocol or device synchronizes the local
  53. * host, the data given to the kernel can be slurped up by this driver
  54. * and distributed to clients by ordinary NTP messaging.
  55. *
  56. * In the default mode the behavior of the clock selection algorithm is
  57. * modified when this driver is in use. The algorithm is designed so
  58. * that this driver will never be selected unless no other discipline
  59. * source is available. This can be overriden with the prefer keyword of
  60. * the server configuration command, in which case only this driver will
  61. * be selected for synchronization and all other discipline sources will
  62. * be ignored. This behavior is intended for use when an external
  63. * discipline source controls the system clock.
  64. *
  65. * Fudge Factors
  66. *
  67. * The stratum for this driver set at 5 by default, but it can be
  68. * changed by the fudge command and/or the ntpdc utility. The reference
  69. * ID is 127.0.0.1 by default, but can be changed using the same mechanism.
  70. * *NEVER* configure this driver to operate at a stratum which might
  71. * possibly disrupt a client with access to a bona fide primary server,
  72. * unless the local clock oscillator is reliably disciplined by another
  73. * source. *NEVER NEVER* configure a server which might devolve to an
  74. * undisciplined local clock to use multicast mode. Always remember that
  75. * an improperly configured local clock driver let loose in the Internet
  76. * can cause very serious disruption. This is why most of us who care
  77. * about good time use cryptographic authentication.
  78. *
  79. * This driver provides a mechanism to trim the local clock in both time
  80. * and frequency, as well as a way to manipulate the leap bits. The
  81. * fudge time1 parameter adjusts the time, in seconds, and the fudge
  82. * time2 parameter adjusts the frequency, in ppm. The fudge time1
  83. * parameter is additive; that is, it adds an increment to the current
  84. * time. The fudge time2 parameter directly sets the frequency.
  85. */
  86. /*
  87. * Local interface definitions
  88. */
  89. #define PRECISION (-7) /* about 10 ms precision */
  90. #define DESCRIPTION "Undisciplined local clock" /* WRU */
  91. #define STRATUM 5 /* default stratum */
  92. #define DISPERSION .01 /* default dispersion (10 ms) */
  93. /*
  94. * Imported from the timer module
  95. */
  96. extern u_long current_time;
  97. /*
  98. * Imported from ntp_proto
  99. */
  100. extern s_char sys_precision;
  101. #ifdef KERNEL_PLL
  102. /*
  103. * Imported from ntp_loopfilter
  104. */
  105. extern int pll_control; /* kernel pll control */
  106. extern int kern_enable; /* kernel pll enabled */
  107. extern int ext_enable; /* external clock enable */
  108. #endif /* KERNEL_PLL */
  109. /*
  110. * Function prototypes
  111. */
  112. static int local_start P((int, struct peer *));
  113. static void local_poll P((int, struct peer *));
  114. /*
  115. * Local variables
  116. */
  117. static u_long poll_time; /* last time polled */
  118. /*
  119. * Transfer vector
  120. */
  121. struct refclock refclock_local = {
  122. local_start, /* start up driver */
  123. noentry, /* shut down driver (not used) */
  124. local_poll, /* transmit poll message */
  125. noentry, /* not used (old lcl_control) */
  126. noentry, /* initialize driver (not used) */
  127. noentry, /* not used (old lcl_buginfo) */
  128. NOFLAGS /* not used */
  129. };
  130. /*
  131. * local_start - start up the clock
  132. */
  133. static int
  134. local_start(
  135. int unit,
  136. struct peer *peer
  137. )
  138. {
  139. struct refclockproc *pp;
  140. pp = peer->procptr;
  141. /*
  142. * Initialize miscellaneous variables
  143. */
  144. peer->precision = sys_precision;
  145. pp->leap = LEAP_NOTINSYNC;
  146. peer->stratum = STRATUM;
  147. pp->stratum = STRATUM;
  148. pp->clockdesc = DESCRIPTION;
  149. memcpy(&pp->refid, "LOCL", 4);
  150. poll_time = current_time;
  151. return (1);
  152. }
  153. /*
  154. * local_poll - called by the transmit procedure
  155. *
  156. * LOCKCLOCK: If the kernel supports the nanokernel or microkernel
  157. * system calls, the leap bits are extracted from the kernel. If there
  158. * is a kernel error or the kernel leap bits are set to 11, the NTP leap
  159. * bits are set to 11 and the stratum is set to infinity. Otherwise, the
  160. * NTP leap bits are set to the kernel leap bits and the stratum is set
  161. * as fudged. This behavior does not faithfully follow the
  162. * specification, but is probably more appropriate in a multiple-server
  163. * national laboratory network.
  164. */
  165. static void
  166. local_poll(
  167. int unit,
  168. struct peer *peer
  169. )
  170. {
  171. #if defined(KERNEL_PLL) && defined(LOCKCLOCK)
  172. struct timex ntv;
  173. #endif /* KERNEL_PLL LOCKCLOCK */
  174. struct refclockproc *pp;
  175. #if defined(VMS) && defined(VMS_LOCALUNIT)
  176. if (unit == VMS_LOCALUNIT) {
  177. extern void vms_local_poll(struct peer *);
  178. vms_local_poll(peer);
  179. return;
  180. }
  181. #endif /* VMS && VMS_LOCALUNIT */
  182. pp = peer->procptr;
  183. pp->polls++;
  184. /*
  185. * Ramble through the usual filtering and grooming code, which
  186. * is essentially a no-op and included mostly for pretty
  187. * billboards. We allow a one-time time adjustment using fudge
  188. * time1 (s) and a continuous frequency adjustment using fudge
  189. * time 2 (ppm).
  190. */
  191. get_systime(&pp->lastrec);
  192. pp->fudgetime1 += pp->fudgetime2 * 1e-6 * (current_time -
  193. poll_time);
  194. poll_time = current_time;
  195. refclock_process_offset(pp, pp->lastrec, pp->lastrec,
  196. pp->fudgetime1);
  197. /*
  198. * If another process is disciplining the system clock, we set
  199. * the leap bits and quality indicators from the kernel.
  200. */
  201. #if defined(KERNEL_PLL) && defined(LOCKCLOCK)
  202. memset(&ntv, 0, sizeof ntv);
  203. switch (ntp_adjtime(&ntv)) {
  204. case TIME_OK:
  205. pp->leap = LEAP_NOWARNING;
  206. peer->stratum = pp->stratum;
  207. break;
  208. case TIME_INS:
  209. pp->leap = LEAP_ADDSECOND;
  210. peer->stratum = pp->stratum;
  211. break;
  212. case TIME_DEL:
  213. pp->leap = LEAP_DELSECOND;
  214. peer->stratum = pp->stratum;
  215. break;
  216. default:
  217. pp->leap = LEAP_NOTINSYNC;
  218. peer->stratum = STRATUM_UNSPEC;
  219. }
  220. pp->disp = 0;
  221. pp->jitter = 0;
  222. #else /* KERNEL_PLL LOCKCLOCK */
  223. pp->leap = LEAP_NOWARNING;
  224. pp->disp = DISPERSION;
  225. pp->jitter = 0;
  226. #endif /* KERNEL_PLL LOCKCLOCK */
  227. pp->lastref = pp->lastrec;
  228. refclock_receive(peer);
  229. pp->fudgetime1 = 0;
  230. }
  231. #else
  232. int refclock_local_bs;
  233. #endif /* REFCLOCK */