Coverage Report

Created: 2023-05-19 06:16

/src/ntp-dev/ntpd/refclock_local.c
Line
Count
Source (jump to first uncovered line)
1
2
/*
3
 * refclock_local - local pseudo-clock driver
4
 *
5
 * wjm 17-aug-1995: add a hook for special treatment of VMS_LOCALUNIT
6
 */
7
#ifdef HAVE_CONFIG_H
8
#include <config.h>
9
#endif
10
11
#ifdef REFCLOCK
12
13
#include "ntpd.h"
14
#include "ntp_refclock.h"
15
#include "ntp_stdlib.h"
16
17
#include <stdio.h>
18
#include <ctype.h>
19
20
#ifdef KERNEL_PLL
21
#include "ntp_syscall.h"
22
#endif
23
24
/*
25
 * This is a hack to allow a machine to use its own system clock as a
26
 * reference clock, i.e., to free-run using no outside clock discipline
27
 * source. Note that the clock selection algorithm will not select this
28
 * driver unless all other sources of synchronization have been lost.
29
 * This is useful if you want to use NTP in an isolated environment
30
 * with no radio clock or NIST modem available. Pick a machine that you
31
 * figure has a good clock oscillator and configure it with this
32
 * driver. Set the clock using the best means available, like
33
 * eyeball-and-wristwatch. Then, point all the other machines at this
34
 * one or use broadcast (not multicast) mode to distribute time.
35
 *
36
 * Another application for this driver is if you want to use a
37
 * particular server's clock as the clock of last resort when all other
38
 * normal synchronization sources have gone away. This is especially
39
 * useful if that server has an ovenized oscillator. However, the
40
 * preferred was to do this is using orphan mode. See the documentation.
41
 *
42
 * A third application for this driver is when an external discipline
43
 * source is available, such as the NIST "lockclock" program, which
44
 * synchronizes the local clock via a telephone modem and the NIST
45
 * Automated Computer Time Service (ACTS), or the Digital Time
46
 * Synchronization Service (DTSS), which runs on DCE machines. In this
47
 * case the stratum should be set at zero, indicating a bona fide
48
 * stratum-1 source. Exercise some caution with this, since there is no
49
 * easy way to telegraph via NTP that something might be wrong in the
50
 * discipline source itself. In the case of DTSS, the local clock can
51
 * have a rather large jitter, depending on the interval between
52
 * corrections and the intrinsic frequency error of the clock
53
 * oscillator. In extreme cases, this can cause clients to exceed the
54
 * 128-ms slew window and drop off the NTP subnet.
55
 *
56
 * Fudge Factors
57
 *
58
 * None currently supported.
59
 */
60
/*
61
 * Local interface definitions
62
 */
63
#define PRECISION (-7)  /* about 10 ms precision */
64
0
#define DESCRIPTION "Undisciplined local clock" /* WRU */
65
0
#define STRATUM   5  /* default stratum */
66
0
#define DISPERSION  .01  /* default dispersion (10 ms) */
67
68
/*
69
 * Imported from the timer module
70
 */
71
extern u_long current_time;
72
73
/*
74
 * Imported from ntp_proto
75
 */
76
extern s_char sys_precision;
77
78
/*
79
 * Function prototypes
80
 */
81
static  int local_start (int, struct peer *);
82
static  void  local_poll  (int, struct peer *);
83
84
/*
85
 * Local variables
86
 */
87
static  u_long poll_time; /* last time polled */
88
  
89
/*
90
 * Transfer vector
91
 */
92
struct  refclock refclock_local = {
93
  local_start,    /* start up driver */
94
  noentry,    /* shut down driver (not used) */
95
  local_poll,   /* transmit poll message */
96
  noentry,    /* not used (old lcl_control) */
97
  noentry,    /* initialize driver (not used) */
98
  noentry,    /* not used (old lcl_buginfo) */
99
  NOFLAGS     /* not used */
100
};
101
102
103
/*
104
 * local_start - start up the clock
105
 */
