xref: /netbsd-src/external/bsd/ntp/dist/ntpd/ntp_control.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /*	$NetBSD: ntp_control.c,v 1.7 2013/12/28 03:20:14 christos Exp $	*/
2 
3 /*
4  * ntp_control.c - respond to mode 6 control messages and send async
5  *		   traps.  Provides service to ntpq and others.
6  */
7 
8 #ifdef HAVE_CONFIG_H
9 # include <config.h>
10 #endif
11 
12 #include <stdio.h>
13 #include <ctype.h>
14 #include <signal.h>
15 #include <sys/stat.h>
16 #ifdef HAVE_NETINET_IN_H
17 # include <netinet/in.h>
18 #endif
19 #include <arpa/inet.h>
20 
21 #include "ntpd.h"
22 #include "ntp_io.h"
23 #include "ntp_refclock.h"
24 #include "ntp_control.h"
25 #include "ntp_unixtime.h"
26 #include "ntp_stdlib.h"
27 #include "ntp_config.h"
28 #include "ntp_crypto.h"
29 #include "ntp_assert.h"
30 #include "ntp_leapsec.h"
31 #include "ntp_md5.h"	/* provides OpenSSL digest API */
32 #include "lib_strbuf.h"
33 #ifdef KERNEL_PLL
34 # include "ntp_syscall.h"
35 #endif
36 
37 
38 /*
39  * Structure to hold request procedure information
40  */
41 
42 struct ctl_proc {
43 	short control_code;		/* defined request code */
44 #define NO_REQUEST	(-1)
45 	u_short flags;			/* flags word */
46 	/* Only one flag.  Authentication required or not. */
47 #define NOAUTH	0
48 #define AUTH	1
49 	void (*handler) (struct recvbuf *, int); /* handle request */
50 };
51 
52 
53 /*
54  * Request processing routines
55  */
56 static	void	ctl_error	(u_char);
57 #ifdef REFCLOCK
58 static	u_short ctlclkstatus	(struct refclockstat *);
59 #endif
60 static	void	ctl_flushpkt	(u_char);
61 static	void	ctl_putdata	(const char *, unsigned int, int);
62 static	void	ctl_putstr	(const char *, const char *, size_t);
63 static	void	ctl_putdblf	(const char *, const char *, double);
64 const char ctl_def_dbl_fmt[] = "%.3f";
65 #define	ctl_putdbl(tag, d)	ctl_putdblf(tag, ctl_def_dbl_fmt, d)
66 const char ctl_def_dbl6_fmt[] = "%.6f";
67 #define	ctl_putdbl6(tag, d)	ctl_putdblf(tag, ctl_def_dbl6_fmt, d)
68 const char ctl_def_sfp_fmt[] = "%g";
69 #define	ctl_putsfp(tag, sfp)	ctl_putdblf(tag, ctl_def_sfp_fmt, \
70 					    FPTOD(sfp))
71 static	void	ctl_putuint	(const char *, u_long);
72 static	void	ctl_puthex	(const char *, u_long);
73 static	void	ctl_putint	(const char *, long);
74 static	void	ctl_putts	(const char *, l_fp *);
75 static	void	ctl_putadr	(const char *, u_int32,
76 				 sockaddr_u *);
77 static	void	ctl_putrefid	(const char *, u_int32);
78 static	void	ctl_putarray	(const char *, double *, int);
79 static	void	ctl_putsys	(int);
80 static	void	ctl_putpeer	(int, struct peer *);
81 static	void	ctl_putfs	(const char *, tstamp_t);
82 #ifdef REFCLOCK
83 static	void	ctl_putclock	(int, struct refclockstat *, int);
84 #endif	/* REFCLOCK */
85 static	const struct ctl_var *ctl_getitem(const struct ctl_var *,
86 					  char **);
87 static	u_short	count_var	(const struct ctl_var *);
88 static	void	control_unspec	(struct recvbuf *, int);
89 static	void	read_status	(struct recvbuf *, int);
90 static	void	read_sysvars	(void);
91 static	void	read_peervars	(void);
92 static	void	read_variables	(struct recvbuf *, int);
93 static	void	write_variables (struct recvbuf *, int);
94 static	void	read_clockstatus(struct recvbuf *, int);
95 static	void	write_clockstatus(struct recvbuf *, int);
96 static	void	set_trap	(struct recvbuf *, int);
97 static	void	save_config	(struct recvbuf *, int);
98 static	void	configure	(struct recvbuf *, int);
99 static	void	send_mru_entry	(mon_entry *, int);
100 static	void	send_random_tag_value(int);
101 static	void	read_mru_list	(struct recvbuf *, int);
102 static	void	send_ifstats_entry(endpt *, u_int);
103 static	void	read_ifstats	(struct recvbuf *);
104 static	void	sockaddrs_from_restrict_u(sockaddr_u *,	sockaddr_u *,
105 					  restrict_u *, int);
106 static	void	send_restrict_entry(restrict_u *, int, u_int);
107 static	void	send_restrict_list(restrict_u *, int, u_int *);
108 static	void	read_addr_restrictions(struct recvbuf *);
109 static	void	read_ordlist	(struct recvbuf *, int);
110 static	u_int32	derive_nonce	(sockaddr_u *, u_int32, u_int32);
111 static	void	generate_nonce	(struct recvbuf *, char *, size_t);
112 static	int	validate_nonce	(const char *, struct recvbuf *);
113 static	void	req_nonce	(struct recvbuf *, int);
114 static	void	unset_trap	(struct recvbuf *, int);
115 static	struct ctl_trap *ctlfindtrap(sockaddr_u *,
116 				     struct interface *);
117 
118 static const struct ctl_proc control_codes[] = {
119 	{ CTL_OP_UNSPEC,		NOAUTH,	control_unspec },
120 	{ CTL_OP_READSTAT,		NOAUTH,	read_status },
121 	{ CTL_OP_READVAR,		NOAUTH,	read_variables },
122 	{ CTL_OP_WRITEVAR,		AUTH,	write_variables },
123 	{ CTL_OP_READCLOCK,		NOAUTH,	read_clockstatus },
124 	{ CTL_OP_WRITECLOCK,		NOAUTH,	write_clockstatus },
125 	{ CTL_OP_SETTRAP,		NOAUTH,	set_trap },
126 	{ CTL_OP_CONFIGURE,		AUTH,	configure },
127 	{ CTL_OP_SAVECONFIG,		AUTH,	save_config },
128 	{ CTL_OP_READ_MRU,		NOAUTH,	read_mru_list },
129 	{ CTL_OP_READ_ORDLIST_A,	AUTH,	read_ordlist },
130 	{ CTL_OP_REQ_NONCE,		NOAUTH,	req_nonce },
131 	{ CTL_OP_UNSETTRAP,		NOAUTH,	unset_trap },
132 	{ NO_REQUEST,			0,	NULL }
133 };
134 
135 /*
136  * System variables we understand
137  */
138 #define	CS_LEAP			1
139 #define	CS_STRATUM		2
140 #define	CS_PRECISION		3
141 #define	CS_ROOTDELAY		4
142 #define	CS_ROOTDISPERSION	5
143 #define	CS_REFID		6
144 #define	CS_REFTIME		7
145 #define	CS_POLL			8
146 #define	CS_PEERID		9
147 #define	CS_OFFSET		10
148 #define	CS_DRIFT		11
149 #define	CS_JITTER		12
150 #define	CS_ERROR		13
151 #define	CS_CLOCK		14
152 #define	CS_PROCESSOR		15
153 #define	CS_SYSTEM		16
154 #define	CS_VERSION		17
155 #define	CS_STABIL		18
156 #define	CS_VARLIST		19
157 #define	CS_TAI			20
158 #define	CS_LEAPTAB		21
159 #define	CS_LEAPEND		22
160 #define	CS_RATE			23
161 #define	CS_MRU_ENABLED		24
162 #define	CS_MRU_DEPTH		25
163 #define	CS_MRU_DEEPEST		26
164 #define	CS_MRU_MINDEPTH		27
165 #define	CS_MRU_MAXAGE		28
166 #define	CS_MRU_MAXDEPTH		29
167 #define	CS_MRU_MEM		30
168 #define	CS_MRU_MAXMEM		31
169 #define	CS_SS_UPTIME		32
170 #define	CS_SS_RESET		33
171 #define	CS_SS_RECEIVED		34
172 #define	CS_SS_THISVER		35
173 #define	CS_SS_OLDVER		36
174 #define	CS_SS_BADFORMAT		37
175 #define	CS_SS_BADAUTH		38
176 #define	CS_SS_DECLINED		39
177 #define	CS_SS_RESTRICTED	40
178 #define	CS_SS_LIMITED		41
179 #define	CS_SS_KODSENT		42
180 #define	CS_SS_PROCESSED		43
181 #define	CS_PEERADR		44
182 #define	CS_PEERMODE		45
183 #define	CS_BCASTDELAY		46
184 #define	CS_AUTHDELAY		47
185 #define	CS_AUTHKEYS		48
186 #define	CS_AUTHFREEK		49
187 #define	CS_AUTHKLOOKUPS		50
188 #define	CS_AUTHKNOTFOUND	51
189 #define	CS_AUTHKUNCACHED	52
190 #define	CS_AUTHKEXPIRED		53
191 #define	CS_AUTHENCRYPTS		54
192 #define	CS_AUTHDECRYPTS		55
193 #define	CS_AUTHRESET		56
194 #define	CS_K_OFFSET		57
195 #define	CS_K_FREQ		58
196 #define	CS_K_MAXERR		59
197 #define	CS_K_ESTERR		60
198 #define	CS_K_STFLAGS		61
199 #define	CS_K_TIMECONST		62
200 #define	CS_K_PRECISION		63
201 #define	CS_K_FREQTOL		64
202 #define	CS_K_PPS_FREQ		65
203 #define	CS_K_PPS_STABIL		66
204 #define	CS_K_PPS_JITTER		67
205 #define	CS_K_PPS_CALIBDUR	68
206 #define	CS_K_PPS_CALIBS		69
207 #define	CS_K_PPS_CALIBERRS	70
208 #define	CS_K_PPS_JITEXC		71
209 #define	CS_K_PPS_STBEXC		72
210 #define	CS_KERN_FIRST		CS_K_OFFSET
211 #define	CS_KERN_LAST		CS_K_PPS_STBEXC
212 #define	CS_IOSTATS_RESET	73
213 #define	CS_TOTAL_RBUF		74
214 #define	CS_FREE_RBUF		75
215 #define	CS_USED_RBUF		76
216 #define	CS_RBUF_LOWATER		77
217 #define	CS_IO_DROPPED		78
218 #define	CS_IO_IGNORED		79
219 #define	CS_IO_RECEIVED		80
220 #define	CS_IO_SENT		81
221 #define	CS_IO_SENDFAILED	82
222 #define	CS_IO_WAKEUPS		83
223 #define	CS_IO_GOODWAKEUPS	84
224 #define	CS_TIMERSTATS_RESET	85
225 #define	CS_TIMER_OVERRUNS	86
226 #define	CS_TIMER_XMTS		87
227 #define	CS_FUZZ			88
228 #define	CS_MAX_NOAUTOKEY	CS_FUZZ
229 #ifdef AUTOKEY
230 #define	CS_FLAGS		(1 + CS_MAX_NOAUTOKEY)
231 #define	CS_HOST			(2 + CS_MAX_NOAUTOKEY)
232 #define	CS_PUBLIC		(3 + CS_MAX_NOAUTOKEY)
233 #define	CS_CERTIF		(4 + CS_MAX_NOAUTOKEY)
234 #define	CS_SIGNATURE		(5 + CS_MAX_NOAUTOKEY)
235 #define	CS_REVTIME		(6 + CS_MAX_NOAUTOKEY)
236 #define	CS_IDENT		(7 + CS_MAX_NOAUTOKEY)
237 #define	CS_DIGEST		(8 + CS_MAX_NOAUTOKEY)
238 #define	CS_MAXCODE		CS_DIGEST
239 #else	/* !AUTOKEY follows */
240 #define	CS_MAXCODE		CS_MAX_NOAUTOKEY
241 #endif	/* !AUTOKEY */
242 
243 /*
244  * Peer variables we understand
245  */
246 #define	CP_CONFIG		1
247 #define	CP_AUTHENABLE		2
248 #define	CP_AUTHENTIC		3
249 #define	CP_SRCADR		4
250 #define	CP_SRCPORT		5
251 #define	CP_DSTADR		6
252 #define	CP_DSTPORT		7
253 #define	CP_LEAP			8
254 #define	CP_HMODE		9
255 #define	CP_STRATUM		10
256 #define	CP_PPOLL		11
257 #define	CP_HPOLL		12
258 #define	CP_PRECISION		13
259 #define	CP_ROOTDELAY		14
260 #define	CP_ROOTDISPERSION	15
261 #define	CP_REFID		16
262 #define	CP_REFTIME		17
263 #define	CP_ORG			18
264 #define	CP_REC			19
265 #define	CP_XMT			20
266 #define	CP_REACH		21
267 #define	CP_UNREACH		22
268 #define	CP_TIMER		23
269 #define	CP_DELAY		24
270 #define	CP_OFFSET		25
271 #define	CP_JITTER		26
272 #define	CP_DISPERSION		27
273 #define	CP_KEYID		28
274 #define	CP_FILTDELAY		29
275 #define	CP_FILTOFFSET		30
276 #define	CP_PMODE		31
277 #define	CP_RECEIVED		32
278 #define	CP_SENT			33
279 #define	CP_FILTERROR		34
280 #define	CP_FLASH		35
281 #define	CP_TTL			36
282 #define	CP_VARLIST		37
283 #define	CP_IN			38
284 #define	CP_OUT			39
285 #define	CP_RATE			40
286 #define	CP_BIAS			41
287 #define	CP_SRCHOST		42
288 #define	CP_TIMEREC		43
289 #define	CP_TIMEREACH		44
290 #define	CP_BADAUTH		45
291 #define	CP_BOGUSORG		46
292 #define	CP_OLDPKT		47
293 #define	CP_SELDISP		48
294 #define	CP_SELBROKEN		49
295 #define	CP_CANDIDATE		50
296 #define	CP_MAX_NOAUTOKEY	CP_CANDIDATE
297 #ifdef AUTOKEY
298 #define	CP_FLAGS		(1 + CP_MAX_NOAUTOKEY)
299 #define	CP_HOST			(2 + CP_MAX_NOAUTOKEY)
300 #define	CP_VALID		(3 + CP_MAX_NOAUTOKEY)
301 #define	CP_INITSEQ		(4 + CP_MAX_NOAUTOKEY)
302 #define	CP_INITKEY		(5 + CP_MAX_NOAUTOKEY)
303 #define	CP_INITTSP		(6 + CP_MAX_NOAUTOKEY)
304 #define	CP_SIGNATURE		(7 + CP_MAX_NOAUTOKEY)
305 #define	CP_IDENT		(8 + CP_MAX_NOAUTOKEY)
306 #define	CP_MAXCODE		CP_IDENT
307 #else	/* !AUTOKEY follows */
308 #define	CP_MAXCODE		CP_MAX_NOAUTOKEY
309 #endif	/* !AUTOKEY */
310 
311 /*
312  * Clock variables we understand
313  */
314 #define	CC_TYPE		1
315 #define	CC_TIMECODE	2
316 #define	CC_POLL		3
317 #define	CC_NOREPLY	4
318 #define	CC_BADFORMAT	5
319 #define	CC_BADDATA	6
320 #define	CC_FUDGETIME1	7
321 #define	CC_FUDGETIME2	8
322 #define	CC_FUDGEVAL1	9
323 #define	CC_FUDGEVAL2	10
324 #define	CC_FLAGS	11
325 #define	CC_DEVICE	12
326 #define	CC_VARLIST	13
327 #define	CC_MAXCODE	CC_VARLIST
328 
329 /*
330  * System variable values. The array can be indexed by the variable
331  * index to find the textual name.
332  */
333 static const struct ctl_var sys_var[] = {
334 	{ 0,		PADDING, "" },		/* 0 */
335 	{ CS_LEAP,	RW, "leap" },		/* 1 */
336 	{ CS_STRATUM,	RO, "stratum" },	/* 2 */
337 	{ CS_PRECISION, RO, "precision" },	/* 3 */
338 	{ CS_ROOTDELAY, RO, "rootdelay" },	/* 4 */
339 	{ CS_ROOTDISPERSION, RO, "rootdisp" },	/* 5 */
340 	{ CS_REFID,	RO, "refid" },		/* 6 */
341 	{ CS_REFTIME,	RO, "reftime" },	/* 7 */
342 	{ CS_POLL,	RO, "tc" },		/* 8 */
343 	{ CS_PEERID,	RO, "peer" },		/* 9 */
344 	{ CS_OFFSET,	RO, "offset" },		/* 10 */
345 	{ CS_DRIFT,	RO, "frequency" },	/* 11 */
346 	{ CS_JITTER,	RO, "sys_jitter" },	/* 12 */
347 	{ CS_ERROR,	RO, "clk_jitter" },	/* 13 */
348 	{ CS_CLOCK,	RO, "clock" },		/* 14 */
349 	{ CS_PROCESSOR, RO, "processor" },	/* 15 */
350 	{ CS_SYSTEM,	RO, "system" },		/* 16 */
351 	{ CS_VERSION,	RO, "version" },	/* 17 */
352 	{ CS_STABIL,	RO, "clk_wander" },	/* 18 */
353 	{ CS_VARLIST,	RO, "sys_var_list" },	/* 19 */
354 	{ CS_TAI,	RO, "tai" },		/* 20 */
355 	{ CS_LEAPTAB,	RO, "leapsec" },	/* 21 */
356 	{ CS_LEAPEND,	RO, "expire" },		/* 22 */
357 	{ CS_RATE,	RO, "mintc" },		/* 23 */
358 	{ CS_MRU_ENABLED,	RO, "mru_enabled" },	/* 24 */
359 	{ CS_MRU_DEPTH,		RO, "mru_depth" },	/* 25 */
360 	{ CS_MRU_DEEPEST,	RO, "mru_deepest" },	/* 26 */
361 	{ CS_MRU_MINDEPTH,	RO, "mru_mindepth" },	/* 27 */
362 	{ CS_MRU_MAXAGE,	RO, "mru_maxage" },	/* 28 */
363 	{ CS_MRU_MAXDEPTH,	RO, "mru_maxdepth" },	/* 29 */
364 	{ CS_MRU_MEM,		RO, "mru_mem" },	/* 30 */
365 	{ CS_MRU_MAXMEM,	RO, "mru_maxmem" },	/* 31 */
366 	{ CS_SS_UPTIME,		RO, "ss_uptime" },	/* 32 */
367 	{ CS_SS_RESET,		RO, "ss_reset" },	/* 33 */
368 	{ CS_SS_RECEIVED,	RO, "ss_received" },	/* 34 */
369 	{ CS_SS_THISVER,	RO, "ss_thisver" },	/* 35 */
370 	{ CS_SS_OLDVER,		RO, "ss_oldver" },	/* 36 */
371 	{ CS_SS_BADFORMAT,	RO, "ss_badformat" },	/* 37 */
372 	{ CS_SS_BADAUTH,	RO, "ss_badauth" },	/* 38 */
373 	{ CS_SS_DECLINED,	RO, "ss_declined" },	/* 39 */
374 	{ CS_SS_RESTRICTED,	RO, "ss_restricted" },	/* 40 */
375 	{ CS_SS_LIMITED,	RO, "ss_limited" },	/* 41 */
376 	{ CS_SS_KODSENT,	RO, "ss_kodsent" },	/* 42 */
377 	{ CS_SS_PROCESSED,	RO, "ss_processed" },	/* 43 */
378 	{ CS_PEERADR,		RO, "peeradr" },	/* 44 */
379 	{ CS_PEERMODE,		RO, "peermode" },	/* 45 */
380 	{ CS_BCASTDELAY,	RO, "bcastdelay" },	/* 46 */
381 	{ CS_AUTHDELAY,		RO, "authdelay" },	/* 47 */
382 	{ CS_AUTHKEYS,		RO, "authkeys" },	/* 48 */
383 	{ CS_AUTHFREEK,		RO, "authfreek" },	/* 49 */
384 	{ CS_AUTHKLOOKUPS,	RO, "authklookups" },	/* 50 */
385 	{ CS_AUTHKNOTFOUND,	RO, "authknotfound" },	/* 51 */
386 	{ CS_AUTHKUNCACHED,	RO, "authkuncached" },	/* 52 */
387 	{ CS_AUTHKEXPIRED,	RO, "authkexpired" },	/* 53 */
388 	{ CS_AUTHENCRYPTS,	RO, "authencrypts" },	/* 54 */
389 	{ CS_AUTHDECRYPTS,	RO, "authdecrypts" },	/* 55 */
390 	{ CS_AUTHRESET,		RO, "authreset" },	/* 56 */
391 	{ CS_K_OFFSET,		RO, "koffset" },	/* 57 */
392 	{ CS_K_FREQ,		RO, "kfreq" },		/* 58 */
393 	{ CS_K_MAXERR,		RO, "kmaxerr" },	/* 59 */
394 	{ CS_K_ESTERR,		RO, "kesterr" },	/* 60 */
395 	{ CS_K_STFLAGS,		RO, "kstflags" },	/* 61 */
396 	{ CS_K_TIMECONST,	RO, "ktimeconst" },	/* 62 */
397 	{ CS_K_PRECISION,	RO, "kprecis" },	/* 63 */
398 	{ CS_K_FREQTOL,		RO, "kfreqtol" },	/* 64 */
399 	{ CS_K_PPS_FREQ,	RO, "kppsfreq" },	/* 65 */
400 	{ CS_K_PPS_STABIL,	RO, "kppsstab" },	/* 66 */
401 	{ CS_K_PPS_JITTER,	RO, "kppsjitter" },	/* 67 */
402 	{ CS_K_PPS_CALIBDUR,	RO, "kppscalibdur" },	/* 68 */
403 	{ CS_K_PPS_CALIBS,	RO, "kppscalibs" },	/* 69 */
404 	{ CS_K_PPS_CALIBERRS,	RO, "kppscaliberrs" },	/* 70 */
405 	{ CS_K_PPS_JITEXC,	RO, "kppsjitexc" },	/* 71 */
406 	{ CS_K_PPS_STBEXC,	RO, "kppsstbexc" },	/* 72 */
407 	{ CS_IOSTATS_RESET,	RO, "iostats_reset" },	/* 73 */
408 	{ CS_TOTAL_RBUF,	RO, "total_rbuf" },	/* 74 */
409 	{ CS_FREE_RBUF,		RO, "free_rbuf" },	/* 75 */
410 	{ CS_USED_RBUF,		RO, "used_rbuf" },	/* 76 */
411 	{ CS_RBUF_LOWATER,	RO, "rbuf_lowater" },	/* 77 */
412 	{ CS_IO_DROPPED,	RO, "io_dropped" },	/* 78 */
413 	{ CS_IO_IGNORED,	RO, "io_ignored" },	/* 79 */
414 	{ CS_IO_RECEIVED,	RO, "io_received" },	/* 80 */
415 	{ CS_IO_SENT,		RO, "io_sent" },	/* 81 */
416 	{ CS_IO_SENDFAILED,	RO, "io_sendfailed" },	/* 82 */
417 	{ CS_IO_WAKEUPS,	RO, "io_wakeups" },	/* 83 */
418 	{ CS_IO_GOODWAKEUPS,	RO, "io_goodwakeups" },	/* 84 */
419 	{ CS_TIMERSTATS_RESET,	RO, "timerstats_reset" },/* 85 */
420 	{ CS_TIMER_OVERRUNS,	RO, "timer_overruns" },	/* 86 */
421 	{ CS_TIMER_XMTS,	RO, "timer_xmts" },	/* 87 */
422 	{ CS_FUZZ,		RO, "fuzz" },		/* 88 */
423 #ifdef AUTOKEY
424 	{ CS_FLAGS,	RO, "flags" },		/* 1 + CS_MAX_NOAUTOKEY */
425 	{ CS_HOST,	RO, "host" },		/* 2 + CS_MAX_NOAUTOKEY */
426 	{ CS_PUBLIC,	RO, "update" },		/* 3 + CS_MAX_NOAUTOKEY */
427 	{ CS_CERTIF,	RO, "cert" },		/* 4 + CS_MAX_NOAUTOKEY */
428 	{ CS_SIGNATURE,	RO, "signature" },	/* 5 + CS_MAX_NOAUTOKEY */
429 	{ CS_REVTIME,	RO, "until" },		/* 6 + CS_MAX_NOAUTOKEY */
430 	{ CS_IDENT,	RO, "ident" },		/* 7 + CS_MAX_NOAUTOKEY */
431 	{ CS_DIGEST,	RO, "digest" },		/* 8 + CS_MAX_NOAUTOKEY */
432 #endif	/* AUTOKEY */
433 	{ 0,		EOV, "" }		/* 87/95 */
434 };
435 
436 static struct ctl_var *ext_sys_var = NULL;
437 
438 /*
439  * System variables we print by default (in fuzzball order,
440  * more-or-less)
441  */
442 static const u_char def_sys_var[] = {
443 	CS_VERSION,
444 	CS_PROCESSOR,
445 	CS_SYSTEM,
446 	CS_LEAP,
447 	CS_STRATUM,
448 	CS_PRECISION,
449 	CS_ROOTDELAY,
450 	CS_ROOTDISPERSION,
451 	CS_REFID,
452 	CS_REFTIME,
453 	CS_CLOCK,
454 	CS_PEERID,
455 	CS_POLL,
456 	CS_RATE,
457 	CS_OFFSET,
458 	CS_DRIFT,
459 	CS_JITTER,
460 	CS_ERROR,
461 	CS_STABIL,
462 	CS_TAI,
463 	CS_LEAPTAB,
464 	CS_LEAPEND,
465 #ifdef AUTOKEY
466 	CS_HOST,
467 	CS_IDENT,
468 	CS_FLAGS,
469 	CS_DIGEST,
470 	CS_SIGNATURE,
471 	CS_PUBLIC,
472 	CS_CERTIF,
473 #endif	/* AUTOKEY */
474 	0
475 };
476 
477 
478 /*
479  * Peer variable list
480  */
481 static const struct ctl_var peer_var[] = {
482 	{ 0,		PADDING, "" },		/* 0 */
483 	{ CP_CONFIG,	RO, "config" },		/* 1 */
484 	{ CP_AUTHENABLE, RO,	"authenable" },	/* 2 */
485 	{ CP_AUTHENTIC, RO, "authentic" }, 	/* 3 */
486 	{ CP_SRCADR,	RO, "srcadr" },		/* 4 */
487 	{ CP_SRCPORT,	RO, "srcport" },	/* 5 */
488 	{ CP_DSTADR,	RO, "dstadr" },		/* 6 */
489 	{ CP_DSTPORT,	RO, "dstport" },	/* 7 */
490 	{ CP_LEAP,	RO, "leap" },		/* 8 */
491 	{ CP_HMODE,	RO, "hmode" },		/* 9 */
492 	{ CP_STRATUM,	RO, "stratum" },	/* 10 */
493 	{ CP_PPOLL,	RO, "ppoll" },		/* 11 */
494 	{ CP_HPOLL,	RO, "hpoll" },		/* 12 */
495 	{ CP_PRECISION,	RO, "precision" },	/* 13 */
496 	{ CP_ROOTDELAY,	RO, "rootdelay" },	/* 14 */
497 	{ CP_ROOTDISPERSION, RO, "rootdisp" },	/* 15 */
498 	{ CP_REFID,	RO, "refid" },		/* 16 */
499 	{ CP_REFTIME,	RO, "reftime" },	/* 17 */
500 	{ CP_ORG,	RO, "org" },		/* 18 */
501 	{ CP_REC,	RO, "rec" },		/* 19 */
502 	{ CP_XMT,	RO, "xleave" },		/* 20 */
503 	{ CP_REACH,	RO, "reach" },		/* 21 */
504 	{ CP_UNREACH,	RO, "unreach" },	/* 22 */
505 	{ CP_TIMER,	RO, "timer" },		/* 23 */
506 	{ CP_DELAY,	RO, "delay" },		/* 24 */
507 	{ CP_OFFSET,	RO, "offset" },		/* 25 */
508 	{ CP_JITTER,	RO, "jitter" },		/* 26 */
509 	{ CP_DISPERSION, RO, "dispersion" },	/* 27 */
510 	{ CP_KEYID,	RO, "keyid" },		/* 28 */
511 	{ CP_FILTDELAY,	RO, "filtdelay" },	/* 29 */
512 	{ CP_FILTOFFSET, RO, "filtoffset" },	/* 30 */
513 	{ CP_PMODE,	RO, "pmode" },		/* 31 */
514 	{ CP_RECEIVED,	RO, "received"},	/* 32 */
515 	{ CP_SENT,	RO, "sent" },		/* 33 */
516 	{ CP_FILTERROR,	RO, "filtdisp" },	/* 34 */
517 	{ CP_FLASH,	RO, "flash" },		/* 35 */
518 	{ CP_TTL,	RO, "ttl" },		/* 36 */
519 	{ CP_VARLIST,	RO, "peer_var_list" },	/* 37 */
520 	{ CP_IN,	RO, "in" },		/* 38 */
521 	{ CP_OUT,	RO, "out" },		/* 39 */
522 	{ CP_RATE,	RO, "headway" },	/* 40 */
523 	{ CP_BIAS,	RO, "bias" },		/* 41 */
524 	{ CP_SRCHOST,	RO, "srchost" },	/* 42 */
525 	{ CP_TIMEREC,	RO, "timerec" },	/* 43 */
526 	{ CP_TIMEREACH,	RO, "timereach" },	/* 44 */
527 	{ CP_BADAUTH,	RO, "badauth" },	/* 45 */
528 	{ CP_BOGUSORG,	RO, "bogusorg" },	/* 46 */
529 	{ CP_OLDPKT,	RO, "oldpkt" },		/* 47 */
530 	{ CP_SELDISP,	RO, "seldisp" },	/* 48 */
531 	{ CP_SELBROKEN,	RO, "selbroken" },	/* 49 */
532 	{ CP_CANDIDATE, RO, "candidate" },	/* 50 */
533 #ifdef AUTOKEY
534 	{ CP_FLAGS,	RO, "flags" },		/* 1 + CP_MAX_NOAUTOKEY */
535 	{ CP_HOST,	RO, "host" },		/* 2 + CP_MAX_NOAUTOKEY */
536 	{ CP_VALID,	RO, "valid" },		/* 3 + CP_MAX_NOAUTOKEY */
537 	{ CP_INITSEQ,	RO, "initsequence" },   /* 4 + CP_MAX_NOAUTOKEY */
538 	{ CP_INITKEY,	RO, "initkey" },	/* 5 + CP_MAX_NOAUTOKEY */
539 	{ CP_INITTSP,	RO, "timestamp" },	/* 6 + CP_MAX_NOAUTOKEY */
540 	{ CP_SIGNATURE,	RO, "signature" },	/* 7 + CP_MAX_NOAUTOKEY */
541 	{ CP_IDENT,	RO, "ident" },		/* 8 + CP_MAX_NOAUTOKEY */
542 #endif	/* AUTOKEY */
543 	{ 0,		EOV, "" }		/* 50/58 */
544 };
545 
546 
547 /*
548  * Peer variables we print by default
549  */
550 static const u_char def_peer_var[] = {
551 	CP_SRCADR,
552 	CP_SRCPORT,
553 	CP_SRCHOST,
554 	CP_DSTADR,
555 	CP_DSTPORT,
556 	CP_OUT,
557 	CP_IN,
558 	CP_LEAP,
559 	CP_STRATUM,
560 	CP_PRECISION,
561 	CP_ROOTDELAY,
562 	CP_ROOTDISPERSION,
563 	CP_REFID,
564 	CP_REFTIME,
565 	CP_REC,
566 	CP_REACH,
567 	CP_UNREACH,
568 	CP_HMODE,
569 	CP_PMODE,
570 	CP_HPOLL,
571 	CP_PPOLL,
572 	CP_RATE,
573 	CP_FLASH,
574 	CP_KEYID,
575 	CP_TTL,
576 	CP_OFFSET,
577 	CP_DELAY,
578 	CP_DISPERSION,
579 	CP_JITTER,
580 	CP_XMT,
581 	CP_BIAS,
582 	CP_FILTDELAY,
583 	CP_FILTOFFSET,
584 	CP_FILTERROR,
585 #ifdef AUTOKEY
586 	CP_HOST,
587 	CP_FLAGS,
588 	CP_SIGNATURE,
589 	CP_VALID,
590 	CP_INITSEQ,
591 	CP_IDENT,
592 #endif	/* AUTOKEY */
593 	0
594 };
595 
596 
597 #ifdef REFCLOCK
598 /*
599  * Clock variable list
600  */
601 static const struct ctl_var clock_var[] = {
602 	{ 0,		PADDING, "" },		/* 0 */
603 	{ CC_TYPE,	RO, "type" },		/* 1 */
604 	{ CC_TIMECODE,	RO, "timecode" },	/* 2 */
605 	{ CC_POLL,	RO, "poll" },		/* 3 */
606 	{ CC_NOREPLY,	RO, "noreply" },	/* 4 */
607 	{ CC_BADFORMAT, RO, "badformat" },	/* 5 */
608 	{ CC_BADDATA,	RO, "baddata" },	/* 6 */
609 	{ CC_FUDGETIME1, RO, "fudgetime1" },	/* 7 */
610 	{ CC_FUDGETIME2, RO, "fudgetime2" },	/* 8 */
611 	{ CC_FUDGEVAL1, RO, "stratum" },	/* 9 */
612 	{ CC_FUDGEVAL2, RO, "refid" },		/* 10 */
613 	{ CC_FLAGS,	RO, "flags" },		/* 11 */
614 	{ CC_DEVICE,	RO, "device" },		/* 12 */
615 	{ CC_VARLIST,	RO, "clock_var_list" },	/* 13 */
616 	{ 0,		EOV, ""  }		/* 14 */
617 };
618 
619 
620 /*
621  * Clock variables printed by default
622  */
623 static const u_char def_clock_var[] = {
624 	CC_DEVICE,
625 	CC_TYPE,	/* won't be output if device = known */
626 	CC_TIMECODE,
627 	CC_POLL,
628 	CC_NOREPLY,
629 	CC_BADFORMAT,
630 	CC_BADDATA,
631 	CC_FUDGETIME1,
632 	CC_FUDGETIME2,
633 	CC_FUDGEVAL1,
634 	CC_FUDGEVAL2,
635 	CC_FLAGS,
636 	0
637 };
638 #endif
639 
640 /*
641  * MRU string constants shared by send_mru_entry() and read_mru_list().
642  */
643 static const char addr_fmt[] =		"addr.%d";
644 static const char last_fmt[] =		"last.%d";
645 
646 /*
647  * System and processor definitions.
648  */
649 #ifndef HAVE_UNAME
650 # ifndef STR_SYSTEM
651 #  define		STR_SYSTEM	"UNIX"
652 # endif
653 # ifndef STR_PROCESSOR
654 #  define		STR_PROCESSOR	"unknown"
655 # endif
656 
657 static const char str_system[] = STR_SYSTEM;
658 static const char str_processor[] = STR_PROCESSOR;
659 #else
660 # include <sys/utsname.h>
661 static struct utsname utsnamebuf;
662 #endif /* HAVE_UNAME */
663 
664 /*
665  * Trap structures. We only allow a few of these, and send a copy of
666  * each async message to each live one. Traps time out after an hour, it
667  * is up to the trap receipient to keep resetting it to avoid being
668  * timed out.
669  */
670 /* ntp_request.c */
671 struct ctl_trap ctl_traps[CTL_MAXTRAPS];
672 int num_ctl_traps;
673 
674 /*
675  * Type bits, for ctlsettrap() call.
676  */
677 #define TRAP_TYPE_CONFIG	0	/* used by configuration code */
678 #define TRAP_TYPE_PRIO		1	/* priority trap */
679 #define TRAP_TYPE_NONPRIO	2	/* nonpriority trap */
680 
681 
682 /*
683  * List relating reference clock types to control message time sources.
684  * Index by the reference clock type. This list will only be used iff
685  * the reference clock driver doesn't set peer->sstclktype to something
686  * different than CTL_SST_TS_UNSPEC.
687  */
688 #ifdef REFCLOCK
689 static const u_char clocktypes[] = {
690 	CTL_SST_TS_NTP, 	/* REFCLK_NONE (0) */
691 	CTL_SST_TS_LOCAL,	/* REFCLK_LOCALCLOCK (1) */
692 	CTL_SST_TS_UHF, 	/* deprecated REFCLK_GPS_TRAK (2) */
693 	CTL_SST_TS_HF,		/* REFCLK_WWV_PST (3) */
694 	CTL_SST_TS_LF,		/* REFCLK_WWVB_SPECTRACOM (4) */
695 	CTL_SST_TS_UHF, 	/* REFCLK_TRUETIME (5) */
696 	CTL_SST_TS_UHF, 	/* REFCLK_IRIG_AUDIO (6) */
697 	CTL_SST_TS_HF,		/* REFCLK_CHU (7) */
698 	CTL_SST_TS_LF,		/* REFCLOCK_PARSE (default) (8) */
699 	CTL_SST_TS_LF,		/* REFCLK_GPS_MX4200 (9) */
700 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_AS2201 (10) */
701 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_ARBITER (11) */
702 	CTL_SST_TS_UHF, 	/* REFCLK_IRIG_TPRO (12) */
703 	CTL_SST_TS_ATOM,	/* REFCLK_ATOM_LEITCH (13) */
704 	CTL_SST_TS_LF,		/* deprecated REFCLK_MSF_EES (14) */
705 	CTL_SST_TS_NTP, 	/* not used (15) */
706 	CTL_SST_TS_UHF, 	/* REFCLK_IRIG_BANCOMM (16) */
707 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_DATU (17) */
708 	CTL_SST_TS_TELEPHONE,	/* REFCLK_NIST_ACTS (18) */
709 	CTL_SST_TS_HF,		/* REFCLK_WWV_HEATH (19) */
710 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_NMEA (20) */
711 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_VME (21) */
712 	CTL_SST_TS_ATOM,	/* REFCLK_ATOM_PPS (22) */
713 	CTL_SST_TS_NTP,		/* not used (23) */
714 	CTL_SST_TS_NTP,		/* not used (24) */
715 	CTL_SST_TS_NTP, 	/* not used (25) */
716 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_HP (26) */
717 	CTL_SST_TS_LF,		/* REFCLK_ARCRON_MSF (27) */
718 	CTL_SST_TS_UHF,		/* REFCLK_SHM (28) */
719 	CTL_SST_TS_UHF, 	/* REFCLK_PALISADE (29) */
720 	CTL_SST_TS_UHF, 	/* REFCLK_ONCORE (30) */
721 	CTL_SST_TS_UHF,		/* REFCLK_JUPITER (31) */
722 	CTL_SST_TS_LF,		/* REFCLK_CHRONOLOG (32) */
723 	CTL_SST_TS_LF,		/* REFCLK_DUMBCLOCK (33) */
724 	CTL_SST_TS_LF,		/* REFCLK_ULINK (34) */
725 	CTL_SST_TS_LF,		/* REFCLK_PCF (35) */
726 	CTL_SST_TS_HF,		/* REFCLK_WWV (36) */
727 	CTL_SST_TS_LF,		/* REFCLK_FG (37) */
728 	CTL_SST_TS_UHF, 	/* REFCLK_HOPF_SERIAL (38) */
729 	CTL_SST_TS_UHF,		/* REFCLK_HOPF_PCI (39) */
730 	CTL_SST_TS_LF,		/* REFCLK_JJY (40) */
731 	CTL_SST_TS_UHF,		/* REFCLK_TT560 (41) */
732 	CTL_SST_TS_UHF,		/* REFCLK_ZYFER (42) */
733 	CTL_SST_TS_UHF,		/* REFCLK_RIPENCC (43) */
734 	CTL_SST_TS_UHF,		/* REFCLK_NEOCLOCK4X (44) */
735 	CTL_SST_TS_UHF,		/* REFCLK_TSYNCPCI (45) */
736 };
737 #endif  /* REFCLOCK */
738 
739 
740 /*
741  * Keyid used for authenticating write requests.
742  */
743 keyid_t ctl_auth_keyid;
744 
745 /*
746  * We keep track of the last error reported by the system internally
747  */
748 static	u_char ctl_sys_last_event;
749 static	u_char ctl_sys_num_events;
750 
751 
752 /*
753  * Statistic counters to keep track of requests and responses.
754  */
755 u_long ctltimereset;		/* time stats reset */
756 u_long numctlreq;		/* number of requests we've received */
757 u_long numctlbadpkts;		/* number of bad control packets */
758 u_long numctlresponses; 	/* number of resp packets sent with data */
759 u_long numctlfrags; 		/* number of fragments sent */
760 u_long numctlerrors;		/* number of error responses sent */
761 u_long numctltooshort;		/* number of too short input packets */
762 u_long numctlinputresp; 	/* number of responses on input */
763 u_long numctlinputfrag; 	/* number of fragments on input */
764 u_long numctlinputerr;		/* number of input pkts with err bit set */
765 u_long numctlbadoffset; 	/* number of input pkts with nonzero offset */
766 u_long numctlbadversion;	/* number of input pkts with unknown version */
767 u_long numctldatatooshort;	/* data too short for count */
768 u_long numctlbadop; 		/* bad op code found in packet */
769 u_long numasyncmsgs;		/* number of async messages we've sent */
770 
771 /*
772  * Response packet used by these routines. Also some state information
773  * so that we can handle packet formatting within a common set of
774  * subroutines.  Note we try to enter data in place whenever possible,
775  * but the need to set the more bit correctly means we occasionally
776  * use the extra buffer and copy.
777  */
778 static struct ntp_control rpkt;
779 static u_char	res_version;
780 static u_char	res_opcode;
781 static associd_t res_associd;
782 static u_short	res_frags;	/* datagrams in this response */
783 static int	res_offset;	/* offset of payload in response */
784 static u_char * datapt;
785 static u_char * dataend;
786 static int	datalinelen;
787 static int	datanotbinflag;
788 static sockaddr_u *rmt_addr;
789 static struct interface *lcl_inter;
790 
791 static u_char	res_authenticate;
792 static u_char	res_authokay;
793 static keyid_t	res_keyid;
794 
795 #define MAXDATALINELEN	(72)
796 
797 static u_char	res_async;	/* sending async trap response? */
798 
799 /*
800  * Pointers for saving state when decoding request packets
801  */
802 static	char *reqpt;
803 static	char *reqend;
804 
805 /*
806  * init_control - initialize request data
807  */
808 void
809 init_control(void)
810 {
811 	size_t i;
812 
813 #ifdef HAVE_UNAME
814 	uname(&utsnamebuf);
815 #endif /* HAVE_UNAME */
816 
817 	ctl_clr_stats();
818 
819 	ctl_auth_keyid = 0;
820 	ctl_sys_last_event = EVNT_UNSPEC;
821 	ctl_sys_num_events = 0;
822 
823 	num_ctl_traps = 0;
824 	for (i = 0; i < COUNTOF(ctl_traps); i++)
825 		ctl_traps[i].tr_flags = 0;
826 }
827 
828 
829 /*
830  * ctl_error - send an error response for the current request
831  */
832 static void
833 ctl_error(
834 	u_char errcode
835 	)
836 {
837 	int		maclen;
838 
839 	numctlerrors++;
840 	DPRINTF(3, ("sending control error %u\n", errcode));
841 
842 	/*
843 	 * Fill in the fields. We assume rpkt.sequence and rpkt.associd
844 	 * have already been filled in.
845 	 */
846 	rpkt.r_m_e_op = (u_char)CTL_RESPONSE | CTL_ERROR |
847 			(res_opcode & CTL_OP_MASK);
848 	rpkt.status = htons((u_short)(errcode << 8) & 0xff00);
849 	rpkt.count = 0;
850 
851 	/*
852 	 * send packet and bump counters
853 	 */
854 	if (res_authenticate && sys_authenticate) {
855 		maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
856 				     CTL_HEADER_LEN);
857 		sendpkt(rmt_addr, lcl_inter, -2, (void *)&rpkt,
858 			CTL_HEADER_LEN + maclen);
859 	} else
860 		sendpkt(rmt_addr, lcl_inter, -3, (void *)&rpkt,
861 			CTL_HEADER_LEN);
862 }
863 
864 /*
865  * save_config - Implements ntpq -c "saveconfig <filename>"
866  *		 Writes current configuration including any runtime
867  *		 changes by ntpq's :config or config-from-file
868  */
869 void
870 save_config(
871 	struct recvbuf *rbufp,
872 	int restrict_mask
873 	)
874 {
875 	char reply[128];
876 #ifdef SAVECONFIG
877 	char filespec[128];
878 	char filename[128];
879 	char fullpath[512];
880 	const char savedconfig_eq[] = "savedconfig=";
881 	char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)];
882 	time_t now;
883 	int fd;
884 	FILE *fptr;
885 #endif
886 
887 	if (RES_NOMODIFY & restrict_mask) {
888 		snprintf(reply, sizeof(reply),
889 			 "saveconfig prohibited by restrict ... nomodify");
890 		ctl_putdata(reply, strlen(reply), 0);
891 		ctl_flushpkt(0);
892 		NLOG(NLOG_SYSINFO)
893 			msyslog(LOG_NOTICE,
894 				"saveconfig from %s rejected due to nomodify restriction",
895 				stoa(&rbufp->recv_srcadr));
896 		sys_restricted++;
897 		return;
898 	}
899 
900 #ifdef SAVECONFIG
901 	if (NULL == saveconfigdir) {
902 		snprintf(reply, sizeof(reply),
903 			 "saveconfig prohibited, no saveconfigdir configured");
904 		ctl_putdata(reply, strlen(reply), 0);
905 		ctl_flushpkt(0);
906 		NLOG(NLOG_SYSINFO)
907 			msyslog(LOG_NOTICE,
908 				"saveconfig from %s rejected, no saveconfigdir",
909 				stoa(&rbufp->recv_srcadr));
910 		return;
911 	}
912 
913 	if (0 == reqend - reqpt)
914 		return;
915 
916 	strlcpy(filespec, reqpt, sizeof(filespec));
917 	time(&now);
918 
919 	/*
920 	 * allow timestamping of the saved config filename with
921 	 * strftime() format such as:
922 	 *   ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf"
923 	 * XXX: Nice feature, but not too safe.
924 	 */
925 	if (0 == strftime(filename, sizeof(filename), filespec,
926 			       localtime(&now)))
927 		strlcpy(filename, filespec, sizeof(filename));
928 
929 	/*
930 	 * Conceptually we should be searching for DIRSEP in filename,
931 	 * however Windows actually recognizes both forward and
932 	 * backslashes as equivalent directory separators at the API
933 	 * level.  On POSIX systems we could allow '\\' but such
934 	 * filenames are tricky to manipulate from a shell, so just
935 	 * reject both types of slashes on all platforms.
936 	 */
937 	if (strchr(filename, '\\') || strchr(filename, '/')) {
938 		snprintf(reply, sizeof(reply),
939 			 "saveconfig does not allow directory in filename");
940 		ctl_putdata(reply, strlen(reply), 0);
941 		ctl_flushpkt(0);
942 		msyslog(LOG_NOTICE,
943 			"saveconfig with path from %s rejected",
944 			stoa(&rbufp->recv_srcadr));
945 		return;
946 	}
947 
948 	snprintf(fullpath, sizeof(fullpath), "%s%s",
949 		 saveconfigdir, filename);
950 
951 	fd = open(fullpath, O_CREAT | O_TRUNC | O_WRONLY,
952 		  S_IRUSR | S_IWUSR);
953 	if (-1 == fd)
954 		fptr = NULL;
955 	else
956 		fptr = fdopen(fd, "w");
957 
958 	if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) {
959 		snprintf(reply, sizeof(reply),
960 			 "Unable to save configuration to file %s",
961 			 filename);
962 		msyslog(LOG_ERR,
963 			"saveconfig %s from %s failed", filename,
964 			stoa(&rbufp->recv_srcadr));
965 	} else {
966 		snprintf(reply, sizeof(reply),
967 			 "Configuration saved to %s", filename);
968 		msyslog(LOG_NOTICE,
969 			"Configuration saved to %s (requested by %s)",
970 			fullpath, stoa(&rbufp->recv_srcadr));
971 		/*
972 		 * save the output filename in system variable
973 		 * savedconfig, retrieved with:
974 		 *   ntpq -c "rv 0 savedconfig"
975 		 */
976 		snprintf(savedconfig, sizeof(savedconfig), "%s%s",
977 			 savedconfig_eq, filename);
978 		set_sys_var(savedconfig, strlen(savedconfig) + 1, RO);
979 	}
980 
981 	if (NULL != fptr)
982 		fclose(fptr);
983 #else	/* !SAVECONFIG follows */
984 	snprintf(reply, sizeof(reply),
985 		 "saveconfig unavailable, configured with --disable-saveconfig");
986 #endif
987 
988 	ctl_putdata(reply, strlen(reply), 0);
989 	ctl_flushpkt(0);
990 }
991 
992 
993 /*
994  * process_control - process an incoming control message
995  */
996 void
997 process_control(
998 	struct recvbuf *rbufp,
999 	int restrict_mask
1000 	)
1001 {
1002 	struct ntp_control *pkt;
1003 	int req_count;
1004 	int req_data;
1005 	const struct ctl_proc *cc;
1006 	keyid_t *pkid;
1007 	int properlen;
1008 	size_t maclen;
1009 
1010 	DPRINTF(3, ("in process_control()\n"));
1011 
1012 	/*
1013 	 * Save the addresses for error responses
1014 	 */
1015 	numctlreq++;
1016 	rmt_addr = &rbufp->recv_srcadr;
1017 	lcl_inter = rbufp->dstadr;
1018 	pkt = (struct ntp_control *)&rbufp->recv_pkt;
1019 
1020 	/*
1021 	 * If the length is less than required for the header, or
1022 	 * it is a response or a fragment, ignore this.
1023 	 */
1024 	if (rbufp->recv_length < (int)CTL_HEADER_LEN
1025 	    || (CTL_RESPONSE | CTL_MORE | CTL_ERROR) & pkt->r_m_e_op
1026 	    || pkt->offset != 0) {
1027 		DPRINTF(1, ("invalid format in control packet\n"));
1028 		if (rbufp->recv_length < (int)CTL_HEADER_LEN)
1029 			numctltooshort++;
1030 		if (CTL_RESPONSE & pkt->r_m_e_op)
1031 			numctlinputresp++;
1032 		if (CTL_MORE & pkt->r_m_e_op)
1033 			numctlinputfrag++;
1034 		if (CTL_ERROR & pkt->r_m_e_op)
1035 			numctlinputerr++;
1036 		if (pkt->offset != 0)
1037 			numctlbadoffset++;
1038 		return;
1039 	}
1040 	res_version = PKT_VERSION(pkt->li_vn_mode);
1041 	if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
1042 		DPRINTF(1, ("unknown version %d in control packet\n",
1043 			    res_version));
1044 		numctlbadversion++;
1045 		return;
1046 	}
1047 
1048 	/*
1049 	 * Pull enough data from the packet to make intelligent
1050 	 * responses
1051 	 */
1052 	rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
1053 					 MODE_CONTROL);
1054 	res_opcode = pkt->r_m_e_op;
1055 	rpkt.sequence = pkt->sequence;
1056 	rpkt.associd = pkt->associd;
1057 	rpkt.status = 0;
1058 	res_frags = 1;
1059 	res_offset = 0;
1060 	res_associd = htons(pkt->associd);
1061 	res_async = FALSE;
1062 	res_authenticate = FALSE;
1063 	res_keyid = 0;
1064 	res_authokay = FALSE;
1065 	req_count = (int)ntohs(pkt->count);
1066 	datanotbinflag = FALSE;
1067 	datalinelen = 0;
1068 	datapt = rpkt.u.data;
1069 	dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
1070 
1071 	if ((rbufp->recv_length & 0x3) != 0)
1072 		DPRINTF(3, ("Control packet length %d unrounded\n",
1073 			    rbufp->recv_length));
1074 
1075 	/*
1076 	 * We're set up now. Make sure we've got at least enough
1077 	 * incoming data space to match the count.
1078 	 */
1079 	req_data = rbufp->recv_length - CTL_HEADER_LEN;
1080 	if (req_data < req_count || rbufp->recv_length & 0x3) {
1081 		ctl_error(CERR_BADFMT);
1082 		numctldatatooshort++;
1083 		return;
1084 	}
1085 
1086 	properlen = req_count + CTL_HEADER_LEN;
1087 	/* round up proper len to a 8 octet boundary */
1088 
1089 	properlen = (properlen + 7) & ~7;
1090 	maclen = rbufp->recv_length - properlen;
1091 	if ((rbufp->recv_length & 3) == 0 &&
1092 	    maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
1093 	    sys_authenticate) {
1094 		res_authenticate = TRUE;
1095 		pkid = (void *)((char *)pkt + properlen);
1096 		res_keyid = ntohl(*pkid);
1097 		DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n",
1098 			    rbufp->recv_length, properlen, res_keyid,
1099 			    maclen));
1100 
1101 		if (!authistrusted(res_keyid))
1102 			DPRINTF(3, ("invalid keyid %08x\n", res_keyid));
1103 		else if (authdecrypt(res_keyid, (u_int32 *)pkt,
1104 				     rbufp->recv_length - maclen,
1105 				     maclen)) {
1106 			res_authokay = TRUE;
1107 			DPRINTF(3, ("authenticated okay\n"));
1108 		} else {
1109 			res_keyid = 0;
1110 			DPRINTF(3, ("authentication failed\n"));
1111 		}
1112 	}
1113 
1114 	/*
1115 	 * Set up translate pointers
1116 	 */
1117 	reqpt = (char *)pkt->u.data;
1118 	reqend = reqpt + req_count;
1119 
1120 	/*
1121 	 * Look for the opcode processor
1122 	 */
1123 	for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
1124 		if (cc->control_code == res_opcode) {
1125 			DPRINTF(3, ("opcode %d, found command handler\n",
1126 				    res_opcode));
1127 			if (cc->flags == AUTH
1128 			    && (!res_authokay
1129 				|| res_keyid != ctl_auth_keyid)) {
1130 				ctl_error(CERR_PERMISSION);
1131 				return;
1132 			}
1133 			(cc->handler)(rbufp, restrict_mask);
1134 			return;
1135 		}
1136 	}
1137 
1138 	/*
1139 	 * Can't find this one, return an error.
1140 	 */
1141 	numctlbadop++;
1142 	ctl_error(CERR_BADOP);
1143 	return;
1144 }
1145 
1146 
1147 /*
1148  * ctlpeerstatus - return a status word for this peer
1149  */
1150 u_short
1151 ctlpeerstatus(
1152 	register struct peer *p
1153 	)
1154 {
1155 	u_short status;
1156 
1157 	status = p->status;
1158 	if (FLAG_CONFIG & p->flags)
1159 		status |= CTL_PST_CONFIG;
1160 	if (p->keyid)
1161 		status |= CTL_PST_AUTHENABLE;
1162 	if (FLAG_AUTHENTIC & p->flags)
1163 		status |= CTL_PST_AUTHENTIC;
1164 	if (p->reach)
1165 		status |= CTL_PST_REACH;
1166 	if (MDF_TXONLY_MASK & p->cast_flags)
1167 		status |= CTL_PST_BCAST;
1168 
1169 	return CTL_PEER_STATUS(status, p->num_events, p->last_event);
1170 }
1171 
1172 
1173 /*
1174  * ctlclkstatus - return a status word for this clock
1175  */
1176 #ifdef REFCLOCK
1177 static u_short
1178 ctlclkstatus(
1179 	struct refclockstat *pcs
1180 	)
1181 {
1182 	return CTL_PEER_STATUS(0, pcs->lastevent, pcs->currentstatus);
1183 }
1184 #endif
1185 
1186 
1187 /*
1188  * ctlsysstatus - return the system status word
1189  */
1190 u_short
1191 ctlsysstatus(void)
1192 {
1193 	register u_char this_clock;
1194 
1195 	this_clock = CTL_SST_TS_UNSPEC;
1196 #ifdef REFCLOCK
1197 	if (sys_peer != NULL) {
1198 		if (CTL_SST_TS_UNSPEC != sys_peer->sstclktype)
1199 			this_clock = sys_peer->sstclktype;
1200 		else if (sys_peer->refclktype < COUNTOF(clocktypes))
1201 			this_clock = clocktypes[sys_peer->refclktype];
1202 	}
1203 #else /* REFCLOCK */
1204 	if (sys_peer != 0)
1205 		this_clock = CTL_SST_TS_NTP;
1206 #endif /* REFCLOCK */
1207 	return CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events,
1208 			      ctl_sys_last_event);
1209 }
1210 
1211 
1212 /*
1213  * ctl_flushpkt - write out the current packet and prepare
1214  *		  another if necessary.
1215  */
1216 static void
1217 ctl_flushpkt(
1218 	u_char more
1219 	)
1220 {
1221 	size_t i;
1222 	int dlen;
1223 	int sendlen;
1224 	int maclen;
1225 	int totlen;
1226 	keyid_t keyid;
1227 
1228 	dlen = datapt - rpkt.u.data;
1229 	if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) {
1230 		/*
1231 		 * Big hack, output a trailing \r\n
1232 		 */
1233 		*datapt++ = '\r';
1234 		*datapt++ = '\n';
1235 		dlen += 2;
1236 	}
1237 	sendlen = dlen + CTL_HEADER_LEN;
1238 
1239 	/*
1240 	 * Pad to a multiple of 32 bits
1241 	 */
1242 	while (sendlen & 0x3) {
1243 		*datapt++ = '\0';
1244 		sendlen++;
1245 	}
1246 
1247 	/*
1248 	 * Fill in the packet with the current info
1249 	 */
1250 	rpkt.r_m_e_op = CTL_RESPONSE | more |
1251 			(res_opcode & CTL_OP_MASK);
1252 	rpkt.count = htons((u_short)dlen);
1253 	rpkt.offset = htons((u_short)res_offset);
1254 	if (res_async) {
1255 		for (i = 0; i < COUNTOF(ctl_traps); i++) {
1256 			if (TRAP_INUSE & ctl_traps[i].tr_flags) {
1257 				rpkt.li_vn_mode =
1258 				    PKT_LI_VN_MODE(
1259 					sys_leap,
1260 					ctl_traps[i].tr_version,
1261 					MODE_CONTROL);
1262 				rpkt.sequence =
1263 				    htons(ctl_traps[i].tr_sequence);
1264 				sendpkt(&ctl_traps[i].tr_addr,
1265 					ctl_traps[i].tr_localaddr, -4,
1266 					(struct pkt *)&rpkt, sendlen);
1267 				if (!more)
1268 					ctl_traps[i].tr_sequence++;
1269 				numasyncmsgs++;
1270 			}
1271 		}
1272 	} else {
1273 		if (res_authenticate && sys_authenticate) {
1274 			totlen = sendlen;
1275 			/*
1276 			 * If we are going to authenticate, then there
1277 			 * is an additional requirement that the MAC
1278 			 * begin on a 64 bit boundary.
1279 			 */
1280 			while (totlen & 7) {
1281 				*datapt++ = '\0';
1282 				totlen++;
1283 			}
1284 			keyid = htonl(res_keyid);
1285 			memcpy(datapt, &keyid, sizeof(keyid));
1286 			maclen = authencrypt(res_keyid,
1287 					     (u_int32 *)&rpkt, totlen);
1288 			sendpkt(rmt_addr, lcl_inter, -5,
1289 				(struct pkt *)&rpkt, totlen + maclen);
1290 		} else {
1291 			sendpkt(rmt_addr, lcl_inter, -6,
1292 				(struct pkt *)&rpkt, sendlen);
1293 		}
1294 		if (more)
1295 			numctlfrags++;
1296 		else
1297 			numctlresponses++;
1298 	}
1299 
1300 	/*
1301 	 * Set us up for another go around.
1302 	 */
1303 	res_frags++;
1304 	res_offset += dlen;
1305 	datapt = rpkt.u.data;
1306 }
1307 
1308 
1309 /*
1310  * ctl_putdata - write data into the packet, fragmenting and starting
1311  * another if this one is full.
1312  */
1313 static void
1314 ctl_putdata(
1315 	const char *dp,
1316 	unsigned int dlen,
1317 	int bin 		/* set to 1 when data is binary */
1318 	)
1319 {
1320 	int overhead;
1321 
1322 	overhead = 0;
1323 	if (!bin) {
1324 		datanotbinflag = TRUE;
1325 		overhead = 3;
1326 		if (datapt != rpkt.u.data) {
1327 			*datapt++ = ',';
1328 			datalinelen++;
1329 			if ((dlen + datalinelen + 1) >= MAXDATALINELEN) {
1330 				*datapt++ = '\r';
1331 				*datapt++ = '\n';
1332 				datalinelen = 0;
1333 			} else {
1334 				*datapt++ = ' ';
1335 				datalinelen++;
1336 			}
1337 		}
1338 	}
1339 
1340 	/*
1341 	 * Save room for trailing junk
1342 	 */
1343 	if (dlen + overhead + datapt > dataend) {
1344 		/*
1345 		 * Not enough room in this one, flush it out.
1346 		 */
1347 		ctl_flushpkt(CTL_MORE);
1348 	}
1349 	memcpy(datapt, dp, dlen);
1350 	datapt += dlen;
1351 	datalinelen += dlen;
1352 }
1353 
1354 
1355 /*
1356  * ctl_putstr - write a tagged string into the response packet
1357  *		in the form:
1358  *
1359  *		tag="data"
1360  *
1361  *		len is the data length excluding the NUL terminator,
1362  *		as in ctl_putstr("var", "value", strlen("value"));
1363  */
1364 static void
1365 ctl_putstr(
1366 	const char *	tag,
1367 	const char *	data,
1368 	size_t		len
1369 	)
1370 {
1371 	char buffer[512];
1372 	char *cp;
1373 	size_t tl;
1374 
1375 	tl = strlen(tag);
1376 	memcpy(buffer, tag, tl);
1377 	cp = buffer + tl;
1378 	if (len > 0) {
1379 		NTP_INSIST(tl + 3 + len <= sizeof(buffer));
1380 		*cp++ = '=';
1381 		*cp++ = '"';
1382 		memcpy(cp, data, len);
1383 		cp += len;
1384 		*cp++ = '"';
1385 	}
1386 	ctl_putdata(buffer, (u_int)(cp - buffer), 0);
1387 }
1388 
1389 
1390 /*
1391  * ctl_putunqstr - write a tagged string into the response packet
1392  *		   in the form:
1393  *
1394  *		   tag=data
1395  *
1396  *	len is the data length excluding the NUL terminator.
1397  *	data must not contain a comma or whitespace.
1398  */
1399 static void
1400 ctl_putunqstr(
1401 	const char *	tag,
1402 	const char *	data,
1403 	size_t		len
1404 	)
1405 {
1406 	char buffer[512];
1407 	char *cp;
1408 	size_t tl;
1409 
1410 	tl = strlen(tag);
1411 	memcpy(buffer, tag, tl);
1412 	cp = buffer + tl;
1413 	if (len > 0) {
1414 		NTP_INSIST(tl + 1 + len <= sizeof(buffer));
1415 		*cp++ = '=';
1416 		memcpy(cp, data, len);
1417 		cp += len;
1418 	}
1419 	ctl_putdata(buffer, (u_int)(cp - buffer), 0);
1420 }
1421 
1422 
1423 /*
1424  * ctl_putdblf - write a tagged, signed double into the response packet
1425  */
1426 static void
1427 ctl_putdblf(
1428 	const char *	tag,
1429 	const char *	fmt,
1430 	double		d
1431 	)
1432 {
1433 	char *cp;
1434 	const char *cq;
1435 	char buffer[200];
1436 
1437 	cp = buffer;
1438 	cq = tag;
1439 	while (*cq != '\0')
1440 		*cp++ = *cq++;
1441 	*cp++ = '=';
1442 	NTP_INSIST((size_t)(cp - buffer) < sizeof(buffer));
1443 	snprintf(cp, sizeof(buffer) - (cp - buffer), fmt, d);
1444 	cp += strlen(cp);
1445 	ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
1446 }
1447 
1448 /*
1449  * ctl_putuint - write a tagged unsigned integer into the response
1450  */
1451 static void
1452 ctl_putuint(
1453 	const char *tag,
1454 	u_long uval
1455 	)
1456 {
1457 	register char *cp;
1458 	register const char *cq;
1459 	char buffer[200];
1460 
1461 	cp = buffer;
1462 	cq = tag;
1463 	while (*cq != '\0')
1464 		*cp++ = *cq++;
1465 
1466 	*cp++ = '=';
1467 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1468 	snprintf(cp, sizeof(buffer) - (cp - buffer), "%lu", uval);
1469 	cp += strlen(cp);
1470 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1471 }
1472 
1473 /*
1474  * ctl_putfs - write a decoded filestamp into the response
1475  */
1476 static void
1477 ctl_putfs(
1478 	const char *tag,
1479 	tstamp_t uval
1480 	)
1481 {
1482 	register char *cp;
1483 	register const char *cq;
1484 	char buffer[200];
1485 	struct tm *tm = NULL;
1486 	time_t fstamp;
1487 
1488 	cp = buffer;
1489 	cq = tag;
1490 	while (*cq != '\0')
1491 		*cp++ = *cq++;
1492 
1493 	*cp++ = '=';
1494 	fstamp = uval - JAN_1970;
1495 	tm = gmtime(&fstamp);
1496 	if (NULL ==  tm)
1497 		return;
1498 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1499 	snprintf(cp, sizeof(buffer) - (cp - buffer),
1500 		 "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
1501 		 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
1502 	cp += strlen(cp);
1503 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1504 }
1505 
1506 
1507 /*
1508  * ctl_puthex - write a tagged unsigned integer, in hex, into the
1509  * response
1510  */
1511 static void
1512 ctl_puthex(
1513 	const char *tag,
1514 	u_long uval
1515 	)
1516 {
1517 	register char *cp;
1518 	register const char *cq;
1519 	char buffer[200];
1520 
1521 	cp = buffer;
1522 	cq = tag;
1523 	while (*cq != '\0')
1524 		*cp++ = *cq++;
1525 
1526 	*cp++ = '=';
1527 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1528 	snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%lx", uval);
1529 	cp += strlen(cp);
1530 	ctl_putdata(buffer,(unsigned)( cp - buffer ), 0);
1531 }
1532 
1533 
1534 /*
1535  * ctl_putint - write a tagged signed integer into the response
1536  */
1537 static void
1538 ctl_putint(
1539 	const char *tag,
1540 	long ival
1541 	)
1542 {
1543 	register char *cp;
1544 	register const char *cq;
1545 	char buffer[200];
1546 
1547 	cp = buffer;
1548 	cq = tag;
1549 	while (*cq != '\0')
1550 		*cp++ = *cq++;
1551 
1552 	*cp++ = '=';
1553 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1554 	snprintf(cp, sizeof(buffer) - (cp - buffer), "%ld", ival);
1555 	cp += strlen(cp);
1556 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1557 }
1558 
1559 
1560 /*
1561  * ctl_putts - write a tagged timestamp, in hex, into the response
1562  */
1563 static void
1564 ctl_putts(
1565 	const char *tag,
1566 	l_fp *ts
1567 	)
1568 {
1569 	register char *cp;
1570 	register const char *cq;
1571 	char buffer[200];
1572 
1573 	cp = buffer;
1574 	cq = tag;
1575 	while (*cq != '\0')
1576 		*cp++ = *cq++;
1577 
1578 	*cp++ = '=';
1579 	NTP_INSIST((size_t)(cp - buffer) < sizeof(buffer));
1580 	snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%08x.%08x",
1581 		 (u_int)ts->l_ui, (u_int)ts->l_uf);
1582 	cp += strlen(cp);
1583 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1584 }
1585 
1586 
1587 /*
1588  * ctl_putadr - write an IP address into the response
1589  */
1590 static void
1591 ctl_putadr(
1592 	const char *tag,
1593 	u_int32 addr32,
1594 	sockaddr_u *addr
1595 	)
1596 {
1597 	register char *cp;
1598 	register const char *cq;
1599 	char buffer[200];
1600 
1601 	cp = buffer;
1602 	cq = tag;
1603 	while (*cq != '\0')
1604 		*cp++ = *cq++;
1605 
1606 	*cp++ = '=';
1607 	if (NULL == addr)
1608 		cq = numtoa(addr32);
1609 	else
1610 		cq = stoa(addr);
1611 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1612 	snprintf(cp, sizeof(buffer) - (cp - buffer), "%s", cq);
1613 	cp += strlen(cp);
1614 	ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
1615 }
1616 
1617 
1618 /*
1619  * ctl_putrefid - send a u_int32 refid as printable text
1620  */
1621 static void
1622 ctl_putrefid(
1623 	const char *	tag,
1624 	u_int32		refid
1625 	)
1626 {
1627 	char	output[16];
1628 	char *	optr;
1629 	char *	oplim;
1630 	char *	iptr;
1631 	char *	iplim;
1632 	char *	past_eq;
1633 
1634 	optr = output;
1635 	oplim = output + sizeof(output);
1636 	while (optr < oplim && '\0' != *tag)
1637 		*optr++ = *tag++;
1638 	if (optr < oplim) {
1639 		*optr++ = '=';
1640 		past_eq = optr;
1641 	}
1642 	if (!(optr < oplim))
1643 		return;
1644 	iptr = (char *)&refid;
1645 	iplim = iptr + sizeof(refid);
1646 	for ( ; optr < oplim && iptr < iplim && '\0' != *iptr;
1647 	     iptr++, optr++)
1648 		if (isprint((int)*iptr))
1649 			*optr = *iptr;
1650 		else
1651 			*optr = '.';
1652 	if (!(optr <= oplim))
1653 		optr = past_eq;
1654 	ctl_putdata(output, (u_int)(optr - output), FALSE);
1655 }
1656 
1657 
1658 /*
1659  * ctl_putarray - write a tagged eight element double array into the response
1660  */
1661 static void
1662 ctl_putarray(
1663 	const char *tag,
1664 	double *arr,
1665 	int start
1666 	)
1667 {
1668 	register char *cp;
1669 	register const char *cq;
1670 	char buffer[200];
1671 	int i;
1672 	cp = buffer;
1673 	cq = tag;
1674 	while (*cq != '\0')
1675 		*cp++ = *cq++;
1676 	*cp++ = '=';
1677 	i = start;
1678 	do {
1679 		if (i == 0)
1680 			i = NTP_SHIFT;
1681 		i--;
1682 		NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1683 		snprintf(cp, sizeof(buffer) - (cp - buffer),
1684 			 " %.2f", arr[i] * 1e3);
1685 		cp += strlen(cp);
1686 	} while (i != start);
1687 	ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
1688 }
1689 
1690 
1691 /*
1692  * ctl_putsys - output a system variable
1693  */
1694 static void
1695 ctl_putsys(
1696 	int varid
1697 	)
1698 {
1699 	l_fp tmp;
1700 	char str[256];
1701 	u_int u;
1702 	double kb;
1703 	double dtemp;
1704 	const char *ss;
1705 #ifdef AUTOKEY
1706 	struct cert_info *cp;
1707 #endif	/* AUTOKEY */
1708 #ifdef KERNEL_PLL
1709 	static struct timex ntx;
1710 	static u_long ntp_adjtime_time;
1711 
1712 	static const double to_ms =
1713 # ifdef STA_NANO
1714 	    	1.0e-6; /* nsec to msec */
1715 # else
1716 		1.0e-3; /* usec to msec */
1717 # endif
1718 
1719 	/*
1720 	 * CS_K_* variables depend on up-to-date output of ntp_adjtime()
1721 	 */
1722 	if (CS_KERN_FIRST <= varid && varid <= CS_KERN_LAST &&
1723 	    current_time != ntp_adjtime_time) {
1724 		ZERO(ntx);
1725 		if (ntp_adjtime(&ntx) < 0)
1726 			msyslog(LOG_ERR, "ntp_adjtime() for mode 6 query failed: %m");
1727 		else
1728 			ntp_adjtime_time = current_time;
1729 	}
1730 #endif	/* KERNEL_PLL */
1731 
1732 	switch (varid) {
1733 
1734 	case CS_LEAP:
1735 		ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
1736 		break;
1737 
1738 	case CS_STRATUM:
1739 		ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
1740 		break;
1741 
1742 	case CS_PRECISION:
1743 		ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
1744 		break;
1745 
1746 	case CS_ROOTDELAY:
1747 		ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
1748 			   1e3);
1749 		break;
1750 
1751 	case CS_ROOTDISPERSION:
1752 		ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
1753 			   sys_rootdisp * 1e3);
1754 		break;
1755 
1756 	case CS_REFID:
1757 		if (sys_stratum > 1 && sys_stratum < STRATUM_UNSPEC)
1758 			ctl_putadr(sys_var[varid].text, sys_refid, NULL);
1759 		else
1760 			ctl_putrefid(sys_var[varid].text, sys_refid);
1761 		break;
1762 
1763 	case CS_REFTIME:
1764 		ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
1765 		break;
1766 
1767 	case CS_POLL:
1768 		ctl_putuint(sys_var[CS_POLL].text, sys_poll);
1769 		break;
1770 
1771 	case CS_PEERID:
1772 		if (sys_peer == NULL)
1773 			ctl_putuint(sys_var[CS_PEERID].text, 0);
1774 		else
1775 			ctl_putuint(sys_var[CS_PEERID].text,
1776 				    sys_peer->associd);
1777 		break;
1778 
1779 	case CS_PEERADR:
1780 		if (sys_peer != NULL && sys_peer->dstadr != NULL)
1781 			ss = sptoa(&sys_peer->srcadr);
1782 		else
1783 			ss = "0.0.0.0:0";
1784 		ctl_putunqstr(sys_var[CS_PEERADR].text, ss, strlen(ss));
1785 		break;
1786 
1787 	case CS_PEERMODE:
1788 		u = (sys_peer != NULL)
1789 			? sys_peer->hmode
1790 			: MODE_UNSPEC;
1791 		ctl_putuint(sys_var[CS_PEERMODE].text, u);
1792 		break;
1793 
1794 	case CS_OFFSET:
1795 		ctl_putdbl6(sys_var[CS_OFFSET].text, last_offset * 1e3);
1796 		break;
1797 
1798 	case CS_DRIFT:
1799 		ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
1800 		break;
1801 
1802 	case CS_JITTER:
1803 		ctl_putdbl6(sys_var[CS_JITTER].text, sys_jitter * 1e3);
1804 		break;
1805 
1806 	case CS_ERROR:
1807 		ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
1808 		break;
1809 
1810 	case CS_CLOCK:
1811 		get_systime(&tmp);
1812 		ctl_putts(sys_var[CS_CLOCK].text, &tmp);
1813 		break;
1814 
1815 	case CS_PROCESSOR:
1816 #ifndef HAVE_UNAME
1817 		ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
1818 			   sizeof(str_processor) - 1);
1819 #else
1820 		ctl_putstr(sys_var[CS_PROCESSOR].text,
1821 			   utsnamebuf.machine, strlen(utsnamebuf.machine));
1822 #endif /* HAVE_UNAME */
1823 		break;
1824 
1825 	case CS_SYSTEM:
1826 #ifndef HAVE_UNAME
1827 		ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
1828 			   sizeof(str_system) - 1);
1829 #else
1830 		snprintf(str, sizeof(str), "%s/%s", utsnamebuf.sysname,
1831 			 utsnamebuf.release);
1832 		ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
1833 #endif /* HAVE_UNAME */
1834 		break;
1835 
1836 	case CS_VERSION:
1837 		ctl_putstr(sys_var[CS_VERSION].text, Version,
1838 			   strlen(Version));
1839 		break;
1840 
1841 	case CS_STABIL:
1842 		ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
1843 			   1e6);
1844 		break;
1845 
1846 	case CS_VARLIST:
1847 	{
1848 		char buf[CTL_MAX_DATA_LEN];
1849 		//buffPointer, firstElementPointer, buffEndPointer
1850 		char *buffp, *buffend;
1851 		int firstVarName;
1852 		const char *ss1;
1853 		int len;
1854 		const struct ctl_var *k;
1855 
1856 		buffp = buf;
1857 		buffend = buf + sizeof(buf);
1858 		if (buffp + strlen(sys_var[CS_VARLIST].text) + 4 > buffend)
1859 			break;	/* really long var name */
1860 
1861 		snprintf(buffp, sizeof(buf), "%s=\"",sys_var[CS_VARLIST].text);
1862 		buffp += strlen(buffp);
1863 		firstVarName = TRUE;
1864 		for (k = sys_var; !(k->flags & EOV); k++) {
1865 			if (k->flags & PADDING)
1866 				continue;
1867 			len = strlen(k->text);
1868 			if (buffp + len + 1 >= buffend)
1869 				break;
1870 			if (!firstVarName)
1871 				*buffp++ = ',';
1872 			else
1873 				firstVarName = FALSE;
1874 			memcpy(buffp, k->text, len);
1875 			buffp += len;
1876 		}
1877 
1878 		for (k = ext_sys_var; k && !(k->flags & EOV); k++) {
1879 			if (k->flags & PADDING)
1880 				continue;
1881 			if (NULL == k->text)
1882 				continue;
1883 			ss1 = strchr(k->text, '=');
1884 			if (NULL == ss1)
1885 				len = strlen(k->text);
1886 			else
1887 				len = ss1 - k->text;
1888 			if (buffp + len + 1 >= buffend)
1889 				break;
1890 			if (firstVarName) {
1891 				*buffp++ = ',';
1892 				firstVarName = FALSE;
1893 			}
1894 			memcpy(buffp, k->text,(unsigned)len);
1895 			buffp += len;
1896 		}
1897 		if (buffp + 2 >= buffend)
1898 			break;
1899 
1900 		*buffp++ = '"';
1901 		*buffp = '\0';
1902 
1903 		ctl_putdata(buf, (unsigned)( buffp - buf ), 0);
1904 		break;
1905 	}
1906 
1907 	case CS_TAI:
1908 		if (sys_tai > 0)
1909 			ctl_putuint(sys_var[CS_TAI].text, sys_tai);
1910 		break;
1911 
1912 	case CS_LEAPTAB:
1913 	{
1914 		leap_signature_t lsig;
1915 		leapsec_getsig(&lsig);
1916 		if (lsig.ttime > 0)
1917 			ctl_putfs(sys_var[CS_LEAPTAB].text, lsig.ttime);
1918 		break;
1919 	}
1920 
1921 	case CS_LEAPEND:
1922 	{
1923 		leap_signature_t lsig;
1924 		leapsec_getsig(&lsig);
1925 		if (lsig.etime > 0)
1926 			ctl_putfs(sys_var[CS_LEAPEND].text, lsig.etime);
1927 		break;
1928 	}
1929 
1930 	case CS_RATE:
1931 		ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll);
1932 		break;
1933 
1934 	case CS_MRU_ENABLED:
1935 		ctl_puthex(sys_var[varid].text, mon_enabled);
1936 		break;
1937 
1938 	case CS_MRU_DEPTH:
1939 		ctl_putuint(sys_var[varid].text, mru_entries);
1940 		break;
1941 
1942 	case CS_MRU_MEM:
1943 		kb = mru_entries * (sizeof(mon_entry) / 1024.);
1944 		u = (u_int)kb;
1945 		if (kb - u >= 0.5)
1946 			u++;
1947 		ctl_putuint(sys_var[varid].text, u);
1948 		break;
1949 
1950 	case CS_MRU_DEEPEST:
1951 		ctl_putuint(sys_var[varid].text, mru_peakentries);
1952 		break;
1953 
1954 	case CS_MRU_MINDEPTH:
1955 		ctl_putuint(sys_var[varid].text, mru_mindepth);
1956 		break;
1957 
1958 	case CS_MRU_MAXAGE:
1959 		ctl_putint(sys_var[varid].text, mru_maxage);
1960 		break;
1961 
1962 	case CS_MRU_MAXDEPTH:
1963 		ctl_putuint(sys_var[varid].text, mru_maxdepth);
1964 		break;
1965 
1966 	case CS_MRU_MAXMEM:
1967 		kb = mru_maxdepth * (sizeof(mon_entry) / 1024.);
1968 		u = (u_int)kb;
1969 		if (kb - u >= 0.5)
1970 			u++;
1971 		ctl_putuint(sys_var[varid].text, u);
1972 		break;
1973 
1974 	case CS_SS_UPTIME:
1975 		ctl_putuint(sys_var[varid].text, current_time);
1976 		break;
1977 
1978 	case CS_SS_RESET:
1979 		ctl_putuint(sys_var[varid].text,
1980 			    current_time - sys_stattime);
1981 		break;
1982 
1983 	case CS_SS_RECEIVED:
1984 		ctl_putuint(sys_var[varid].text, sys_received);
1985 		break;
1986 
1987 	case CS_SS_THISVER:
1988 		ctl_putuint(sys_var[varid].text, sys_newversion);
1989 		break;
1990 
1991 	case CS_SS_OLDVER:
1992 		ctl_putuint(sys_var[varid].text, sys_oldversion);
1993 		break;
1994 
1995 	case CS_SS_BADFORMAT:
1996 		ctl_putuint(sys_var[varid].text, sys_badlength);
1997 		break;
1998 
1999 	case CS_SS_BADAUTH:
2000 		ctl_putuint(sys_var[varid].text, sys_badauth);
2001 		break;
2002 
2003 	case CS_SS_DECLINED:
2004 		ctl_putuint(sys_var[varid].text, sys_declined);
2005 		break;
2006 
2007 	case CS_SS_RESTRICTED:
2008 		ctl_putuint(sys_var[varid].text, sys_restricted);
2009 		break;
2010 
2011 	case CS_SS_LIMITED:
2012 		ctl_putuint(sys_var[varid].text, sys_limitrejected);
2013 		break;
2014 
2015 	case CS_SS_KODSENT:
2016 		ctl_putuint(sys_var[varid].text, sys_kodsent);
2017 		break;
2018 
2019 	case CS_SS_PROCESSED:
2020 		ctl_putuint(sys_var[varid].text, sys_processed);
2021 		break;
2022 
2023 	case CS_BCASTDELAY:
2024 		ctl_putdbl(sys_var[varid].text, sys_bdelay * 1e3);
2025 		break;
2026 
2027 	case CS_AUTHDELAY:
2028 		LFPTOD(&sys_authdelay, dtemp);
2029 		ctl_putdbl(sys_var[varid].text, dtemp * 1e3);
2030 		break;
2031 
2032 	case CS_AUTHKEYS:
2033 		ctl_putuint(sys_var[varid].text, authnumkeys);
2034 		break;
2035 
2036 	case CS_AUTHFREEK:
2037 		ctl_putuint(sys_var[varid].text, authnumfreekeys);
2038 		break;
2039 
2040 	case CS_AUTHKLOOKUPS:
2041 		ctl_putuint(sys_var[varid].text, authkeylookups);
2042 		break;
2043 
2044 	case CS_AUTHKNOTFOUND:
2045 		ctl_putuint(sys_var[varid].text, authkeynotfound);
2046 		break;
2047 
2048 	case CS_AUTHKUNCACHED:
2049 		ctl_putuint(sys_var[varid].text, authkeyuncached);
2050 		break;
2051 
2052 	case CS_AUTHKEXPIRED:
2053 		ctl_putuint(sys_var[varid].text, authkeyexpired);
2054 		break;
2055 
2056 	case CS_AUTHENCRYPTS:
2057 		ctl_putuint(sys_var[varid].text, authencryptions);
2058 		break;
2059 
2060 	case CS_AUTHDECRYPTS:
2061 		ctl_putuint(sys_var[varid].text, authdecryptions);
2062 		break;
2063 
2064 	case CS_AUTHRESET:
2065 		ctl_putuint(sys_var[varid].text,
2066 			    current_time - auth_timereset);
2067 		break;
2068 
2069 		/*
2070 		 * CTL_IF_KERNLOOP() puts a zero if the kernel loop is
2071 		 * unavailable, otherwise calls putfunc with args.
2072 		 */
2073 #ifndef KERNEL_PLL
2074 # define	CTL_IF_KERNLOOP(putfunc, args)	\
2075 		ctl_putint(sys_var[varid].text, 0)
2076 #else
2077 # define	CTL_IF_KERNLOOP(putfunc, args)	\
2078 		putfunc args
2079 #endif
2080 
2081 		/*
2082 		 * CTL_IF_KERNPPS() puts a zero if either the kernel
2083 		 * loop is unavailable, or kernel hard PPS is not
2084 		 * active, otherwise calls putfunc with args.
2085 		 */
2086 #ifndef KERNEL_PLL
2087 # define	CTL_IF_KERNPPS(putfunc, args)	\
2088 		ctl_putint(sys_var[varid].text, 0)
2089 #else
2090 # define	CTL_IF_KERNPPS(putfunc, args)			\
2091 		if (0 == ntx.shift)				\
2092 			ctl_putint(sys_var[varid].text, 0);	\
2093 		else						\
2094 			putfunc args	/* no trailing ; */
2095 #endif
2096 
2097 	case CS_K_OFFSET:
2098 		CTL_IF_KERNLOOP(
2099 			ctl_putdblf,
2100 			(sys_var[varid].text, "%g", to_ms * ntx.offset)
2101 		);
2102 		break;
2103 
2104 	case CS_K_FREQ:
2105 		CTL_IF_KERNLOOP(
2106 			ctl_putsfp,
2107 			(sys_var[varid].text, ntx.freq)
2108 		);
2109 		break;
2110 
2111 	case CS_K_MAXERR:
2112 		CTL_IF_KERNLOOP(
2113 			ctl_putdblf,
2114 			(sys_var[varid].text, "%.6g",
2115 			 to_ms * ntx.maxerror)
2116 		);
2117 		break;
2118 
2119 	case CS_K_ESTERR:
2120 		CTL_IF_KERNLOOP(
2121 			ctl_putdblf,
2122 			(sys_var[varid].text, "%.6g",
2123 			 to_ms * ntx.esterror)
2124 		);
2125 		break;
2126 
2127 	case CS_K_STFLAGS:
2128 #ifndef KERNEL_PLL
2129 		ss = "";
2130 #else
2131 		ss = k_st_flags(ntx.status);
2132 #endif
2133 		ctl_putstr(sys_var[varid].text, ss, strlen(ss));
2134 		break;
2135 
2136 	case CS_K_TIMECONST:
2137 		CTL_IF_KERNLOOP(
2138 			ctl_putint,
2139 			(sys_var[varid].text, ntx.constant)
2140 		);
2141 		break;
2142 
2143 	case CS_K_PRECISION:
2144 		CTL_IF_KERNLOOP(
2145 			ctl_putdblf,
2146 			(sys_var[varid].text, "%.6g",
2147 			    to_ms * ntx.precision)
2148 		);
2149 		break;
2150 
2151 	case CS_K_FREQTOL:
2152 		CTL_IF_KERNLOOP(
2153 			ctl_putsfp,
2154 			(sys_var[varid].text, ntx.tolerance)
2155 		);
2156 		break;
2157 
2158 	case CS_K_PPS_FREQ:
2159 		CTL_IF_KERNPPS(
2160 			ctl_putsfp,
2161 			(sys_var[varid].text, ntx.ppsfreq)
2162 		);
2163 		break;
2164 
2165 	case CS_K_PPS_STABIL:
2166 		CTL_IF_KERNPPS(
2167 			ctl_putsfp,
2168 			(sys_var[varid].text, ntx.stabil)
2169 		);
2170 		break;
2171 
2172 	case CS_K_PPS_JITTER:
2173 		CTL_IF_KERNPPS(
2174 			ctl_putdbl,
2175 			(sys_var[varid].text, to_ms * ntx.jitter)
2176 		);
2177 		break;
2178 
2179 	case CS_K_PPS_CALIBDUR:
2180 		CTL_IF_KERNPPS(
2181 			ctl_putint,
2182 			(sys_var[varid].text, 1 << ntx.shift)
2183 		);
2184 		break;
2185 
2186 	case CS_K_PPS_CALIBS:
2187 		CTL_IF_KERNPPS(
2188 			ctl_putint,
2189 			(sys_var[varid].text, ntx.calcnt)
2190 		);
2191 		break;
2192 
2193 	case CS_K_PPS_CALIBERRS:
2194 		CTL_IF_KERNPPS(
2195 			ctl_putint,
2196 			(sys_var[varid].text, ntx.errcnt)
2197 		);
2198 		break;
2199 
2200 	case CS_K_PPS_JITEXC:
2201 		CTL_IF_KERNPPS(
2202 			ctl_putint,
2203 			(sys_var[varid].text, ntx.jitcnt)
2204 		);
2205 		break;
2206 
2207 	case CS_K_PPS_STBEXC:
2208 		CTL_IF_KERNPPS(
2209 			ctl_putint,
2210 			(sys_var[varid].text, ntx.stbcnt)
2211 		);
2212 		break;
2213 
2214 	case CS_IOSTATS_RESET:
2215 		ctl_putuint(sys_var[varid].text,
2216 			    current_time - io_timereset);
2217 		break;
2218 
2219 	case CS_TOTAL_RBUF:
2220 		ctl_putuint(sys_var[varid].text, total_recvbuffs());
2221 		break;
2222 
2223 	case CS_FREE_RBUF:
2224 		ctl_putuint(sys_var[varid].text, free_recvbuffs());
2225 		break;
2226 
2227 	case CS_USED_RBUF:
2228 		ctl_putuint(sys_var[varid].text, full_recvbuffs());
2229 		break;
2230 
2231 	case CS_RBUF_LOWATER:
2232 		ctl_putuint(sys_var[varid].text, lowater_additions());
2233 		break;
2234 
2235 	case CS_IO_DROPPED:
2236 		ctl_putuint(sys_var[varid].text, packets_dropped);
2237 		break;
2238 
2239 	case CS_IO_IGNORED:
2240 		ctl_putuint(sys_var[varid].text, packets_ignored);
2241 		break;
2242 
2243 	case CS_IO_RECEIVED:
2244 		ctl_putuint(sys_var[varid].text, packets_received);
2245 		break;
2246 
2247 	case CS_IO_SENT:
2248 		ctl_putuint(sys_var[varid].text, packets_sent);
2249 		break;
2250 
2251 	case CS_IO_SENDFAILED:
2252 		ctl_putuint(sys_var[varid].text, packets_notsent);
2253 		break;
2254 
2255 	case CS_IO_WAKEUPS:
2256 		ctl_putuint(sys_var[varid].text, handler_calls);
2257 		break;
2258 
2259 	case CS_IO_GOODWAKEUPS:
2260 		ctl_putuint(sys_var[varid].text, handler_pkts);
2261 		break;
2262 
2263 	case CS_TIMERSTATS_RESET:
2264 		ctl_putuint(sys_var[varid].text,
2265 			    current_time - timer_timereset);
2266 		break;
2267 
2268 	case CS_TIMER_OVERRUNS:
2269 		ctl_putuint(sys_var[varid].text, alarm_overflow);
2270 		break;
2271 
2272 	case CS_TIMER_XMTS:
2273 		ctl_putuint(sys_var[varid].text, timer_xmtcalls);
2274 		break;
2275 
2276 	case CS_FUZZ:
2277 		ctl_putdbl(sys_var[varid].text, sys_fuzz * 1e3);
2278 		break;
2279 #ifdef AUTOKEY
2280 	case CS_FLAGS:
2281 		if (crypto_flags)
2282 			ctl_puthex(sys_var[CS_FLAGS].text,
2283 			    crypto_flags);
2284 		break;
2285 
2286 	case CS_DIGEST:
2287 		if (crypto_flags) {
2288 			strlcpy(str, OBJ_nid2ln(crypto_nid),
2289 			    COUNTOF(str));
2290 			ctl_putstr(sys_var[CS_DIGEST].text, str,
2291 			    strlen(str));
2292 		}
2293 		break;
2294 
2295 	case CS_SIGNATURE:
2296 		if (crypto_flags) {
2297 			const EVP_MD *dp;
2298 
2299 			dp = EVP_get_digestbynid(crypto_flags >> 16);
2300 			strlcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)),
2301 			    COUNTOF(str));
2302 			ctl_putstr(sys_var[CS_SIGNATURE].text, str,
2303 			    strlen(str));
2304 		}
2305 		break;
2306 
2307 	case CS_HOST:
2308 		if (hostval.ptr != NULL)
2309 			ctl_putstr(sys_var[CS_HOST].text, hostval.ptr,
2310 			    strlen(hostval.ptr));
2311 		break;
2312 
2313 	case CS_IDENT:
2314 		if (sys_ident != NULL)
2315 			ctl_putstr(sys_var[CS_IDENT].text, sys_ident,
2316 			    strlen(sys_ident));
2317 		break;
2318 
2319 	case CS_CERTIF:
2320 		for (cp = cinfo; cp != NULL; cp = cp->link) {
2321 			snprintf(str, sizeof(str), "%s %s 0x%x",
2322 			    cp->subject, cp->issuer, cp->flags);
2323 			ctl_putstr(sys_var[CS_CERTIF].text, str,
2324 			    strlen(str));
2325 			ctl_putfs(sys_var[CS_REVTIME].text, cp->last);
2326 		}
2327 		break;
2328 
2329 	case CS_PUBLIC:
2330 		if (hostval.tstamp != 0)
2331 			ctl_putfs(sys_var[CS_PUBLIC].text,
2332 			    ntohl(hostval.tstamp));
2333 		break;
2334 #endif	/* AUTOKEY */
2335 	}
2336 }
2337 
2338 
2339 /*
2340  * ctl_putpeer - output a peer variable
2341  */
2342 static void
2343 ctl_putpeer(
2344 	int id,
2345 	struct peer *p
2346 	)
2347 {
2348 	char buf[CTL_MAX_DATA_LEN];
2349 	char *s;
2350 	char *t;
2351 	char *be;
2352 	int i;
2353 	const struct ctl_var *k;
2354 #ifdef AUTOKEY
2355 	struct autokey *ap;
2356 	const EVP_MD *dp;
2357 	const char *str;
2358 #endif	/* AUTOKEY */
2359 
2360 	switch (id) {
2361 
2362 	case CP_CONFIG:
2363 		ctl_putuint(peer_var[id].text,
2364 			    !(FLAG_PREEMPT & p->flags));
2365 		break;
2366 
2367 	case CP_AUTHENABLE:
2368 		ctl_putuint(peer_var[id].text, !(p->keyid));
2369 		break;
2370 
2371 	case CP_AUTHENTIC:
2372 		ctl_putuint(peer_var[id].text,
2373 			    !!(FLAG_AUTHENTIC & p->flags));
2374 		break;
2375 
2376 	case CP_SRCADR:
2377 		ctl_putadr(peer_var[id].text, 0, &p->srcadr);
2378 		break;
2379 
2380 	case CP_SRCPORT:
2381 		ctl_putuint(peer_var[id].text, SRCPORT(&p->srcadr));
2382 		break;
2383 
2384 	case CP_SRCHOST:
2385 		if (p->hostname != NULL)
2386 			ctl_putstr(peer_var[id].text, p->hostname,
2387 				   strlen(p->hostname));
2388 		break;
2389 
2390 	case CP_DSTADR:
2391 		ctl_putadr(peer_var[id].text, 0,
2392 			   (p->dstadr != NULL)
2393 				? &p->dstadr->sin
2394 				: NULL);
2395 		break;
2396 
2397 	case CP_DSTPORT:
2398 		ctl_putuint(peer_var[id].text,
2399 			    (p->dstadr != NULL)
2400 				? SRCPORT(&p->dstadr->sin)
2401 				: 0);
2402 		break;
2403 
2404 	case CP_IN:
2405 		if (p->r21 > 0.)
2406 			ctl_putdbl(peer_var[id].text, p->r21 / 1e3);
2407 		break;
2408 
2409 	case CP_OUT:
2410 		if (p->r34 > 0.)
2411 			ctl_putdbl(peer_var[id].text, p->r34 / 1e3);
2412 		break;
2413 
2414 	case CP_RATE:
2415 		ctl_putuint(peer_var[id].text, p->throttle);
2416 		break;
2417 
2418 	case CP_LEAP:
2419 		ctl_putuint(peer_var[id].text, p->leap);
2420 		break;
2421 
2422 	case CP_HMODE:
2423 		ctl_putuint(peer_var[id].text, p->hmode);
2424 		break;
2425 
2426 	case CP_STRATUM:
2427 		ctl_putuint(peer_var[id].text, p->stratum);
2428 		break;
2429 
2430 	case CP_PPOLL:
2431 		ctl_putuint(peer_var[id].text, p->ppoll);
2432 		break;
2433 
2434 	case CP_HPOLL:
2435 		ctl_putuint(peer_var[id].text, p->hpoll);
2436 		break;
2437 
2438 	case CP_PRECISION:
2439 		ctl_putint(peer_var[id].text, p->precision);
2440 		break;
2441 
2442 	case CP_ROOTDELAY:
2443 		ctl_putdbl(peer_var[id].text, p->rootdelay * 1e3);
2444 		break;
2445 
2446 	case CP_ROOTDISPERSION:
2447 		ctl_putdbl(peer_var[id].text, p->rootdisp * 1e3);
2448 		break;
2449 
2450 	case CP_REFID:
2451 #ifdef REFCLOCK
2452 		if (p->flags & FLAG_REFCLOCK) {
2453 			ctl_putrefid(peer_var[id].text, p->refid);
2454 			break;
2455 		}
2456 #endif
2457 		if (p->stratum > 1 && p->stratum < STRATUM_UNSPEC)
2458 			ctl_putadr(peer_var[id].text, p->refid,
2459 				   NULL);
2460 		else
2461 			ctl_putrefid(peer_var[id].text, p->refid);
2462 		break;
2463 
2464 	case CP_REFTIME:
2465 		ctl_putts(peer_var[id].text, &p->reftime);
2466 		break;
2467 
2468 	case CP_ORG:
2469 		ctl_putts(peer_var[id].text, &p->aorg);
2470 		break;
2471 
2472 	case CP_REC:
2473 		ctl_putts(peer_var[id].text, &p->dst);
2474 		break;
2475 
2476 	case CP_XMT:
2477 		if (p->xleave)
2478 			ctl_putdbl(peer_var[id].text, p->xleave * 1e3);
2479 		break;
2480 
2481 	case CP_BIAS:
2482 		if (p->bias != 0.)
2483 			ctl_putdbl(peer_var[id].text, p->bias * 1e3);
2484 		break;
2485 
2486 	case CP_REACH:
2487 		ctl_puthex(peer_var[id].text, p->reach);
2488 		break;
2489 
2490 	case CP_FLASH:
2491 		ctl_puthex(peer_var[id].text, p->flash);
2492 		break;
2493 
2494 	case CP_TTL:
2495 #ifdef REFCLOCK
2496 		if (p->flags & FLAG_REFCLOCK) {
2497 			ctl_putuint(peer_var[id].text, p->ttl);
2498 			break;
2499 		}
2500 #endif
2501 		if (p->ttl > 0 && p->ttl < COUNTOF(sys_ttl))
2502 			ctl_putint(peer_var[id].text,
2503 				   sys_ttl[p->ttl]);
2504 		break;
2505 
2506 	case CP_UNREACH:
2507 		ctl_putuint(peer_var[id].text, p->unreach);
2508 		break;
2509 
2510 	case CP_TIMER:
2511 		ctl_putuint(peer_var[id].text,
2512 			    p->nextdate - current_time);
2513 		break;
2514 
2515 	case CP_DELAY:
2516 		ctl_putdbl(peer_var[id].text, p->delay * 1e3);
2517 		break;
2518 
2519 	case CP_OFFSET:
2520 		ctl_putdbl(peer_var[id].text, p->offset * 1e3);
2521 		break;
2522 
2523 	case CP_JITTER:
2524 		ctl_putdbl(peer_var[id].text, p->jitter * 1e3);
2525 		break;
2526 
2527 	case CP_DISPERSION:
2528 		ctl_putdbl(peer_var[id].text, p->disp * 1e3);
2529 		break;
2530 
2531 	case CP_KEYID:
2532 		if (p->keyid > NTP_MAXKEY)
2533 			ctl_puthex(peer_var[id].text, p->keyid);
2534 		else
2535 			ctl_putuint(peer_var[id].text, p->keyid);
2536 		break;
2537 
2538 	case CP_FILTDELAY:
2539 		ctl_putarray(peer_var[id].text, p->filter_delay,
2540 			     p->filter_nextpt);
2541 		break;
2542 
2543 	case CP_FILTOFFSET:
2544 		ctl_putarray(peer_var[id].text, p->filter_offset,
2545 			     p->filter_nextpt);
2546 		break;
2547 
2548 	case CP_FILTERROR:
2549 		ctl_putarray(peer_var[id].text, p->filter_disp,
2550 			     p->filter_nextpt);
2551 		break;
2552 
2553 	case CP_PMODE:
2554 		ctl_putuint(peer_var[id].text, p->pmode);
2555 		break;
2556 
2557 	case CP_RECEIVED:
2558 		ctl_putuint(peer_var[id].text, p->received);
2559 		break;
2560 
2561 	case CP_SENT:
2562 		ctl_putuint(peer_var[id].text, p->sent);
2563 		break;
2564 
2565 	case CP_VARLIST:
2566 		s = buf;
2567 		be = buf + sizeof(buf);
2568 		if (strlen(peer_var[id].text) + 4 > sizeof(buf))
2569 			break;	/* really long var name */
2570 
2571 		snprintf(s, sizeof(buf), "%s=\"", peer_var[id].text);
2572 		s += strlen(s);
2573 		t = s;
2574 		for (k = peer_var; !(EOV & k->flags); k++) {
2575 			if (PADDING & k->flags)
2576 				continue;
2577 			i = strlen(k->text);
2578 			if (s + i + 1 >= be)
2579 				break;
2580 			if (s != t)
2581 				*s++ = ',';
2582 			memcpy(s, k->text, i);
2583 			s += i;
2584 		}
2585 		if (s + 2 < be) {
2586 			*s++ = '"';
2587 			*s = '\0';
2588 			ctl_putdata(buf, (u_int)(s - buf), 0);
2589 		}
2590 		break;
2591 
2592 	case CP_TIMEREC:
2593 		ctl_putuint(peer_var[id].text,
2594 			    current_time - p->timereceived);
2595 		break;
2596 
2597 	case CP_TIMEREACH:
2598 		ctl_putuint(peer_var[id].text,
2599 			    current_time - p->timereachable);
2600 		break;
2601 
2602 	case CP_BADAUTH:
2603 		ctl_putuint(peer_var[id].text, p->badauth);
2604 		break;
2605 
2606 	case CP_BOGUSORG:
2607 		ctl_putuint(peer_var[id].text, p->bogusorg);
2608 		break;
2609 
2610 	case CP_OLDPKT:
2611 		ctl_putuint(peer_var[id].text, p->oldpkt);
2612 		break;
2613 
2614 	case CP_SELDISP:
2615 		ctl_putuint(peer_var[id].text, p->seldisptoolarge);
2616 		break;
2617 
2618 	case CP_SELBROKEN:
2619 		ctl_putuint(peer_var[id].text, p->selbroken);
2620 		break;
2621 
2622 	case CP_CANDIDATE:
2623 		ctl_putuint(peer_var[id].text, p->status);
2624 		break;
2625 #ifdef AUTOKEY
2626 	case CP_FLAGS:
2627 		if (p->crypto)
2628 			ctl_puthex(peer_var[id].text, p->crypto);
2629 		break;
2630 
2631 	case CP_SIGNATURE:
2632 		if (p->crypto) {
2633 			dp = EVP_get_digestbynid(p->crypto >> 16);
2634 			str = OBJ_nid2ln(EVP_MD_pkey_type(dp));
2635 			ctl_putstr(peer_var[id].text, str, strlen(str));
2636 		}
2637 		break;
2638 
2639 	case CP_HOST:
2640 		if (p->subject != NULL)
2641 			ctl_putstr(peer_var[id].text, p->subject,
2642 			    strlen(p->subject));
2643 		break;
2644 
2645 	case CP_VALID:		/* not used */
2646 		break;
2647 
2648 	case CP_INITSEQ:
2649 		if (NULL == (ap = p->recval.ptr))
2650 			break;
2651 
2652 		ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
2653 		ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
2654 		ctl_putfs(peer_var[CP_INITTSP].text,
2655 			  ntohl(p->recval.tstamp));
2656 		break;
2657 
2658 	case CP_IDENT:
2659 		if (p->ident != NULL)
2660 			ctl_putstr(peer_var[id].text, p->ident,
2661 			    strlen(p->ident));
2662 		break;
2663 
2664 
2665 #endif	/* AUTOKEY */
2666 	}
2667 }
2668 
2669 
2670 #ifdef REFCLOCK
2671 /*
2672  * ctl_putclock - output clock variables
2673  */
2674 static void
2675 ctl_putclock(
2676 	int id,
2677 	struct refclockstat *pcs,
2678 	int mustput
2679 	)
2680 {
2681 	char buf[CTL_MAX_DATA_LEN];
2682 	char *s, *t, *be;
2683 	const char *ss;
2684 	int i;
2685 	const struct ctl_var *k;
2686 
2687 	switch (id) {
2688 
2689 	case CC_TYPE:
2690 		if (mustput || pcs->clockdesc == NULL
2691 		    || *(pcs->clockdesc) == '\0') {
2692 			ctl_putuint(clock_var[id].text, pcs->type);
2693 		}
2694 		break;
2695 	case CC_TIMECODE:
2696 		ctl_putstr(clock_var[id].text,
2697 			   pcs->p_lastcode,
2698 			   (unsigned)pcs->lencode);
2699 		break;
2700 
2701 	case CC_POLL:
2702 		ctl_putuint(clock_var[id].text, pcs->polls);
2703 		break;
2704 
2705 	case CC_NOREPLY:
2706 		ctl_putuint(clock_var[id].text,
2707 			    pcs->noresponse);
2708 		break;
2709 
2710 	case CC_BADFORMAT:
2711 		ctl_putuint(clock_var[id].text,
2712 			    pcs->badformat);
2713 		break;
2714 
2715 	case CC_BADDATA:
2716 		ctl_putuint(clock_var[id].text,
2717 			    pcs->baddata);
2718 		break;
2719 
2720 	case CC_FUDGETIME1:
2721 		if (mustput || (pcs->haveflags & CLK_HAVETIME1))
2722 			ctl_putdbl(clock_var[id].text,
2723 				   pcs->fudgetime1 * 1e3);
2724 		break;
2725 
2726 	case CC_FUDGETIME2:
2727 		if (mustput || (pcs->haveflags & CLK_HAVETIME2))
2728 			ctl_putdbl(clock_var[id].text,
2729 				   pcs->fudgetime2 * 1e3);
2730 		break;
2731 
2732 	case CC_FUDGEVAL1:
2733 		if (mustput || (pcs->haveflags & CLK_HAVEVAL1))
2734 			ctl_putint(clock_var[id].text,
2735 				   pcs->fudgeval1);
2736 		break;
2737 
2738 	case CC_FUDGEVAL2:
2739 		if (mustput || (pcs->haveflags & CLK_HAVEVAL2)) {
2740 			if (pcs->fudgeval1 > 1)
2741 				ctl_putadr(clock_var[id].text,
2742 					   pcs->fudgeval2, NULL);
2743 			else
2744 				ctl_putrefid(clock_var[id].text,
2745 					     pcs->fudgeval2);
2746 		}
2747 		break;
2748 
2749 	case CC_FLAGS:
2750 		ctl_putuint(clock_var[id].text, pcs->flags);
2751 		break;
2752 
2753 	case CC_DEVICE:
2754 		if (pcs->clockdesc == NULL ||
2755 		    *(pcs->clockdesc) == '\0') {
2756 			if (mustput)
2757 				ctl_putstr(clock_var[id].text,
2758 					   "", 0);
2759 		} else {
2760 			ctl_putstr(clock_var[id].text,
2761 				   pcs->clockdesc,
2762 				   strlen(pcs->clockdesc));
2763 		}
2764 		break;
2765 
2766 	case CC_VARLIST:
2767 		s = buf;
2768 		be = buf + sizeof(buf);
2769 		if (strlen(clock_var[CC_VARLIST].text) + 4 >
2770 		    sizeof(buf))
2771 			break;	/* really long var name */
2772 
2773 		snprintf(s, sizeof(buf), "%s=\"",
2774 			 clock_var[CC_VARLIST].text);
2775 		s += strlen(s);
2776 		t = s;
2777 
2778 		for (k = clock_var; !(EOV & k->flags); k++) {
2779 			if (PADDING & k->flags)
2780 				continue;
2781 
2782 			i = strlen(k->text);
2783 			if (s + i + 1 >= be)
2784 				break;
2785 
2786 			if (s != t)
2787 				*s++ = ',';
2788 			memcpy(s, k->text, i);
2789 			s += i;
2790 		}
2791 
2792 		for (k = pcs->kv_list; k && !(EOV & k->flags); k++) {
2793 			if (PADDING & k->flags)
2794 				continue;
2795 
2796 			ss = k->text;
2797 			if (NULL == ss)
2798 				continue;
2799 
2800 			while (*ss && *ss != '=')
2801 				ss++;
2802 			i = ss - k->text;
2803 			if (s + i + 1 >= be)
2804 				break;
2805 
2806 			if (s != t)
2807 				*s++ = ',';
2808 			memcpy(s, k->text, (unsigned)i);
2809 			s += i;
2810 			*s = '\0';
2811 		}
2812 		if (s + 2 >= be)
2813 			break;
2814 
2815 		*s++ = '"';
2816 		*s = '\0';
2817 		ctl_putdata(buf, (unsigned)(s - buf), 0);
2818 		break;
2819 	}
2820 }
2821 #endif
2822 
2823 
2824 
2825 /*
2826  * ctl_getitem - get the next data item from the incoming packet
2827  */
2828 static const struct ctl_var *
2829 ctl_getitem(
2830 	const struct ctl_var *var_list,
2831 	char **data
2832 	)
2833 {
2834 	static const struct ctl_var eol = { 0, EOV, NULL };
2835 	static char buf[128];
2836 	static u_long quiet_until;
2837 	const struct ctl_var *v;
2838 	const char *pch;
2839 	char *cp;
2840 	char *tp;
2841 
2842 	/*
2843 	 * Delete leading commas and white space
2844 	 */
2845 	while (reqpt < reqend && (*reqpt == ',' ||
2846 				  isspace((unsigned char)*reqpt)))
2847 		reqpt++;
2848 	if (reqpt >= reqend)
2849 		return NULL;
2850 
2851 	if (NULL == var_list)
2852 		return &eol;
2853 
2854 	/*
2855 	 * Look for a first character match on the tag.  If we find
2856 	 * one, see if it is a full match.
2857 	 */
2858 	v = var_list;
2859 	cp = reqpt;
2860 	for (v = var_list; !(EOV & v->flags); v++) {
2861 		if (!(PADDING & v->flags) && *cp == *(v->text)) {
2862 			pch = v->text;
2863 			while ('\0' != *pch && '=' != *pch && cp < reqend
2864 			       && *cp == *pch) {
2865 				cp++;
2866 				pch++;
2867 			}
2868 			if ('\0' == *pch || '=' == *pch) {
2869 				while (cp < reqend && isspace((u_char)*cp))
2870 					cp++;
2871 				if (cp == reqend || ',' == *cp) {
2872 					buf[0] = '\0';
2873 					*data = buf;
2874 					if (cp < reqend)
2875 						cp++;
2876 					reqpt = cp;
2877 					return v;
2878 				}
2879 				if ('=' == *cp) {
2880 					cp++;
2881 					tp = buf;
2882 					while (cp < reqend && isspace((u_char)*cp))
2883 						cp++;
2884 					while (cp < reqend && *cp != ',') {
2885 						*tp++ = *cp++;
2886 						if ((size_t)(tp - buf) >= sizeof(buf)) {
2887 							ctl_error(CERR_BADFMT);
2888 							numctlbadpkts++;
2889 							NLOG(NLOG_SYSEVENT)
2890 								if (quiet_until <= current_time) {
2891 									quiet_until = current_time + 300;
2892 									msyslog(LOG_WARNING,
2893 "Possible 'ntpdx' exploit from %s#%u (possibly spoofed)", stoa(rmt_addr), SRCPORT(rmt_addr));
2894 								}
2895 							return NULL;
2896 						}
2897 					}
2898 					if (cp < reqend)
2899 						cp++;
2900 					*tp-- = '\0';
2901 					while (tp >= buf && isspace((u_char)*tp))
2902 						*tp-- = '\0';
2903 					reqpt = cp;
2904 					*data = buf;
2905 					return v;
2906 				}
2907 			}
2908 			cp = reqpt;
2909 		}
2910 	}
2911 	return v;
2912 }
2913 
2914 
2915 /*
2916  * control_unspec - response to an unspecified op-code
2917  */
2918 /*ARGSUSED*/
2919 static void
2920 control_unspec(
2921 	struct recvbuf *rbufp,
2922 	int restrict_mask
2923 	)
2924 {
2925 	struct peer *peer;
2926 
2927 	/*
2928 	 * What is an appropriate response to an unspecified op-code?
2929 	 * I return no errors and no data, unless a specified assocation
2930 	 * doesn't exist.
2931 	 */
2932 	if (res_associd) {
2933 		peer = findpeerbyassoc(res_associd);
2934 		if (NULL == peer) {
2935 			ctl_error(CERR_BADASSOC);
2936 			return;
2937 		}
2938 		rpkt.status = htons(ctlpeerstatus(peer));
2939 	} else
2940 		rpkt.status = htons(ctlsysstatus());
2941 	ctl_flushpkt(0);
2942 }
2943 
2944 
2945 /*
2946  * read_status - return either a list of associd's, or a particular
2947  * peer's status.
2948  */
2949 /*ARGSUSED*/
2950 static void
2951 read_status(
2952 	struct recvbuf *rbufp,
2953 	int restrict_mask
2954 	)
2955 {
2956 	struct peer *peer;
2957 	const u_char *cp;
2958 	size_t n;
2959 	/* a_st holds association ID, status pairs alternating */
2960 	u_short a_st[CTL_MAX_DATA_LEN / sizeof(u_short)];
2961 
2962 #ifdef DEBUG
2963 	if (debug > 2)
2964 		printf("read_status: ID %d\n", res_associd);
2965 #endif
2966 	/*
2967 	 * Two choices here. If the specified association ID is
2968 	 * zero we return all known assocation ID's.  Otherwise
2969 	 * we return a bunch of stuff about the particular peer.
2970 	 */
2971 	if (res_associd) {
2972 		peer = findpeerbyassoc(res_associd);
2973 		if (NULL == peer) {
2974 			ctl_error(CERR_BADASSOC);
2975 			return;
2976 		}
2977 		rpkt.status = htons(ctlpeerstatus(peer));
2978 		if (res_authokay)
2979 			peer->num_events = 0;
2980 		/*
2981 		 * For now, output everything we know about the
2982 		 * peer. May be more selective later.
2983 		 */
2984 		for (cp = def_peer_var; *cp != 0; cp++)
2985 			ctl_putpeer((int)*cp, peer);
2986 		ctl_flushpkt(0);
2987 		return;
2988 	}
2989 	n = 0;
2990 	rpkt.status = htons(ctlsysstatus());
2991 	for (peer = peer_list; peer != NULL; peer = peer->p_link) {
2992 		a_st[n++] = htons(peer->associd);
2993 		a_st[n++] = htons(ctlpeerstatus(peer));
2994 		/* two entries each loop iteration, so n + 1 */
2995 		if (n + 1 >= COUNTOF(a_st)) {
2996 			ctl_putdata((void *)a_st, n * sizeof(a_st[0]),
2997 				    1);
2998 			n = 0;
2999 		}
3000 	}
3001 	if (n)
3002 		ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 1);
3003 	ctl_flushpkt(0);
3004 }
3005 
3006 
3007 /*
3008  * read_peervars - half of read_variables() implementation
3009  */
3010 static void
3011 read_peervars(void)
3012 {
3013 	const struct ctl_var *v;
3014 	struct peer *peer;
3015 	const u_char *cp;
3016 	size_t i;
3017 	char *	valuep;
3018 	u_char	wants[CP_MAXCODE + 1];
3019 	u_int	gotvar;
3020 
3021 	/*
3022 	 * Wants info for a particular peer. See if we know
3023 	 * the guy.
3024 	 */
3025 	peer = findpeerbyassoc(res_associd);
3026 	if (NULL == peer) {
3027 		ctl_error(CERR_BADASSOC);
3028 		return;
3029 	}
3030 	rpkt.status = htons(ctlpeerstatus(peer));
3031 	if (res_authokay)
3032 		peer->num_events = 0;
3033 	ZERO(wants);
3034 	gotvar = 0;
3035 	while (NULL != (v = ctl_getitem(peer_var, &valuep))) {
3036 		if (v->flags & EOV) {
3037 			ctl_error(CERR_UNKNOWNVAR);
3038 			return;
3039 		}
3040 		NTP_INSIST(v->code < COUNTOF(wants));
3041 		wants[v->code] = 1;
3042 		gotvar = 1;
3043 	}
3044 	if (gotvar) {
3045 		for (i = 1; i < COUNTOF(wants); i++)
3046 			if (wants[i])
3047 				ctl_putpeer(i, peer);
3048 	} else
3049 		for (cp = def_peer_var; *cp != 0; cp++)
3050 			ctl_putpeer((int)*cp, peer);
3051 	ctl_flushpkt(0);
3052 }
3053 
3054 
3055 /*
3056  * read_sysvars - half of read_variables() implementation
3057  */
3058 static void
3059 read_sysvars(void)
3060 {
3061 	const struct ctl_var *v;
3062 	struct ctl_var *kv;
3063 	u_int	n;
3064 	u_int	gotvar;
3065 	const u_char *cs;
3066 	char *	valuep;
3067 	const char * pch;
3068 	u_char *wants;
3069 	size_t	wants_count;
3070 
3071 	/*
3072 	 * Wants system variables. Figure out which he wants
3073 	 * and give them to him.
3074 	 */
3075 	rpkt.status = htons(ctlsysstatus());
3076 	if (res_authokay)
3077 		ctl_sys_num_events = 0;
3078 	wants_count = CS_MAXCODE + 1 + count_var(ext_sys_var);
3079 	wants = emalloc_zero(wants_count);
3080 	gotvar = 0;
3081 	while (NULL != (v = ctl_getitem(sys_var, &valuep))) {
3082 		if (!(EOV & v->flags)) {
3083 			NTP_INSIST(v->code < wants_count);
3084 			wants[v->code] = 1;
3085 			gotvar = 1;
3086 		} else {
3087 			v = ctl_getitem(ext_sys_var, &valuep);
3088 			NTP_INSIST(v != NULL);
3089 			if (EOV & v->flags) {
3090 				ctl_error(CERR_UNKNOWNVAR);
3091 				free(wants);
3092 				return;
3093 			}
3094 			n = v->code + CS_MAXCODE + 1;
3095 			NTP_INSIST(n < wants_count);
3096 			wants[n] = 1;
3097 			gotvar = 1;
3098 		}
3099 	}
3100 	if (gotvar) {
3101 		for (n = 1; n <= CS_MAXCODE; n++)
3102 			if (wants[n])
3103 				ctl_putsys(n);
3104 		for (n = 0; n + CS_MAXCODE + 1 < wants_count; n++)
3105 			if (wants[n + CS_MAXCODE + 1]) {
3106 				pch = ext_sys_var[n].text;
3107 				ctl_putdata(pch, strlen(pch), 0);
3108 			}
3109 	} else {
3110 		for (cs = def_sys_var; *cs != 0; cs++)
3111 			ctl_putsys((int)*cs);
3112 		for (kv = ext_sys_var; kv && !(EOV & kv->flags); kv++)
3113 			if (DEF & kv->flags)
3114 				ctl_putdata(kv->text, strlen(kv->text),
3115 					    0);
3116 	}
3117 	free(wants);
3118 	ctl_flushpkt(0);
3119 }
3120 
3121 
3122 /*
3123  * read_variables - return the variables the caller asks for
3124  */
3125 /*ARGSUSED*/
3126 static void
3127 read_variables(
3128 	struct recvbuf *rbufp,
3129 	int restrict_mask
3130 	)
3131 {
3132 	if (res_associd)
3133 		read_peervars();
3134 	else
3135 		read_sysvars();
3136 }
3137 
3138 
3139 /*
3140  * write_variables - write into variables. We only allow leap bit
3141  * writing this way.
3142  */
3143 /*ARGSUSED*/
3144 static void
3145 write_variables(
3146 	struct recvbuf *rbufp,
3147 	int restrict_mask
3148 	)
3149 {
3150 	const struct ctl_var *v;
3151 	int ext_var;
3152 	char *valuep;
3153 	long val;
3154 	size_t octets;
3155 	char *vareqv;
3156 	const char *t;
3157 	char *tt;
3158 
3159 	val = 0;
3160 	/*
3161 	 * If he's trying to write into a peer tell him no way
3162 	 */
3163 	if (res_associd != 0) {
3164 		ctl_error(CERR_PERMISSION);
3165 		return;
3166 	}
3167 
3168 	/*
3169 	 * Set status
3170 	 */
3171 	rpkt.status = htons(ctlsysstatus());
3172 
3173 	/*
3174 	 * Look through the variables. Dump out at the first sign of
3175 	 * trouble.
3176 	 */
3177 	while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
3178 		ext_var = 0;
3179 		if (v->flags & EOV) {
3180 			if ((v = ctl_getitem(ext_sys_var, &valuep)) !=
3181 			    0) {
3182 				if (v->flags & EOV) {
3183 					ctl_error(CERR_UNKNOWNVAR);
3184 					return;
3185 				}
3186 				ext_var = 1;
3187 			} else {
3188 				break;
3189 			}
3190 		}
3191 		if (!(v->flags & CAN_WRITE)) {
3192 			ctl_error(CERR_PERMISSION);
3193 			return;
3194 		}
3195 		if (!ext_var && (*valuep == '\0' || !atoint(valuep,
3196 							    &val))) {
3197 			ctl_error(CERR_BADFMT);
3198 			return;
3199 		}
3200 		if (!ext_var && (val & ~LEAP_NOTINSYNC) != 0) {
3201 			ctl_error(CERR_BADVALUE);
3202 			return;
3203 		}
3204 
3205 		if (ext_var) {
3206 			octets = strlen(v->text) + strlen(valuep) + 2;
3207 			vareqv = emalloc(octets);
3208 			tt = vareqv;
3209 			t = v->text;
3210 			while (*t && *t != '=')
3211 				*tt++ = *t++;
3212 			*tt++ = '=';
3213 			memcpy(tt, valuep, 1 + strlen(valuep));
3214 			set_sys_var(vareqv, 1 + strlen(vareqv), v->flags);
3215 			free(vareqv);
3216 		} else {
3217 			ctl_error(CERR_UNSPEC); /* really */
3218 			return;
3219 		}
3220 	}
3221 
3222 	/*
3223 	 * If we got anything, do it. xxx nothing to do ***
3224 	 */
3225 	/*
3226 	  if (leapind != ~0 || leapwarn != ~0) {
3227 	  if (!leap_setleap((int)leapind, (int)leapwarn)) {
3228 	  ctl_error(CERR_PERMISSION);
3229 	  return;
3230 	  }
3231 	  }
3232 	*/
3233 	ctl_flushpkt(0);
3234 }
3235 
3236 /*
3237  * configure() processes ntpq :config/config-from-file, allowing
3238  *		generic runtime reconfiguration.
3239  */
3240 static void configure(
3241 	struct recvbuf *rbufp,
3242 	int restrict_mask
3243 	)
3244 {
3245 	size_t data_count;
3246 	int retval;
3247 	int replace_nl;
3248 
3249 	/* I haven't yet implemented changes to an existing association.
3250 	 * Hence check if the association id is 0
3251 	 */
3252 	if (res_associd != 0) {
3253 		ctl_error(CERR_BADVALUE);
3254 		return;
3255 	}
3256 
3257 	if (RES_NOMODIFY & restrict_mask) {
3258 		snprintf(remote_config.err_msg,
3259 			 sizeof(remote_config.err_msg),
3260 			 "runtime configuration prohibited by restrict ... nomodify");
3261 		ctl_putdata(remote_config.err_msg,
3262 			    strlen(remote_config.err_msg), 0);
3263 		ctl_flushpkt(0);
3264 		NLOG(NLOG_SYSINFO)
3265 			msyslog(LOG_NOTICE,
3266 				"runtime config from %s rejected due to nomodify restriction",
3267 				stoa(&rbufp->recv_srcadr));
3268 		sys_restricted++;
3269 		return;
3270 	}
3271 
3272 	/* Initialize the remote config buffer */
3273 	data_count = reqend - reqpt;
3274 	memcpy(remote_config.buffer, reqpt, data_count);
3275 	if (data_count > 0
3276 	    && '\n' != remote_config.buffer[data_count - 1])
3277 		remote_config.buffer[data_count++] = '\n';
3278 	remote_config.buffer[data_count] = '\0';
3279 	remote_config.pos = 0;
3280 	remote_config.err_pos = 0;
3281 	remote_config.no_errors = 0;
3282 
3283 	/* do not include terminating newline in log */
3284 	if (data_count > 0
3285 	    && '\n' == remote_config.buffer[data_count - 1]) {
3286 		remote_config.buffer[data_count - 1] = '\0';
3287 		replace_nl = TRUE;
3288 	} else {
3289 		replace_nl = FALSE;
3290 	}
3291 
3292 	DPRINTF(1, ("Got Remote Configuration Command: %s\n",
3293 		remote_config.buffer));
3294 	msyslog(LOG_NOTICE, "%s config: %s",
3295 		stoa(&rbufp->recv_srcadr),
3296 		remote_config.buffer);
3297 
3298 	if (replace_nl)
3299 		remote_config.buffer[data_count - 1] = '\n';
3300 
3301 	config_remotely(&rbufp->recv_srcadr);
3302 
3303 	/*
3304 	 * Check if errors were reported. If not, output 'Config
3305 	 * Succeeded'.  Else output the error count.  It would be nice
3306 	 * to output any parser error messages.
3307 	 */
3308 	if (0 == remote_config.no_errors) {
3309 		retval = snprintf(remote_config.err_msg,
3310 				  sizeof(remote_config.err_msg),
3311 				  "Config Succeeded");
3312 		if (retval > 0)
3313 			remote_config.err_pos += retval;
3314 	}
3315 
3316 	ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0);
3317 	ctl_flushpkt(0);
3318 
3319 	DPRINTF(1, ("Reply: %s\n", remote_config.err_msg));
3320 
3321 	if (remote_config.no_errors > 0)
3322 		msyslog(LOG_NOTICE, "%d error in %s config",
3323 			remote_config.no_errors,
3324 			stoa(&rbufp->recv_srcadr));
3325 }
3326 
3327 
3328 /*
3329  * derive_nonce - generate client-address-specific nonce value
3330  *		  associated with a given timestamp.
3331  */
3332 static u_int32 derive_nonce(
3333 	sockaddr_u *	addr,
3334 	u_int32		ts_i,
3335 	u_int32		ts_f
3336 	)
3337 {
3338 	static u_int32	salt[2];
3339 	union d_tag {
3340 		u_char	digest[EVP_MAX_MD_SIZE];
3341 		u_int32 extract;
3342 	}		d;
3343 	EVP_MD_CTX	ctx;
3344 	u_int		len;
3345 
3346 	while (!salt[0])
3347 		salt[0] = ntp_random();
3348 	salt[1] = conf_file_sum;
3349 
3350 	EVP_DigestInit(&ctx, EVP_get_digestbynid(NID_md5));
3351 	EVP_DigestUpdate(&ctx, salt, sizeof(salt));
3352 	EVP_DigestUpdate(&ctx, &ts_i, sizeof(ts_i));
3353 	EVP_DigestUpdate(&ctx, &ts_f, sizeof(ts_f));
3354 	if (IS_IPV4(addr))
3355 		EVP_DigestUpdate(&ctx, &SOCK_ADDR4(addr),
3356 			         sizeof(SOCK_ADDR4(addr)));
3357 	else
3358 		EVP_DigestUpdate(&ctx, &SOCK_ADDR6(addr),
3359 			         sizeof(SOCK_ADDR6(addr)));
3360 	EVP_DigestUpdate(&ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr)));
3361 	EVP_DigestUpdate(&ctx, salt, sizeof(salt));
3362 	EVP_DigestFinal(&ctx, d.digest, &len);
3363 
3364 	return d.extract;
3365 }
3366 
3367 
3368 /*
3369  * generate_nonce - generate client-address-specific nonce string.
3370  */
3371 static void generate_nonce(
3372 	struct recvbuf *	rbufp,
3373 	char *			nonce,
3374 	size_t			nonce_octets
3375 	)
3376 {
3377 	u_int32 derived;
3378 
3379 	derived = derive_nonce(&rbufp->recv_srcadr,
3380 			       rbufp->recv_time.l_ui,
3381 			       rbufp->recv_time.l_uf);
3382 	snprintf(nonce, nonce_octets, "%08x%08x%08x",
3383 		 rbufp->recv_time.l_ui, rbufp->recv_time.l_uf, derived);
3384 }
3385 
3386 
3387 /*
3388  * validate_nonce - validate client-address-specific nonce string.
3389  *
3390  * Returns TRUE if the local calculation of the nonce matches the
3391  * client-provided value and the timestamp is recent enough.
3392  */
3393 static int validate_nonce(
3394 	const char *		pnonce,
3395 	struct recvbuf *	rbufp
3396 	)
3397 {
3398 	u_int	ts_i;
3399 	u_int	ts_f;
3400 	l_fp	ts;
3401 	l_fp	now_delta;
3402 	u_int	supposed;
3403 	u_int	derived;
3404 
3405 	if (3 != sscanf(pnonce, "%08x%08x%08x", &ts_i, &ts_f, &supposed))
3406 		return FALSE;
3407 
3408 	ts.l_ui = (u_int32)ts_i;
3409 	ts.l_uf = (u_int32)ts_f;
3410 	derived = derive_nonce(&rbufp->recv_srcadr, ts.l_ui, ts.l_uf);
3411 	get_systime(&now_delta);
3412 	L_SUB(&now_delta, &ts);
3413 
3414 	return (supposed == derived && now_delta.l_ui < 16);
3415 }
3416 
3417 
3418 /*
3419  * send_random_tag_value - send a randomly-generated three character
3420  *			   tag prefix, a '.', an index, a '=' and a
3421  *			   random integer value.
3422  *
3423  * To try to force clients to ignore unrecognized tags in mrulist,
3424  * reslist, and ifstats responses, the first and last rows are spiced
3425  * with randomly-generated tag names with correct .# index.  Make it
3426  * three characters knowing that none of the currently-used subscripted
3427  * tags have that length, avoiding the need to test for
3428  * tag collision.
3429  */
3430 static void
3431 send_random_tag_value(
3432 	int	indx
3433 	)
3434 {
3435 	int	noise;
3436 	char	buf[32];
3437 
3438 	noise = rand() ^ (rand() << 16);
3439 	buf[0] = 'a' + noise % 26;
3440 	noise >>= 5;
3441 	buf[1] = 'a' + noise % 26;
3442 	noise >>= 5;
3443 	buf[2] = 'a' + noise % 26;
3444 	noise >>= 5;
3445 	buf[3] = '.';
3446 	snprintf(&buf[4], sizeof(buf) - 4, "%d", indx);
3447 	ctl_putuint(buf, noise);
3448 }
3449 
3450 
3451 /*
3452  * Send a MRU list entry in response to a "ntpq -c mrulist" operation.
3453  *
3454  * To keep clients honest about not depending on the order of values,
3455  * and thereby avoid being locked into ugly workarounds to maintain
3456  * backward compatibility later as new fields are added to the response,
3457  * the order is random.
3458  */
3459 static void
3460 send_mru_entry(
3461 	mon_entry *	mon,
3462 	int		count
3463 	)
3464 {
3465 	const char first_fmt[] =	"first.%d";
3466 	const char ct_fmt[] =		"ct.%d";
3467 	const char mv_fmt[] =		"mv.%d";
3468 	const char rs_fmt[] =		"rs.%d";
3469 	char	tag[32];
3470 	u_char	sent[6]; /* 6 tag=value pairs */
3471 	u_int32 noise;
3472 	u_int	which;
3473 	u_int	remaining;
3474 	const char * pch;
3475 
3476 	remaining = COUNTOF(sent);
3477 	ZERO(sent);
3478 	noise = (u_int32)(rand() ^ (rand() << 16));
3479 	while (remaining > 0) {
3480 		which = (noise & 7) % COUNTOF(sent);
3481 		noise >>= 3;
3482 		while (sent[which])
3483 			which = (which + 1) % COUNTOF(sent);
3484 
3485 		switch (which) {
3486 
3487 		case 0:
3488 			snprintf(tag, sizeof(tag), addr_fmt, count);
3489 			pch = sptoa(&mon->rmtadr);
3490 			ctl_putunqstr(tag, pch, strlen(pch));
3491 			break;
3492 
3493 		case 1:
3494 			snprintf(tag, sizeof(tag), last_fmt, count);
3495 			ctl_putts(tag, &mon->last);
3496 			break;
3497 
3498 		case 2:
3499 			snprintf(tag, sizeof(tag), first_fmt, count);
3500 			ctl_putts(tag, &mon->first);
3501 			break;
3502 
3503 		case 3:
3504 			snprintf(tag, sizeof(tag), ct_fmt, count);
3505 			ctl_putint(tag, mon->count);
3506 			break;
3507 
3508 		case 4:
3509 			snprintf(tag, sizeof(tag), mv_fmt, count);
3510 			ctl_putuint(tag, mon->vn_mode);
3511 			break;
3512 
3513 		case 5:
3514 			snprintf(tag, sizeof(tag), rs_fmt, count);
3515 			ctl_puthex(tag, mon->flags);
3516 			break;
3517 		}
3518 		sent[which] = TRUE;
3519 		remaining--;
3520 	}
3521 }
3522 
3523 
3524 /*
3525  * read_mru_list - supports ntpq's mrulist command.
3526  *
3527  * The challenge here is to match ntpdc's monlist functionality without
3528  * being limited to hundreds of entries returned total, and without
3529  * requiring state on the server.  If state were required, ntpq's
3530  * mrulist command would require authentication.
3531  *
3532  * The approach was suggested by Ry Jones.  A finite and variable number
3533  * of entries are retrieved per request, to avoid having responses with
3534  * such large numbers of packets that socket buffers are overflowed and
3535  * packets lost.  The entries are retrieved oldest-first, taking into
3536  * account that the MRU list will be changing between each request.  We
3537  * can expect to see duplicate entries for addresses updated in the MRU
3538  * list during the fetch operation.  In the end, the client can assemble
3539  * a close approximation of the MRU list at the point in time the last
3540  * response was sent by ntpd.  The only difference is it may be longer,
3541  * containing some number of oldest entries which have since been
3542  * reclaimed.  If necessary, the protocol could be extended to zap those
3543  * from the client snapshot at the end, but so far that doesn't seem
3544  * useful.
3545  *
3546  * To accomodate the changing MRU list, the starting point for requests
3547  * after the first request is supplied as a series of last seen
3548  * timestamps and associated addresses, the newest ones the client has
3549  * received.  As long as at least one of those entries hasn't been
3550  * bumped to the head of the MRU list, ntpd can pick up at that point.
3551  * Otherwise, the request is failed and it is up to ntpq to back up and
3552  * provide the next newest entry's timestamps and addresses, conceivably
3553  * backing up all the way to the starting point.
3554  *
3555  * input parameters:
3556  *	nonce=		Regurgitated nonce retrieved by the client
3557  *			previously using CTL_OP_REQ_NONCE, demonstrating
3558  *			ability to receive traffic sent to its address.
3559  *	frags=		Limit on datagrams (fragments) in response.  Used
3560  *			by newer ntpq versions instead of limit= when
3561  *			retrieving multiple entries.
3562  *	limit=		Limit on MRU entries returned.  One of frags= or
3563  *			limit= must be provided.
3564  *			limit=1 is a special case:  Instead of fetching
3565  *			beginning with the supplied starting point's
3566  *			newer neighbor, fetch the supplied entry, and
3567  *			in that case the #.last timestamp can be zero.
3568  *			This enables fetching a single entry by IP
3569  *			address.  When limit is not one and frags= is
3570  *			provided, the fragment limit controls.
3571  *	mincount=	(decimal) Return entries with count >= mincount.
3572  *	laddr=		Return entries associated with the server's IP
3573  *			address given.  No port specification is needed,
3574  *			and any supplied is ignored.
3575  *	resall=		0x-prefixed hex restrict bits which must all be
3576  *			lit for an MRU entry to be included.
3577  *			Has precedence over any resany=.
3578  *	resany=		0x-prefixed hex restrict bits, at least one of
3579  *			which must be list for an MRU entry to be
3580  *			included.
3581  *	last.0=		0x-prefixed hex l_fp timestamp of newest entry
3582  *			which client previously received.
3583  *	addr.0=		text of newest entry's IP address and port,
3584  *			IPv6 addresses in bracketed form: [::]:123
3585  *	last.1=		timestamp of 2nd newest entry client has.
3586  *	addr.1=		address of 2nd newest entry.
3587  *	[...]
3588  *
3589  * ntpq provides as many last/addr pairs as will fit in a single request
3590  * packet, except for the first request in a MRU fetch operation.
3591  *
3592  * The response begins with a new nonce value to be used for any
3593  * followup request.  Following the nonce is the next newer entry than
3594  * referred to by last.0 and addr.0, if the "0" entry has not been
3595  * bumped to the front.  If it has, the first entry returned will be the
3596  * next entry newer than referred to by last.1 and addr.1, and so on.
3597  * If none of the referenced entries remain unchanged, the request fails
3598  * and ntpq backs up to the next earlier set of entries to resync.
3599  *
3600  * Except for the first response, the response begins with confirmation
3601  * of the entry that precedes the first additional entry provided:
3602  *
3603  *	last.older=	hex l_fp timestamp matching one of the input
3604  *			.last timestamps, which entry now precedes the
3605  *			response 0. entry in the MRU list.
3606  *	addr.older=	text of address corresponding to older.last.
3607  *
3608  * And in any case, a successful response contains sets of values
3609  * comprising entries, with the oldest numbered 0 and incrementing from
3610  * there:
3611  *
3612  *	addr.#		text of IPv4 or IPv6 address and port
3613  *	last.#		hex l_fp timestamp of last receipt
3614  *	first.#		hex l_fp timestamp of first receipt
3615  *	ct.#		count of packets received
3616  *	mv.#		mode and version
3617  *	rs.#		restriction mask (RES_* bits)
3618  *
3619  * Note the code currently assumes there are no valid three letter
3620  * tags sent with each row, and needs to be adjusted if that changes.
3621  *
3622  * The client should accept the values in any order, and ignore .#
3623  * values which it does not understand, to allow a smooth path to
3624  * future changes without requiring a new opcode.  Clients can rely
3625  * on all *.0 values preceding any *.1 values, that is all values for
3626  * a given index number are together in the response.
3627  *
3628  * The end of the response list is noted with one or two tag=value
3629  * pairs.  Unconditionally:
3630  *
3631  *	now=		0x-prefixed l_fp timestamp at the server marking
3632  *			the end of the operation.
3633  *
3634  * If any entries were returned, now= is followed by:
3635  *
3636  *	last.newest=	hex l_fp identical to last.# of the prior
3637  *			entry.
3638  */
3639 static void read_mru_list(
3640 	struct recvbuf *rbufp,
3641 	int restrict_mask
3642 	)
3643 {
3644 	const char		nonce_text[] =		"nonce";
3645 	const char		frags_text[] =		"frags";
3646 	const char		limit_text[] =		"limit";
3647 	const char		mincount_text[] =	"mincount";
3648 	const char		resall_text[] =		"resall";
3649 	const char		resany_text[] =		"resany";
3650 	const char		maxlstint_text[] =	"maxlstint";
3651 	const char		laddr_text[] =		"laddr";
3652 	const char		resaxx_fmt[] =		"0x%hx";
3653 	u_int			limit;
3654 	u_short			frags;
3655 	u_short			resall;
3656 	u_short			resany;
3657 	int			mincount;
3658 	u_int			maxlstint;
3659 	sockaddr_u		laddr;
3660 	struct interface *	lcladr;
3661 	u_int			count;
3662 	u_int			ui;
3663 	u_int			uf;
3664 	l_fp			last[16];
3665 	sockaddr_u		addr[COUNTOF(last)];
3666 	char			buf[128];
3667 	struct ctl_var *	in_parms;
3668 	const struct ctl_var *	v;
3669 	char *			val;
3670 	const char *		pch;
3671 	char *			pnonce;
3672 	int			nonce_valid;
3673 	size_t			i;
3674 	int			priors;
3675 	u_short			hash;
3676 	mon_entry *		mon;
3677 	mon_entry *		prior_mon;
3678 	l_fp			now;
3679 
3680 	if (RES_NOMRULIST & restrict_mask) {
3681 		ctl_error(CERR_PERMISSION);
3682 		NLOG(NLOG_SYSINFO)
3683 			msyslog(LOG_NOTICE,
3684 				"mrulist from %s rejected due to nomrulist restriction",
3685 				stoa(&rbufp->recv_srcadr));
3686 		sys_restricted++;
3687 		return;
3688 	}
3689 	/*
3690 	 * fill in_parms var list with all possible input parameters.
3691 	 */
3692 	in_parms = NULL;
3693 	set_var(&in_parms, nonce_text, sizeof(nonce_text), 0);
3694 	set_var(&in_parms, frags_text, sizeof(frags_text), 0);
3695 	set_var(&in_parms, limit_text, sizeof(limit_text), 0);
3696 	set_var(&in_parms, mincount_text, sizeof(mincount_text), 0);
3697 	set_var(&in_parms, resall_text, sizeof(resall_text), 0);
3698 	set_var(&in_parms, resany_text, sizeof(resany_text), 0);
3699 	set_var(&in_parms, maxlstint_text, sizeof(maxlstint_text), 0);
3700 	set_var(&in_parms, laddr_text, sizeof(laddr_text), 0);
3701 	for (i = 0; i < COUNTOF(last); i++) {
3702 		snprintf(buf, sizeof(buf), last_fmt, (int)i);
3703 		set_var(&in_parms, buf, strlen(buf) + 1, 0);
3704 		snprintf(buf, sizeof(buf), addr_fmt, (int)i);
3705 		set_var(&in_parms, buf, strlen(buf) + 1, 0);
3706 	}
3707 
3708 	/* decode input parms */
3709 	pnonce = NULL;
3710 	frags = 0;
3711 	limit = 0;
3712 	mincount = 0;
3713 	resall = 0;
3714 	resany = 0;
3715 	maxlstint = 0;
3716 	lcladr = NULL;
3717 	priors = 0;
3718 	ZERO(last);
3719 	ZERO(addr);
3720 
3721 	while (NULL != (v = ctl_getitem(in_parms, &val)) &&
3722 	       !(EOV & v->flags)) {
3723 	        int si;
3724 
3725 		if (!strcmp(nonce_text, v->text)) {
3726 			if (NULL != pnonce)
3727 				free(pnonce);
3728 			pnonce = estrdup(val);
3729 		} else if (!strcmp(frags_text, v->text)) {
3730 			sscanf(val, "%hu", &frags);
3731 		} else if (!strcmp(limit_text, v->text)) {
3732 			sscanf(val, "%u", &limit);
3733 		} else if (!strcmp(mincount_text, v->text)) {
3734 			if (1 != sscanf(val, "%d", &mincount) ||
3735 			    mincount < 0)
3736 				mincount = 0;
3737 		} else if (!strcmp(resall_text, v->text)) {
3738 			sscanf(val, resaxx_fmt, &resall);
3739 		} else if (!strcmp(resany_text, v->text)) {
3740 			sscanf(val, resaxx_fmt, &resany);
3741 		} else if (!strcmp(maxlstint_text, v->text)) {
3742 			sscanf(val, "%u", &maxlstint);
3743 		} else if (!strcmp(laddr_text, v->text)) {
3744 			if (decodenetnum(val, &laddr))
3745 				lcladr = getinterface(&laddr, 0);
3746 		} else if (1 == sscanf(v->text, last_fmt, &si) &&
3747 			   (size_t)si < COUNTOF(last)) {
3748 			if (2 == sscanf(val, "0x%08x.%08x", &ui, &uf)) {
3749 				last[si].l_ui = ui;
3750 				last[si].l_uf = uf;
3751 				if (!SOCK_UNSPEC(&addr[si]) &&
3752 				    si == priors)
3753 					priors++;
3754 			}
3755 		} else if (1 == sscanf(v->text, addr_fmt, &si) &&
3756 			   (size_t)si < COUNTOF(addr)) {
3757 			if (decodenetnum(val, &addr[si])
3758 			    && last[si].l_ui && last[si].l_uf &&
3759 			    si == priors)
3760 				priors++;
3761 		}
3762 	}
3763 	free_varlist(in_parms);
3764 	in_parms = NULL;
3765 
3766 	/* return no responses until the nonce is validated */
3767 	if (NULL == pnonce)
3768 		return;
3769 
3770 	nonce_valid = validate_nonce(pnonce, rbufp);
3771 	free(pnonce);
3772 	if (!nonce_valid)
3773 		return;
3774 
3775 	if ((0 == frags && !(0 < limit && limit <= MRU_ROW_LIMIT)) ||
3776 	    frags > MRU_FRAGS_LIMIT) {
3777 		ctl_error(CERR_BADVALUE);
3778 		return;
3779 	}
3780 
3781 	/*
3782 	 * If either frags or limit is not given, use the max.
3783 	 */
3784 	if (0 != frags && 0 == limit)
3785 		limit = UINT_MAX;
3786 	else if (0 != limit && 0 == frags)
3787 		frags = MRU_FRAGS_LIMIT;
3788 
3789 	/*
3790 	 * Find the starting point if one was provided.
3791 	 */
3792 	mon = NULL;
3793 	for (i = 0; i < (size_t)priors; i++) {
3794 		hash = MON_HASH(&addr[i]);
3795 		for (mon = mon_hash[hash];
3796 		     mon != NULL;
3797 		     mon = mon->hash_next)
3798 			if (ADDR_PORT_EQ(&mon->rmtadr, &addr[i]))
3799 				break;
3800 		if (mon != NULL) {
3801 			if (L_ISEQU(&mon->last, &last[i]))
3802 				break;
3803 			mon = NULL;
3804 		}
3805 	}
3806 
3807 	/* If a starting point was provided... */
3808 	if (priors) {
3809 		/* and none could be found unmodified... */
3810 		if (NULL == mon) {
3811 			/* tell ntpq to try again with older entries */
3812 			ctl_error(CERR_UNKNOWNVAR);
3813 			return;
3814 		}
3815 		/* confirm the prior entry used as starting point */
3816 		ctl_putts("last.older", &mon->last);
3817 		pch = sptoa(&mon->rmtadr);
3818 		ctl_putunqstr("addr.older", pch, strlen(pch));
3819 
3820 		/*
3821 		 * Move on to the first entry the client doesn't have,
3822 		 * except in the special case of a limit of one.  In
3823 		 * that case return the starting point entry.
3824 		 */
3825 		if (limit > 1)
3826 			mon = PREV_DLIST(mon_mru_list, mon, mru);
3827 	} else {	/* start with the oldest */
3828 		mon = TAIL_DLIST(mon_mru_list, mru);
3829 	}
3830 
3831 	/*
3832 	 * send up to limit= entries in up to frags= datagrams
3833 	 */
3834 	get_systime(&now);
3835 	generate_nonce(rbufp, buf, sizeof(buf));
3836 	ctl_putunqstr("nonce", buf, strlen(buf));
3837 	prior_mon = NULL;
3838 	for (count = 0;
3839 	     mon != NULL && res_frags < frags && count < limit;
3840 	     mon = PREV_DLIST(mon_mru_list, mon, mru)) {
3841 
3842 		if (mon->count < mincount)
3843 			continue;
3844 		if (resall && resall != (resall & mon->flags))
3845 			continue;
3846 		if (resany && !(resany & mon->flags))
3847 			continue;
3848 		if (maxlstint > 0 && now.l_ui - mon->last.l_ui >
3849 		    maxlstint)
3850 			continue;
3851 		if (lcladr != NULL && mon->lcladr != lcladr)
3852 			continue;
3853 
3854 		send_mru_entry(mon, count);
3855 		if (!count)
3856 			send_random_tag_value(0);
3857 		count++;
3858 		prior_mon = mon;
3859 	}
3860 
3861 	/*
3862 	 * If this batch completes the MRU list, say so explicitly with
3863 	 * a now= l_fp timestamp.
3864 	 */
3865 	if (NULL == mon) {
3866 		if (count > 1)
3867 			send_random_tag_value(count - 1);
3868 		ctl_putts("now", &now);
3869 		/* if any entries were returned confirm the last */
3870 		if (prior_mon != NULL)
3871 			ctl_putts("last.newest", &prior_mon->last);
3872 	}
3873 	ctl_flushpkt(0);
3874 }
3875 
3876 
3877 /*
3878  * Send a ifstats entry in response to a "ntpq -c ifstats" request.
3879  *
3880  * To keep clients honest about not depending on the order of values,
3881  * and thereby avoid being locked into ugly workarounds to maintain
3882  * backward compatibility later as new fields are added to the response,
3883  * the order is random.
3884  */
3885 static void
3886 send_ifstats_entry(
3887 	endpt *	la,
3888 	u_int	ifnum
3889 	)
3890 {
3891 	const char addr_fmtu[] =	"addr.%u";
3892 	const char bcast_fmt[] =	"bcast.%u";
3893 	const char en_fmt[] =		"en.%u";	/* enabled */
3894 	const char name_fmt[] =		"name.%u";
3895 	const char flags_fmt[] =	"flags.%u";
3896 	const char tl_fmt[] =		"tl.%u";	/* ttl */
3897 	const char mc_fmt[] =		"mc.%u";	/* mcast count */
3898 	const char rx_fmt[] =		"rx.%u";
3899 	const char tx_fmt[] =		"tx.%u";
3900 	const char txerr_fmt[] =	"txerr.%u";
3901 	const char pc_fmt[] =		"pc.%u";	/* peer count */
3902 	const char up_fmt[] =		"up.%u";	/* uptime */
3903 	char	tag[32];
3904 	u_char	sent[IFSTATS_FIELDS]; /* 12 tag=value pairs */
3905 	int	noisebits;
3906 	u_int32 noise;
3907 	u_int	which;
3908 	u_int	remaining;
3909 	const char *pch;
3910 
3911 	remaining = COUNTOF(sent);
3912 	ZERO(sent);
3913 	noise = 0;
3914 	noisebits = 0;
3915 	while (remaining > 0) {
3916 		if (noisebits < 4) {
3917 			noise = rand() ^ (rand() << 16);
3918 			noisebits = 31;
3919 		}
3920 		which = (noise & 0xf) % COUNTOF(sent);
3921 		noise >>= 4;
3922 		noisebits -= 4;
3923 
3924 		while (sent[which])
3925 			which = (which + 1) % COUNTOF(sent);
3926 
3927 		switch (which) {
3928 
3929 		case 0:
3930 			snprintf(tag, sizeof(tag), addr_fmtu, ifnum);
3931 			pch = sptoa(&la->sin);
3932 			ctl_putunqstr(tag, pch, strlen(pch));
3933 			break;
3934 
3935 		case 1:
3936 			snprintf(tag, sizeof(tag), bcast_fmt, ifnum);
3937 			if (INT_BCASTOPEN & la->flags)
3938 				pch = sptoa(&la->bcast);
3939 			else
3940 				pch = "";
3941 			ctl_putunqstr(tag, pch, strlen(pch));
3942 			break;
3943 
3944 		case 2:
3945 			snprintf(tag, sizeof(tag), en_fmt, ifnum);
3946 			ctl_putint(tag, !la->ignore_packets);
3947 			break;
3948 
3949 		case 3:
3950 			snprintf(tag, sizeof(tag), name_fmt, ifnum);
3951 			ctl_putstr(tag, la->name, strlen(la->name));
3952 			break;
3953 
3954 		case 4:
3955 			snprintf(tag, sizeof(tag), flags_fmt, ifnum);
3956 			ctl_puthex(tag, (u_int)la->flags);
3957 			break;
3958 
3959 		case 5:
3960 			snprintf(tag, sizeof(tag), tl_fmt, ifnum);
3961 			ctl_putint(tag, la->last_ttl);
3962 			break;
3963 
3964 		case 6:
3965 			snprintf(tag, sizeof(tag), mc_fmt, ifnum);
3966 			ctl_putint(tag, la->num_mcast);
3967 			break;
3968 
3969 		case 7:
3970 			snprintf(tag, sizeof(tag), rx_fmt, ifnum);
3971 			ctl_putint(tag, la->received);
3972 			break;
3973 
3974 		case 8:
3975 			snprintf(tag, sizeof(tag), tx_fmt, ifnum);
3976 			ctl_putint(tag, la->sent);
3977 			break;
3978 
3979 		case 9:
3980 			snprintf(tag, sizeof(tag), txerr_fmt, ifnum);
3981 			ctl_putint(tag, la->notsent);
3982 			break;
3983 
3984 		case 10:
3985 			snprintf(tag, sizeof(tag), pc_fmt, ifnum);
3986 			ctl_putuint(tag, la->peercnt);
3987 			break;
3988 
3989 		case 11:
3990 			snprintf(tag, sizeof(tag), up_fmt, ifnum);
3991 			ctl_putuint(tag, current_time - la->starttime);
3992 			break;
3993 		}
3994 		sent[which] = TRUE;
3995 		remaining--;
3996 	}
3997 	send_random_tag_value((int)ifnum);
3998 }
3999 
4000 
4001 /*
4002  * read_ifstats - send statistics for each local address, exposed by
4003  *		  ntpq -c ifstats
4004  */
4005 static void
4006 read_ifstats(
4007 	struct recvbuf *	rbufp
4008 	)
4009 {
4010 	u_int	ifidx;
4011 	endpt *	la;
4012 
4013 	/*
4014 	 * loop over [0..sys_ifnum] searching ep_list for each
4015 	 * ifnum in turn.
4016 	 */
4017 	for (ifidx = 0; ifidx < sys_ifnum; ifidx++) {
4018 		for (la = ep_list; la != NULL; la = la->elink)
4019 			if (ifidx == la->ifnum)
4020 				break;
4021 		if (NULL == la)
4022 			continue;
4023 		/* return stats for one local address */
4024 		send_ifstats_entry(la, ifidx);
4025 	}
4026 	ctl_flushpkt(0);
4027 }
4028 
4029 static void
4030 sockaddrs_from_restrict_u(
4031 	sockaddr_u *	psaA,
4032 	sockaddr_u *	psaM,
4033 	restrict_u *	pres,
4034 	int		ipv6
4035 	)
4036 {
4037 	ZERO(*psaA);
4038 	ZERO(*psaM);
4039 	if (!ipv6) {
4040 		psaA->sa.sa_family = AF_INET;
4041 		psaA->sa4.sin_addr.s_addr = htonl(pres->u.v4.addr);
4042 		psaM->sa.sa_family = AF_INET;
4043 		psaM->sa4.sin_addr.s_addr = htonl(pres->u.v4.mask);
4044 	} else {
4045 		psaA->sa.sa_family = AF_INET6;
4046 		memcpy(&psaA->sa6.sin6_addr, &pres->u.v6.addr,
4047 		       sizeof(psaA->sa6.sin6_addr));
4048 		psaM->sa.sa_family = AF_INET6;
4049 		memcpy(&psaM->sa6.sin6_addr, &pres->u.v6.mask,
4050 		       sizeof(psaA->sa6.sin6_addr));
4051 	}
4052 }
4053 
4054 
4055 /*
4056  * Send a restrict entry in response to a "ntpq -c reslist" request.
4057  *
4058  * To keep clients honest about not depending on the order of values,
4059  * and thereby avoid being locked into ugly workarounds to maintain
4060  * backward compatibility later as new fields are added to the response,
4061  * the order is random.
4062  */
4063 static void
4064 send_restrict_entry(
4065 	restrict_u *	pres,
4066 	int		ipv6,
4067 	u_int		idx
4068 	)
4069 {
4070 	const char addr_fmtu[] =	"addr.%u";
4071 	const char mask_fmtu[] =	"mask.%u";
4072 	const char hits_fmt[] =		"hits.%u";
4073 	const char flags_fmt[] =	"flags.%u";
4074 	char		tag[32];
4075 	u_char		sent[RESLIST_FIELDS]; /* 4 tag=value pairs */
4076 	int		noisebits;
4077 	u_int32		noise;
4078 	u_int		which;
4079 	u_int		remaining;
4080 	sockaddr_u	addr;
4081 	sockaddr_u	mask;
4082 	const char *	pch;
4083 	char *		buf;
4084 	const char *	match_str;
4085 	const char *	access_str;
4086 
4087 	sockaddrs_from_restrict_u(&addr, &mask, pres, ipv6);
4088 	remaining = COUNTOF(sent);
4089 	ZERO(sent);
4090 	noise = 0;
4091 	noisebits = 0;
4092 	while (remaining > 0) {
4093 		if (noisebits < 2) {
4094 			noise = rand() ^ (rand() << 16);
4095 			noisebits = 31;
4096 		}
4097 		which = (noise & 0x3) % COUNTOF(sent);
4098 		noise >>= 2;
4099 		noisebits -= 2;
4100 
4101 		while (sent[which])
4102 			which = (which + 1) % COUNTOF(sent);
4103 
4104 		switch (which) {
4105 
4106 		case 0:
4107 			snprintf(tag, sizeof(tag), addr_fmtu, idx);
4108 			pch = stoa(&addr);
4109 			ctl_putunqstr(tag, pch, strlen(pch));
4110 			break;
4111 
4112 		case 1:
4113 			snprintf(tag, sizeof(tag), mask_fmtu, idx);
4114 			pch = stoa(&mask);
4115 			ctl_putunqstr(tag, pch, strlen(pch));
4116 			break;
4117 
4118 		case 2:
4119 			snprintf(tag, sizeof(tag), hits_fmt, idx);
4120 			ctl_putuint(tag, pres->count);
4121 			break;
4122 
4123 		case 3:
4124 			snprintf(tag, sizeof(tag), flags_fmt, idx);
4125 			match_str = res_match_flags(pres->mflags);
4126 			access_str = res_access_flags(pres->flags);
4127 			if ('\0' == match_str[0]) {
4128 				pch = access_str;
4129 			} else {
4130 				LIB_GETBUF(buf);
4131 				snprintf(buf, LIB_BUFLENGTH, "%s %s",
4132 					 match_str, access_str);
4133 				pch = buf;
4134 			}
4135 			ctl_putunqstr(tag, pch, strlen(pch));
4136 			break;
4137 		}
4138 		sent[which] = TRUE;
4139 		remaining--;
4140 	}
4141 	send_random_tag_value((int)idx);
4142 }
4143 
4144 
4145 static void
4146 send_restrict_list(
4147 	restrict_u *	pres,
4148 	int		ipv6,
4149 	u_int *		pidx
4150 	)
4151 {
4152 	for ( ; pres != NULL; pres = pres->link) {
4153 		send_restrict_entry(pres, ipv6, *pidx);
4154 		(*pidx)++;
4155 	}
4156 }
4157 
4158 
4159 /*
4160  * read_addr_restrictions - returns IPv4 and IPv6 access control lists
4161  */
4162 static void
4163 read_addr_restrictions(
4164 	struct recvbuf *	rbufp
4165 )
4166 {
4167 	u_int idx;
4168 
4169 	idx = 0;
4170 	send_restrict_list(restrictlist4, FALSE, &idx);
4171 	send_restrict_list(restrictlist6, TRUE, &idx);
4172 	ctl_flushpkt(0);
4173 }
4174 
4175 
4176 /*
4177  * read_ordlist - CTL_OP_READ_ORDLIST_A for ntpq -c ifstats & reslist
4178  */
4179 static void
4180 read_ordlist(
4181 	struct recvbuf *	rbufp,
4182 	int			restrict_mask
4183 	)
4184 {
4185 	const char ifstats_s[] = "ifstats";
4186 	const size_t ifstats_chars = COUNTOF(ifstats_s) - 1;
4187 	const char addr_rst_s[] = "addr_restrictions";
4188 	const size_t a_r_chars = COUNTOF(addr_rst_s) - 1;
4189 	struct ntp_control *	cpkt;
4190 	u_short			qdata_octets;
4191 
4192 	/*
4193 	 * CTL_OP_READ_ORDLIST_A was first named CTL_OP_READ_IFSTATS and
4194 	 * used only for ntpq -c ifstats.  With the addition of reslist
4195 	 * the same opcode was generalized to retrieve ordered lists
4196 	 * which require authentication.  The request data is empty or
4197 	 * contains "ifstats" (not null terminated) to retrieve local
4198 	 * addresses and associated stats.  It is "addr_restrictions"
4199 	 * to retrieve the IPv4 then IPv6 remote address restrictions,
4200 	 * which are access control lists.  Other request data return
4201 	 * CERR_UNKNOWNVAR.
4202 	 */
4203 	cpkt = (struct ntp_control *)&rbufp->recv_pkt;
4204 	qdata_octets = ntohs(cpkt->count);
4205 	if (0 == qdata_octets || (ifstats_chars == qdata_octets &&
4206 	    !memcmp(ifstats_s, cpkt->u.data, ifstats_chars))) {
4207 		read_ifstats(rbufp);
4208 		return;
4209 	}
4210 	if (a_r_chars == qdata_octets &&
4211 	    !memcmp(addr_rst_s, cpkt->u.data, a_r_chars)) {
4212 		read_addr_restrictions(rbufp);
4213 		return;
4214 	}
4215 	ctl_error(CERR_UNKNOWNVAR);
4216 }
4217 
4218 
4219 /*
4220  * req_nonce - CTL_OP_REQ_NONCE for ntpq -c mrulist prerequisite.
4221  */
4222 static void req_nonce(
4223 	struct recvbuf *	rbufp,
4224 	int			restrict_mask
4225 	)
4226 {
4227 	char	buf[64];
4228 
4229 	generate_nonce(rbufp, buf, sizeof(buf));
4230 	ctl_putunqstr("nonce", buf, strlen(buf));
4231 	ctl_flushpkt(0);
4232 }
4233 
4234 
4235 /*
4236  * read_clockstatus - return clock radio status
4237  */
4238 /*ARGSUSED*/
4239 static void
4240 read_clockstatus(
4241 	struct recvbuf *rbufp,
4242 	int restrict_mask
4243 	)
4244 {
4245 #ifndef REFCLOCK
4246 	/*
4247 	 * If no refclock support, no data to return
4248 	 */
4249 	ctl_error(CERR_BADASSOC);
4250 #else
4251 	const struct ctl_var *	v;
4252 	int			i;
4253 	struct peer *		peer;
4254 	char *			valuep;
4255 	u_char *		wants;
4256 	size_t			wants_alloc;
4257 	int			gotvar;
4258 	const u_char *		cc;
4259 	struct ctl_var *	kv;
4260 	struct refclockstat	cs;
4261 
4262 	if (res_associd != 0) {
4263 		peer = findpeerbyassoc(res_associd);
4264 	} else {
4265 		/*
4266 		 * Find a clock for this jerk.	If the system peer
4267 		 * is a clock use it, else search peer_list for one.
4268 		 */
4269 		if (sys_peer != NULL && (FLAG_REFCLOCK &
4270 		    sys_peer->flags))
4271 			peer = sys_peer;
4272 		else
4273 			for (peer = peer_list;
4274 			     peer != NULL;
4275 			     peer = peer->p_link)
4276 				if (FLAG_REFCLOCK & peer->flags)
4277 					break;
4278 	}
4279 	if (NULL == peer || !(FLAG_REFCLOCK & peer->flags)) {
4280 		ctl_error(CERR_BADASSOC);
4281 		return;
4282 	}
4283 	/*
4284 	 * If we got here we have a peer which is a clock. Get his
4285 	 * status.
4286 	 */
4287 	cs.kv_list = NULL;
4288 	refclock_control(&peer->srcadr, NULL, &cs);
4289 	kv = cs.kv_list;
4290 	/*
4291 	 * Look for variables in the packet.
4292 	 */
4293 	rpkt.status = htons(ctlclkstatus(&cs));
4294 	wants_alloc = CC_MAXCODE + 1 + count_var(kv);
4295 	wants = emalloc_zero(wants_alloc);
4296 	gotvar = FALSE;
4297 	while (NULL != (v = ctl_getitem(clock_var, &valuep))) {
4298 		if (!(EOV & v->flags)) {
4299 			wants[v->code] = TRUE;
4300 			gotvar = TRUE;
4301 		} else {
4302 			v = ctl_getitem(kv, &valuep);
4303 			NTP_INSIST(NULL != v);
4304 			if (EOV & v->flags) {
4305 				ctl_error(CERR_UNKNOWNVAR);
4306 				free(wants);
4307 				free_varlist(cs.kv_list);
4308 				return;
4309 			}
4310 			wants[CC_MAXCODE + 1 + v->code] = TRUE;
4311 			gotvar = TRUE;
4312 		}
4313 	}
4314 
4315 	if (gotvar) {
4316 		for (i = 1; i <= CC_MAXCODE; i++)
4317 			if (wants[i])
4318 				ctl_putclock(i, &cs, TRUE);
4319 		if (kv != NULL)
4320 			for (i = 0; !(EOV & kv[i].flags); i++)
4321 				if (wants[i + CC_MAXCODE + 1])
4322 					ctl_putdata(kv[i].text,
4323 						    strlen(kv[i].text),
4324 						    FALSE);
4325 	} else {
4326 		for (cc = def_clock_var; *cc != 0; cc++)
4327 			ctl_putclock((int)*cc, &cs, FALSE);
4328 		for ( ; kv != NULL && !(EOV & kv->flags); kv++)
4329 			if (DEF & kv->flags)
4330 				ctl_putdata(kv->text, strlen(kv->text),
4331 					    FALSE);
4332 	}
4333 
4334 	free(wants);
4335 	free_varlist(cs.kv_list);
4336 
4337 	ctl_flushpkt(0);
4338 #endif
4339 }
4340 
4341 
4342 /*
4343  * write_clockstatus - we don't do this
4344  */
4345 /*ARGSUSED*/
4346 static void
4347 write_clockstatus(
4348 	struct recvbuf *rbufp,
4349 	int restrict_mask
4350 	)
4351 {
4352 	ctl_error(CERR_PERMISSION);
4353 }
4354 
4355 /*
4356  * Trap support from here on down. We send async trap messages when the
4357  * upper levels report trouble. Traps can by set either by control
4358  * messages or by configuration.
4359  */
4360 /*
4361  * set_trap - set a trap in response to a control message
4362  */
4363 static void
4364 set_trap(
4365 	struct recvbuf *rbufp,
4366 	int restrict_mask
4367 	)
4368 {
4369 	int traptype;
4370 
4371 	/*
4372 	 * See if this guy is allowed
4373 	 */
4374 	if (restrict_mask & RES_NOTRAP) {
4375 		ctl_error(CERR_PERMISSION);
4376 		return;
4377 	}
4378 
4379 	/*
4380 	 * Determine his allowed trap type.
4381 	 */
4382 	traptype = TRAP_TYPE_PRIO;
4383 	if (restrict_mask & RES_LPTRAP)
4384 		traptype = TRAP_TYPE_NONPRIO;
4385 
4386 	/*
4387 	 * Call ctlsettrap() to do the work.  Return
4388 	 * an error if it can't assign the trap.
4389 	 */
4390 	if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
4391 			(int)res_version))
4392 		ctl_error(CERR_NORESOURCE);
4393 	ctl_flushpkt(0);
4394 }
4395 
4396 
4397 /*
4398  * unset_trap - unset a trap in response to a control message
4399  */
4400 static void
4401 unset_trap(
4402 	struct recvbuf *rbufp,
4403 	int restrict_mask
4404 	)
4405 {
4406 	int traptype;
4407 
4408 	/*
4409 	 * We don't prevent anyone from removing his own trap unless the
4410 	 * trap is configured. Note we also must be aware of the
4411 	 * possibility that restriction flags were changed since this
4412 	 * guy last set his trap. Set the trap type based on this.
4413 	 */
4414 	traptype = TRAP_TYPE_PRIO;
4415 	if (restrict_mask & RES_LPTRAP)
4416 		traptype = TRAP_TYPE_NONPRIO;
4417 
4418 	/*
4419 	 * Call ctlclrtrap() to clear this out.
4420 	 */
4421 	if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
4422 		ctl_error(CERR_BADASSOC);
4423 	ctl_flushpkt(0);
4424 }
4425 
4426 
4427 /*
4428  * ctlsettrap - called to set a trap
4429  */
4430 int
4431 ctlsettrap(
4432 	sockaddr_u *raddr,
4433 	struct interface *linter,
4434 	int traptype,
4435 	int version
4436 	)
4437 {
4438 	size_t n;
4439 	struct ctl_trap *tp;
4440 	struct ctl_trap *tptouse;
4441 
4442 	/*
4443 	 * See if we can find this trap.  If so, we only need update
4444 	 * the flags and the time.
4445 	 */
4446 	if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
4447 		switch (traptype) {
4448 
4449 		case TRAP_TYPE_CONFIG:
4450 			tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
4451 			break;
4452 
4453 		case TRAP_TYPE_PRIO:
4454 			if (tp->tr_flags & TRAP_CONFIGURED)
4455 				return (1); /* don't change anything */
4456 			tp->tr_flags = TRAP_INUSE;
4457 			break;
4458 
4459 		case TRAP_TYPE_NONPRIO:
4460 			if (tp->tr_flags & TRAP_CONFIGURED)
4461 				return (1); /* don't change anything */
4462 			tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
4463 			break;
4464 		}
4465 		tp->tr_settime = current_time;
4466 		tp->tr_resets++;
4467 		return (1);
4468 	}
4469 
4470 	/*
4471 	 * First we heard of this guy.	Try to find a trap structure
4472 	 * for him to use, clearing out lesser priority guys if we
4473 	 * have to. Clear out anyone who's expired while we're at it.
4474 	 */
4475 	tptouse = NULL;
4476 	for (n = 0; n < COUNTOF(ctl_traps); n++) {
4477 		tp = &ctl_traps[n];
4478 		if ((TRAP_INUSE & tp->tr_flags) &&
4479 		    !(TRAP_CONFIGURED & tp->tr_flags) &&
4480 		    ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
4481 			tp->tr_flags = 0;
4482 			num_ctl_traps--;
4483 		}
4484 		if (!(TRAP_INUSE & tp->tr_flags)) {
4485 			tptouse = tp;
4486 		} else if (!(TRAP_CONFIGURED & tp->tr_flags)) {
4487 			switch (traptype) {
4488 
4489 			case TRAP_TYPE_CONFIG:
4490 				if (tptouse == NULL) {
4491 					tptouse = tp;
4492 					break;
4493 				}
4494 				if ((TRAP_NONPRIO & tptouse->tr_flags) &&
4495 				    !(TRAP_NONPRIO & tp->tr_flags))
4496 					break;
4497 
4498 				if (!(TRAP_NONPRIO & tptouse->tr_flags)
4499 				    && (TRAP_NONPRIO & tp->tr_flags)) {
4500 					tptouse = tp;
4501 					break;
4502 				}
4503 				if (tptouse->tr_origtime <
4504 				    tp->tr_origtime)
4505 					tptouse = tp;
4506 				break;
4507 
4508 			case TRAP_TYPE_PRIO:
4509 				if ( TRAP_NONPRIO & tp->tr_flags) {
4510 					if (tptouse == NULL ||
4511 					    ((TRAP_INUSE &
4512 					      tptouse->tr_flags) &&
4513 					     tptouse->tr_origtime <
4514 					     tp->tr_origtime))
4515 						tptouse = tp;
4516 				}
4517 				break;
4518 
4519 			case TRAP_TYPE_NONPRIO:
4520 				break;
4521 			}
4522 		}
4523 	}
4524 
4525 	/*
4526 	 * If we don't have room for him return an error.
4527 	 */
4528 	if (tptouse == NULL)
4529 		return (0);
4530 
4531 	/*
4532 	 * Set up this structure for him.
4533 	 */
4534 	tptouse->tr_settime = tptouse->tr_origtime = current_time;
4535 	tptouse->tr_count = tptouse->tr_resets = 0;
4536 	tptouse->tr_sequence = 1;
4537 	tptouse->tr_addr = *raddr;
4538 	tptouse->tr_localaddr = linter;
4539 	tptouse->tr_version = (u_char) version;
4540 	tptouse->tr_flags = TRAP_INUSE;
4541 	if (traptype == TRAP_TYPE_CONFIG)
4542 		tptouse->tr_flags |= TRAP_CONFIGURED;
4543 	else if (traptype == TRAP_TYPE_NONPRIO)
4544 		tptouse->tr_flags |= TRAP_NONPRIO;
4545 	num_ctl_traps++;
4546 	return (1);
4547 }
4548 
4549 
4550 /*
4551  * ctlclrtrap - called to clear a trap
4552  */
4553 int
4554 ctlclrtrap(
4555 	sockaddr_u *raddr,
4556 	struct interface *linter,
4557 	int traptype
4558 	)
4559 {
4560 	register struct ctl_trap *tp;
4561 
4562 	if ((tp = ctlfindtrap(raddr, linter)) == NULL)
4563 		return (0);
4564 
4565 	if (tp->tr_flags & TRAP_CONFIGURED
4566 	    && traptype != TRAP_TYPE_CONFIG)
4567 		return (0);
4568 
4569 	tp->tr_flags = 0;
4570 	num_ctl_traps--;
4571 	return (1);
4572 }
4573 
4574 
4575 /*
4576  * ctlfindtrap - find a trap given the remote and local addresses
4577  */
4578 static struct ctl_trap *
4579 ctlfindtrap(
4580 	sockaddr_u *raddr,
4581 	struct interface *linter
4582 	)
4583 {
4584 	size_t	n;
4585 
4586 	for (n = 0; n < COUNTOF(ctl_traps); n++)
4587 		if ((ctl_traps[n].tr_flags & TRAP_INUSE)
4588 		    && ADDR_PORT_EQ(raddr, &ctl_traps[n].tr_addr)
4589 	 	    && (linter == ctl_traps[n].tr_localaddr))
4590 			return &ctl_traps[n];
4591 
4592 	return NULL;
4593 }
4594 
4595 
4596 /*
4597  * report_event - report an event to the trappers
4598  */
4599 void
4600 report_event(
4601 	int	err,		/* error code */
4602 	struct peer *peer,	/* peer structure pointer */
4603 	const char *str		/* protostats string */
4604 	)
4605 {
4606 	char	statstr[NTP_MAXSTRLEN];
4607 	int	i;
4608 	size_t	len;
4609 
4610 	/*
4611 	 * Report the error to the protostats file, system log and
4612 	 * trappers.
4613 	 */
4614 	if (peer == NULL) {
4615 
4616 		/*
4617 		 * Discard a system report if the number of reports of
4618 		 * the same type exceeds the maximum.
4619 		 */
4620 		if (ctl_sys_last_event != (u_char)err)
4621 			ctl_sys_num_events= 0;
4622 		if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS)
4623 			return;
4624 
4625 		ctl_sys_last_event = (u_char)err;
4626 		ctl_sys_num_events++;
4627 		snprintf(statstr, sizeof(statstr),
4628 		    "0.0.0.0 %04x %02x %s",
4629 		    ctlsysstatus(), err, eventstr(err));
4630 		if (str != NULL) {
4631 			len = strlen(statstr);
4632 			snprintf(statstr + len, sizeof(statstr) - len,
4633 			    " %s", str);
4634 		}
4635 		NLOG(NLOG_SYSEVENT)
4636 			msyslog(LOG_INFO, "%s", statstr);
4637 	} else {
4638 
4639 		/*
4640 		 * Discard a peer report if the number of reports of
4641 		 * the same type exceeds the maximum for that peer.
4642 		 */
4643 		const char *	src;
4644 		u_char		errlast;
4645 
4646 		errlast = (u_char)err & ~PEER_EVENT;
4647 		if (peer->last_event == errlast)
4648 			peer->num_events = 0;
4649 		if (peer->num_events >= CTL_PEER_MAXEVENTS)
4650 			return;
4651 
4652 		peer->last_event = errlast;
4653 		peer->num_events++;
4654 		if (ISREFCLOCKADR(&peer->srcadr))
4655 			src = refnumtoa(&peer->srcadr);
4656 		else
4657 			src = stoa(&peer->srcadr);
4658 
4659 		snprintf(statstr, sizeof(statstr),
4660 		    "%s %04x %02x %s", src,
4661 		    ctlpeerstatus(peer), err, eventstr(err));
4662 		if (str != NULL) {
4663 			len = strlen(statstr);
4664 			snprintf(statstr + len, sizeof(statstr) - len,
4665 			    " %s", str);
4666 		}
4667 		NLOG(NLOG_PEEREVENT)
4668 			msyslog(LOG_INFO, "%s", statstr);
4669 	}
4670 	record_proto_stats(statstr);
4671 #if DEBUG
4672 	if (debug)
4673 		printf("event at %lu %s\n", current_time, statstr);
4674 #endif
4675 
4676 	/*
4677 	 * If no trappers, return.
4678 	 */
4679 	if (num_ctl_traps <= 0)
4680 		return;
4681 
4682 	/*
4683 	 * Set up the outgoing packet variables
4684 	 */
4685 	res_opcode = CTL_OP_ASYNCMSG;
4686 	res_offset = 0;
4687 	res_async = TRUE;
4688 	res_authenticate = FALSE;
4689 	datapt = rpkt.u.data;
4690 	dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
4691 	if (!(err & PEER_EVENT)) {
4692 		rpkt.associd = 0;
4693 		rpkt.status = htons(ctlsysstatus());
4694 
4695 		/* Include the core system variables and the list. */
4696 		for (i = 1; i <= CS_VARLIST; i++)
4697 			ctl_putsys(i);
4698 	} else {
4699 		NTP_INSIST(peer != NULL);
4700 		rpkt.associd = htons(peer->associd);
4701 		rpkt.status = htons(ctlpeerstatus(peer));
4702 
4703 		/* Dump it all. Later, maybe less. */
4704 		for (i = 1; i <= CP_MAX_NOAUTOKEY; i++)
4705 			ctl_putpeer(i, peer);
4706 #ifdef REFCLOCK
4707 		/*
4708 		 * for clock exception events: add clock variables to
4709 		 * reflect info on exception
4710 		 */
4711 		if (err == PEVNT_CLOCK) {
4712 			struct refclockstat cs;
4713 			struct ctl_var *kv;
4714 
4715 			cs.kv_list = NULL;
4716 			refclock_control(&peer->srcadr, NULL, &cs);
4717 
4718 			ctl_puthex("refclockstatus",
4719 				   ctlclkstatus(&cs));
4720 
4721 			for (i = 1; i <= CC_MAXCODE; i++)
4722 				ctl_putclock(i, &cs, FALSE);
4723 			for (kv = cs.kv_list;
4724 			     kv != NULL && !(EOV & kv->flags);
4725 			     kv++)
4726 				if (DEF & kv->flags)
4727 					ctl_putdata(kv->text,
4728 						    strlen(kv->text),
4729 						    FALSE);
4730 			free_varlist(cs.kv_list);
4731 		}
4732 #endif /* REFCLOCK */
4733 	}
4734 
4735 	/*
4736 	 * We're done, return.
4737 	 */
4738 	ctl_flushpkt(0);
4739 }
4740 
4741 
4742 /*
4743  * mprintf_event - printf-style varargs variant of report_event()
4744  */
4745 int
4746 mprintf_event(
4747 	int		evcode,		/* event code */
4748 	struct peer *	p,		/* may be NULL */
4749 	const char *	fmt,		/* msnprintf format */
4750 	...
4751 	)
4752 {
4753 	va_list	ap;
4754 	int	rc;
4755 	char	msg[512];
4756 
4757 	va_start(ap, fmt);
4758 	rc = mvsnprintf(msg, sizeof(msg), fmt, ap);
4759 	va_end(ap);
4760 	report_event(evcode, p, msg);
4761 
4762 	return rc;
4763 }
4764 
4765 
4766 /*
4767  * ctl_clr_stats - clear stat counters
4768  */
4769 void
4770 ctl_clr_stats(void)
4771 {
4772 	ctltimereset = current_time;
4773 	numctlreq = 0;
4774 	numctlbadpkts = 0;
4775 	numctlresponses = 0;
4776 	numctlfrags = 0;
4777 	numctlerrors = 0;
4778 	numctlfrags = 0;
4779 	numctltooshort = 0;
4780 	numctlinputresp = 0;
4781 	numctlinputfrag = 0;
4782 	numctlinputerr = 0;
4783 	numctlbadoffset = 0;
4784 	numctlbadversion = 0;
4785 	numctldatatooshort = 0;
4786 	numctlbadop = 0;
4787 	numasyncmsgs = 0;
4788 }
4789 
4790 static u_short
4791 count_var(
4792 	const struct ctl_var *k
4793 	)
4794 {
4795 	u_int c;
4796 
4797 	if (NULL == k)
4798 		return 0;
4799 
4800 	c = 0;
4801 	while (!(EOV & (k++)->flags))
4802 		c++;
4803 
4804 	NTP_ENSURE(c <= USHRT_MAX);
4805 	return (u_short)c;
4806 }
4807 
4808 
4809 char *
4810 add_var(
4811 	struct ctl_var **kv,
4812 	u_long size,
4813 	u_short def
4814 	)
4815 {
4816 	u_short		c;
4817 	struct ctl_var *k;
4818 	char *		buf;
4819 
4820 	c = count_var(*kv);
4821 	*kv  = erealloc(*kv, (c + 2) * sizeof(**kv));
4822 	k = *kv;
4823 	buf = emalloc(size);
4824 	k[c].code  = c;
4825 	k[c].text  = buf;
4826 	k[c].flags = def;
4827 	k[c + 1].code  = 0;
4828 	k[c + 1].text  = NULL;
4829 	k[c + 1].flags = EOV;
4830 
4831 	return buf;
4832 }
4833 
4834 
4835 void
4836 set_var(
4837 	struct ctl_var **kv,
4838 	const char *data,
4839 	u_long size,
4840 	u_short def
4841 	)
4842 {
4843 	struct ctl_var *k;
4844 	const char *s;
4845 	const char *t;
4846 	char *td;
4847 
4848 	if (NULL == data || !size)
4849 		return;
4850 
4851 	k = *kv;
4852 	if (k != NULL) {
4853 		while (!(EOV & k->flags)) {
4854 			if (NULL == k->text)	{
4855 				td = emalloc(size);
4856 				memcpy(td, data, size);
4857 				k->text = td;
4858 				k->flags = def;
4859 				return;
4860 			} else {
4861 				s = data;
4862 				t = k->text;
4863 				while (*t != '=' && *s == *t) {
4864 					s++;
4865 					t++;
4866 				}
4867 				if (*s == *t && ((*t == '=') || !*t)) {
4868 					td = erealloc((void *)(intptr_t)k->text, size);
4869 					memcpy(td, data, size);
4870 					k->text = td;
4871 					k->flags = def;
4872 					return;
4873 				}
4874 			}
4875 			k++;
4876 		}
4877 	}
4878 	td = add_var(kv, size, def);
4879 	memcpy(td, data, size);
4880 }
4881 
4882 
4883 void
4884 set_sys_var(
4885 	const char *data,
4886 	u_long size,
4887 	u_short def
4888 	)
4889 {
4890 	set_var(&ext_sys_var, data, size, def);
4891 }
4892 
4893 
4894 /*
4895  * get_ext_sys_var() retrieves the value of a user-defined variable or
4896  * NULL if the variable has not been setvar'd.
4897  */
4898 const char *
4899 get_ext_sys_var(const char *tag)
4900 {
4901 	struct ctl_var *	v;
4902 	size_t			c;
4903 	const char *		val;
4904 
4905 	val = NULL;
4906 	c = strlen(tag);
4907 	for (v = ext_sys_var; !(EOV & v->flags); v++) {
4908 		if (NULL != v->text && !memcmp(tag, v->text, c)) {
4909 			if ('=' == v->text[c]) {
4910 				val = v->text + c + 1;
4911 				break;
4912 			} else if ('\0' == v->text[c]) {
4913 				val = "";
4914 				break;
4915 			}
4916 		}
4917 	}
4918 
4919 	return val;
4920 }
4921 
4922 
4923 void
4924 free_varlist(
4925 	struct ctl_var *kv
4926 	)
4927 {
4928 	struct ctl_var *k;
4929 	if (kv) {
4930 		for (k = kv; !(k->flags & EOV); k++)
4931 			free((void *)(intptr_t)k->text);
4932 		free((void *)kv);
4933 	}
4934 }
4935