106
static int
107
local_start(
108
  int unit,
109
  struct peer *peer
110
  )
111
0
{
112
0
  struct refclockproc *pp;
113
114
0
  pp = peer->procptr;
115
116
  /*
117
   * Initialize miscellaneous variables
118
   */
119
0
  peer->precision = sys_precision;
120
0
  pp->leap = LEAP_NOTINSYNC;
121
0
  peer->stratum = STRATUM;
122
0
  pp->stratum = STRATUM;
123
0
  pp->clockdesc = DESCRIPTION;
124
0
  memcpy(&pp->refid, "LOCL", 4);
125
0
  poll_time = current_time;
126
0
  return (1);
127
0
}
128
129
130
/*
131
 * local_poll - called by the transmit procedure
132
 *
133
 * LOCKCLOCK: If the kernel supports the nanokernel or microkernel
134
 * system calls, the leap bits are extracted from the kernel. If there
135
 * is a kernel error or the kernel leap bits are set to 11, the NTP leap
136
 * bits are set to 11 and the stratum is set to infinity. Otherwise, the
137
 * NTP leap bits are set to the kernel leap bits and the stratum is set
138
 * as fudged. This behavior does not faithfully follow the
139
 * specification, but is probably more appropriate in a multiple-server
140
 * national laboratory network.
141
 */
142
static void
143
local_poll(
144
  int unit,
145
  struct peer *peer
146
  )
147
0
{
148
#if defined(KERNEL_PLL) && defined(LOCKCLOCK)
149
  struct timex ntv;
150
#endif /* KERNEL_PLL LOCKCLOCK */
151
0
  struct refclockproc *pp;
152
153
  /*
154
   * Do no evil unless the house is dark or lit with our own lamp.
155
   */
156
0
  if (!(sys_peer == NULL || sys_peer == peer))
157
0
    return;
158
159
#if defined(VMS) && defined(VMS_LOCALUNIT)
160
  if (unit == VMS_LOCALUNIT) {
161
    extern void vms_local_poll(struct peer *);
162
163
    vms_local_poll(peer);
164
    return;
165
  }
166
#endif /* VMS && VMS_LOCALUNIT */
167
168
0
  pp = peer->procptr;
169
0
  pp->polls++;
170
171
  /*
172
   * Ramble through the usual filtering and grooming code, which
173
   * is essentially a no-op and included mostly for pretty
174
   * billboards.
175
   */
176
0
  poll_time = current_time;
177
0
  refclock_process_offset(pp, pp->lastrec, pp->lastrec, 0);
178
179
  /*
180
   * If another process is disciplining the system clock, we set
181
   * the leap bits and quality indicators from the kernel.
182
   */
183
#if defined(KERNEL_PLL) && defined(LOCKCLOCK)
184
  memset(&ntv,  0, sizeof ntv);
185
  switch (ntp_adjtime(&ntv)) {
186
  case TIME_OK:
187
    pp->leap = LEAP_NOWARNING;
188
    peer->stratum = pp->stratum;
189
    break;
190
191
  case TIME_INS:
192
    pp->leap = LEAP_ADDSECOND;
193
    peer->stratum = pp->stratum;
194
    break;
195
196
  case TIME_DEL:
197
    pp->leap = LEAP_DELSECOND;
198
    peer->stratum = pp->stratum;
199
    break;
200
201
  default:
202
    pp->leap = LEAP_NOTINSYNC;
203
    peer->stratum = STRATUM_UNSPEC;
204
  }
205
  pp->disp = 0;
206
  pp->jitter = 0;
207
#else /* KERNEL_PLL LOCKCLOCK */
208
0
  pp->leap = LEAP_NOWARNING;
209
0
  pp->disp = DISPERSION;
210
0
  pp->jitter = 0;
211
0
#endif /* KERNEL_PLL LOCKCLOCK */
212
0
  pp->lastref = pp->lastrec;
213
0
  refclock_receive(peer);
214
0
}
215
#else
216
int refclock_local_bs;
217
#endif /* REFCLOCK */