xref: /netbsd-src/external/bsd/ntp/dist/ntpd/ntp_control.c (revision b757af438b42b93f8c6571f026d8b8ef3eaf5fc9)
1 /*	$NetBSD: ntp_control.c,v 1.6 2012/02/01 20:48:01 kardel Exp $	*/
2 
3 /*
4  * ntp_control.c - respond to control messages and send async traps
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 # include <config.h>
9 #endif
10 
11 #include "ntpd.h"
12 #include "ntp_io.h"
13 #include "ntp_refclock.h"
14 #include "ntp_control.h"
15 #include "ntp_unixtime.h"
16 #include "ntp_stdlib.h"
17 #include "ntp_config.h"
18 #include "ntp_crypto.h"
19 #include "ntp_assert.h"
20 
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <signal.h>
24 #include <sys/stat.h>
25 
26 #ifdef HAVE_NETINET_IN_H
27 #include <netinet/in.h>
28 #endif
29 #include <arpa/inet.h>
30 
31 /*
32  * Structure to hold request procedure information
33  */
34 
35 struct ctl_proc {
36 	short control_code;		/* defined request code */
37 #define NO_REQUEST	(-1)
38 	u_short flags;			/* flags word */
39 	/* Only one flag.  Authentication required or not. */
40 #define NOAUTH	0
41 #define AUTH	1
42 	void (*handler) (struct recvbuf *, int); /* handle request */
43 };
44 
45 
46 /*
47  * Request processing routines
48  */
49 static	void	ctl_error	(int);
50 #ifdef REFCLOCK
51 static	u_short ctlclkstatus	(struct refclockstat *);
52 #endif
53 static	void	ctl_flushpkt	(int);
54 static	void	ctl_putdata	(const char *, unsigned int, int);
55 static	void	ctl_putstr	(const char *, const char *,
56 				 unsigned int);
57 static	void	ctl_putdbl	(const char *, double);
58 static	void	ctl_putuint	(const char *, u_long);
59 static	void	ctl_puthex	(const char *, u_long);
60 static	void	ctl_putint	(const char *, long);
61 static	void	ctl_putts	(const char *, l_fp *);
62 static	void	ctl_putadr	(const char *, u_int32,
63 				 sockaddr_u *);
64 static	void	ctl_putrefid	(const char *, u_int32);
65 static	void	ctl_putarray	(const char *, double *, int);
66 static	void	ctl_putsys	(int);
67 static	void	ctl_putpeer	(int, struct peer *);
68 static	void	ctl_putfs	(const char *, tstamp_t);
69 #ifdef REFCLOCK
70 static	void	ctl_putclock	(int, struct refclockstat *, int);
71 #endif	/* REFCLOCK */
72 static	struct ctl_var *ctl_getitem (struct ctl_var *, char **);
73 static	u_long count_var	(struct ctl_var *);
74 static	void	control_unspec	(struct recvbuf *, int);
75 static	void	read_status	(struct recvbuf *, int);
76 static	void	read_variables	(struct recvbuf *, int);
77 static	void	write_variables (struct recvbuf *, int);
78 static	void	read_clock_status (struct recvbuf *, int);
79 static	void	write_clock_status (struct recvbuf *, int);
80 static	void	set_trap	(struct recvbuf *, int);
81 static	void	unset_trap	(struct recvbuf *, int);
82 static	void	configure	(struct recvbuf *, int);
83 static	void	save_config	(struct recvbuf *, int);
84 static	struct ctl_trap *ctlfindtrap (sockaddr_u *,
85 				      struct interface *);
86 
87 static	struct ctl_proc control_codes[] = {
88 	{ CTL_OP_UNSPEC,	NOAUTH, control_unspec },
89 	{ CTL_OP_READSTAT,	NOAUTH, read_status },
90 	{ CTL_OP_READVAR,	NOAUTH, read_variables },
91 	{ CTL_OP_WRITEVAR,	AUTH,	write_variables },
92 	{ CTL_OP_READCLOCK,	NOAUTH, read_clock_status },
93 	{ CTL_OP_WRITECLOCK,	NOAUTH, write_clock_status },
94 	{ CTL_OP_SETTRAP,	NOAUTH, set_trap },
95 	{ CTL_OP_UNSETTRAP,	NOAUTH, unset_trap },
96 	{ CTL_OP_SAVECONFIG,	AUTH,	save_config },
97 	{ CTL_OP_CONFIGURE,	AUTH,	configure },
98 	{ NO_REQUEST,		0,	NULL }
99 };
100 
101 /*
102  * System variable values. The array can be indexed by the variable
103  * index to find the textual name.
104  */
105 static struct ctl_var sys_var[] = {
106 	{ 0,		PADDING, "" },		/* 0 */
107 	{ CS_LEAP,	RW, "leap" },		/* 1 */
108 	{ CS_STRATUM,	RO, "stratum" },	/* 2 */
109 	{ CS_PRECISION, RO, "precision" },	/* 3 */
110 	{ CS_ROOTDELAY, RO, "rootdelay" },	/* 4 */
111 	{ CS_ROOTDISPERSION, RO, "rootdisp" },	/* 5 */
112 	{ CS_REFID,	RO, "refid" },		/* 6 */
113 	{ CS_REFTIME,	RO, "reftime" },	/* 7 */
114 	{ CS_POLL,	RO, "tc" },		/* 8 */
115 	{ CS_PEERID,	RO, "peer" },		/* 9 */
116 	{ CS_OFFSET,	RO, "offset" },		/* 10 */
117 	{ CS_DRIFT,	RO, "frequency" },	/* 11 */
118 	{ CS_JITTER,	RO, "sys_jitter" },	/* 12 */
119 	{ CS_ERROR,	RO, "clk_jitter" },	/* 13 */
120 	{ CS_CLOCK,	RO, "clock" },		/* 14 */
121 	{ CS_PROCESSOR, RO, "processor" },	/* 15 */
122 	{ CS_SYSTEM,	RO, "system" },		/* 16 */
123 	{ CS_VERSION,	RO, "version" },	/* 17 */
124 	{ CS_STABIL,	RO, "clk_wander" },	/* 18 */
125 	{ CS_VARLIST,	RO, "sys_var_list" },	/* 19 */
126 	{ CS_TAI,	RO, "tai" },		/* 20 */
127 	{ CS_LEAPTAB,	RO, "leapsec" },	/* 21 */
128 	{ CS_LEAPEND,	RO, "expire" },		/* 22 */
129 	{ CS_RATE,	RO, "mintc" },		/* 23 */
130 #ifdef OPENSSL
131 	{ CS_FLAGS,	RO, "flags" },		/* 24 */
132 	{ CS_HOST,	RO, "host" },		/* 25 */
133 	{ CS_PUBLIC,	RO, "update" },		/* 26 */
134 	{ CS_CERTIF,	RO, "cert" },		/* 27 */
135 	{ CS_SIGNATURE,	RO, "signature" },	/* 28 */
136 	{ CS_REVTIME,	RO, "until" },		/* 29 */
137 	{ CS_GROUP,	RO, "group" },		/* 30 */
138 	{ CS_DIGEST,	RO, "digest" },		/* 31 */
139 #endif /* OPENSSL */
140 	{ 0,		EOV, "" }		/* 24/3 2*/
141 };
142 
143 static struct ctl_var *ext_sys_var = (struct ctl_var *)0;
144 
145 /*
146  * System variables we print by default (in fuzzball order,
147  * more-or-less)
148  */
149 static	u_char def_sys_var[] = {
150 	CS_VERSION,
151 	CS_PROCESSOR,
152 	CS_SYSTEM,
153 	CS_LEAP,
154 	CS_STRATUM,
155 	CS_PRECISION,
156 	CS_ROOTDELAY,
157 	CS_ROOTDISPERSION,
158 	CS_REFID,
159 	CS_REFTIME,
160 	CS_CLOCK,
161 	CS_PEERID,
162 	CS_POLL,
163 	CS_RATE,
164 	CS_OFFSET,
165 	CS_DRIFT,
166 	CS_JITTER,
167 	CS_ERROR,
168 	CS_STABIL,
169 	CS_TAI,
170 	CS_LEAPTAB,
171 	CS_LEAPEND,
172 #ifdef OPENSSL
173 	CS_HOST,
174 	CS_GROUP,
175 	CS_FLAGS,
176 	CS_DIGEST,
177 	CS_SIGNATURE,
178 	CS_PUBLIC,
179 	CS_CERTIF,
180 #endif /* OPENSSL */
181 	0
182 };
183 
184 
185 /*
186  * Peer variable list
187  */
188 static struct ctl_var peer_var[] = {
189 	{ 0,		PADDING, "" },		/* 0 */
190 	{ CP_CONFIG,	RO, "config" },		/* 1 */
191 	{ CP_AUTHENABLE, RO,	"authenable" },	/* 2 */
192 	{ CP_AUTHENTIC, RO, "authentic" }, 	/* 3 */
193 	{ CP_SRCADR,	RO, "srcadr" },		/* 4 */
194 	{ CP_SRCPORT,	RO, "srcport" },	/* 5 */
195 	{ CP_DSTADR,	RO, "dstadr" },		/* 6 */
196 	{ CP_DSTPORT,	RO, "dstport" },	/* 7 */
197 	{ CP_LEAP,	RO, "leap" },		/* 8 */
198 	{ CP_HMODE,	RO, "hmode" },		/* 9 */
199 	{ CP_STRATUM,	RO, "stratum" },	/* 10 */
200 	{ CP_PPOLL,	RO, "ppoll" },		/* 11 */
201 	{ CP_HPOLL,	RO, "hpoll" },		/* 12 */
202 	{ CP_PRECISION,	RO, "precision" },	/* 13 */
203 	{ CP_ROOTDELAY,	RO, "rootdelay" },	/* 14 */
204 	{ CP_ROOTDISPERSION, RO, "rootdisp" },	/* 15 */
205 	{ CP_REFID,	RO, "refid" },		/* 16 */
206 	{ CP_REFTIME,	RO, "reftime" },	/* 17 */
207 	{ CP_ORG,	RO, "org" },		/* 18 */
208 	{ CP_REC,	RO, "rec" },		/* 19 */
209 	{ CP_XMT,	RO, "xleave" },		/* 20 */
210 	{ CP_REACH,	RO, "reach" },		/* 21 */
211 	{ CP_UNREACH,	RO, "unreach" },	/* 22 */
212 	{ CP_TIMER,	RO, "timer" },		/* 23 */
213 	{ CP_DELAY,	RO, "delay" },		/* 24 */
214 	{ CP_OFFSET,	RO, "offset" },		/* 25 */
215 	{ CP_JITTER,	RO, "jitter" },		/* 26 */
216 	{ CP_DISPERSION, RO, "dispersion" },	/* 27 */
217 	{ CP_KEYID,	RO, "keyid" },		/* 28 */
218 	{ CP_FILTDELAY,	RO, "filtdelay=" },	/* 29 */
219 	{ CP_FILTOFFSET, RO, "filtoffset=" },	/* 30 */
220 	{ CP_PMODE,	RO, "pmode" },		/* 31 */
221 	{ CP_RECEIVED,	RO, "received"},	/* 32 */
222 	{ CP_SENT,	RO, "sent" },		/* 33 */
223 	{ CP_FILTERROR,	RO, "filtdisp=" },	/* 34 */
224 	{ CP_FLASH,	RO, "flash" },		/* 35 */
225 	{ CP_TTL,	RO, "ttl" },		/* 36 */
226 	{ CP_VARLIST,	RO, "peer_var_list" },	/* 37 */
227 	{ CP_IN,	RO, "in" },		/* 38 */
228 	{ CP_OUT,	RO, "out" },		/* 39 */
229 	{ CP_RATE,	RO, "headway" },	/* 40 */
230 	{ CP_BIAS,	RO, "bias" },		/* 41 */
231 #ifdef OPENSSL
232 	{ CP_FLAGS,	RO, "flags" },		/* 42 */
233 	{ CP_HOST,	RO, "host" },		/* 43 */
234 	{ CP_VALID,	RO, "valid" },		/* 44 */
235 	{ CP_INITSEQ,	RO, "initsequence" },   /* 45 */
236 	{ CP_INITKEY,	RO, "initkey" },	/* 46 */
237 	{ CP_INITTSP,	RO, "timestamp" },	/* 47 */
238 	{ CP_SIGNATURE,	RO, "signature" },	/* 48 */
239 #endif /* OPENSSL */
240 	{ 0,		EOV, "" }		/* 42/49 */
241 };
242 
243 
244 /*
245  * Peer variables we print by default
246  */
247 static u_char def_peer_var[] = {
248 	CP_SRCADR,
249 	CP_SRCPORT,
250 	CP_DSTADR,
251 	CP_DSTPORT,
252 	CP_OUT,
253 	CP_IN,
254 	CP_LEAP,
255 	CP_STRATUM,
256 	CP_PRECISION,
257 	CP_ROOTDELAY,
258 	CP_ROOTDISPERSION,
259 	CP_REFID,
260 	CP_REFTIME,
261 	CP_REC,
262 	CP_REACH,
263 	CP_UNREACH,
264 	CP_HMODE,
265 	CP_PMODE,
266 	CP_HPOLL,
267 	CP_PPOLL,
268 	CP_RATE,
269 	CP_FLASH,
270 	CP_KEYID,
271 	CP_TTL,
272 	CP_OFFSET,
273 	CP_DELAY,
274 	CP_DISPERSION,
275 	CP_JITTER,
276 	CP_XMT,
277 	CP_BIAS,
278 	CP_FILTDELAY,
279 	CP_FILTOFFSET,
280 	CP_FILTERROR,
281 #ifdef OPENSSL
282 	CP_HOST,
283 	CP_FLAGS,
284 	CP_SIGNATURE,
285 	CP_VALID,
286 	CP_INITSEQ,
287 #endif /* OPENSSL */
288 	0
289 };
290 
291 
292 #ifdef REFCLOCK
293 /*
294  * Clock variable list
295  */
296 static struct ctl_var clock_var[] = {
297 	{ 0,		PADDING, "" },		/* 0 */
298 	{ CC_TYPE,	RO, "type" },		/* 1 */
299 	{ CC_TIMECODE,	RO, "timecode" },	/* 2 */
300 	{ CC_POLL,	RO, "poll" },		/* 3 */
301 	{ CC_NOREPLY,	RO, "noreply" },	/* 4 */
302 	{ CC_BADFORMAT, RO, "badformat" },	/* 5 */
303 	{ CC_BADDATA,	RO, "baddata" },	/* 6 */
304 	{ CC_FUDGETIME1, RO, "fudgetime1" },	/* 7 */
305 	{ CC_FUDGETIME2, RO, "fudgetime2" },	/* 8 */
306 	{ CC_FUDGEVAL1, RO, "stratum" },	/* 9 */
307 	{ CC_FUDGEVAL2, RO, "refid" },		/* 10 */
308 	{ CC_FLAGS,	RO, "flags" },		/* 11 */
309 	{ CC_DEVICE,	RO, "device" },		/* 12 */
310 	{ CC_VARLIST,	RO, "clock_var_list" },	/* 13 */
311 	{ 0,		EOV, ""  }		/* 14 */
312 };
313 
314 
315 /*
316  * Clock variables printed by default
317  */
318 static u_char def_clock_var[] = {
319 	CC_DEVICE,
320 	CC_TYPE,	/* won't be output if device = known */
321 	CC_TIMECODE,
322 	CC_POLL,
323 	CC_NOREPLY,
324 	CC_BADFORMAT,
325 	CC_BADDATA,
326 	CC_FUDGETIME1,
327 	CC_FUDGETIME2,
328 	CC_FUDGEVAL1,
329 	CC_FUDGEVAL2,
330 	CC_FLAGS,
331 	0
332 };
333 #endif
334 
335 
336 /*
337  * System and processor definitions.
338  */
339 #ifndef HAVE_UNAME
340 # ifndef STR_SYSTEM
341 #  define		STR_SYSTEM	"UNIX"
342 # endif
343 # ifndef STR_PROCESSOR
344 #  define		STR_PROCESSOR	"unknown"
345 # endif
346 
347 static char str_system[] = STR_SYSTEM;
348 static char str_processor[] = STR_PROCESSOR;
349 #else
350 # include <sys/utsname.h>
351 static struct utsname utsnamebuf;
352 #endif /* HAVE_UNAME */
353 
354 /*
355  * Trap structures. We only allow a few of these, and send a copy of
356  * each async message to each live one. Traps time out after an hour, it
357  * is up to the trap receipient to keep resetting it to avoid being
358  * timed out.
359  */
360 /* ntp_request.c */
361 struct ctl_trap ctl_trap[CTL_MAXTRAPS];
362 int num_ctl_traps;
363 
364 /*
365  * Type bits, for ctlsettrap() call.
366  */
367 #define TRAP_TYPE_CONFIG	0	/* used by configuration code */
368 #define TRAP_TYPE_PRIO		1	/* priority trap */
369 #define TRAP_TYPE_NONPRIO	2	/* nonpriority trap */
370 
371 
372 /*
373  * List relating reference clock types to control message time sources.
374  * Index by the reference clock type. This list will only be used iff
375  * the reference clock driver doesn't set peer->sstclktype to something
376  * different than CTL_SST_TS_UNSPEC.
377  */
378 static u_char clocktypes[] = {
379 	CTL_SST_TS_NTP, 	/* REFCLK_NONE (0) */
380 	CTL_SST_TS_LOCAL,	/* REFCLK_LOCALCLOCK (1) */
381 	CTL_SST_TS_UHF, 	/* deprecated REFCLK_GPS_TRAK (2) */
382 	CTL_SST_TS_HF,		/* REFCLK_WWV_PST (3) */
383 	CTL_SST_TS_LF,		/* REFCLK_WWVB_SPECTRACOM (4) */
384 	CTL_SST_TS_UHF, 	/* REFCLK_TRUETIME (5) */
385 	CTL_SST_TS_UHF, 	/* REFCLK_GOES_TRAK (6) IRIG_AUDIO? */
386 	CTL_SST_TS_HF,		/* REFCLK_CHU (7) */
387 	CTL_SST_TS_LF,		/* REFCLOCK_PARSE (default) (8) */
388 	CTL_SST_TS_LF,		/* REFCLK_GPS_MX4200 (9) */
389 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_AS2201 (10) */
390 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_ARBITER (11) */
391 	CTL_SST_TS_UHF, 	/* REFCLK_IRIG_TPRO (12) */
392 	CTL_SST_TS_ATOM,	/* REFCLK_ATOM_LEITCH (13) */
393 	CTL_SST_TS_LF,		/* deprecated REFCLK_MSF_EES (14) */
394 	CTL_SST_TS_NTP, 	/* not used (15) */
395 	CTL_SST_TS_UHF, 	/* REFCLK_IRIG_BANCOMM (16) */
396 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_DATU (17) */
397 	CTL_SST_TS_TELEPHONE,	/* REFCLK_NIST_ACTS (18) */
398 	CTL_SST_TS_HF,		/* REFCLK_WWV_HEATH (19) */
399 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_NMEA (20) */
400 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_VME (21) */
401 	CTL_SST_TS_ATOM,	/* REFCLK_ATOM_PPS (22) */
402 	CTL_SST_TS_NTP,		/* not used (23) */
403 	CTL_SST_TS_NTP,		/* not used (24) */
404 	CTL_SST_TS_NTP, 	/* not used (25) */
405 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_HP (26) */
406 	CTL_SST_TS_LF,		/* REFCLK_ARCRON_MSF (27) */
407 	CTL_SST_TS_UHF,		/* REFCLK_SHM (28) */
408 	CTL_SST_TS_UHF, 	/* REFCLK_PALISADE (29) */
409 	CTL_SST_TS_UHF, 	/* REFCLK_ONCORE (30) */
410 	CTL_SST_TS_UHF,		/* REFCLK_JUPITER (31) */
411 	CTL_SST_TS_LF,		/* REFCLK_CHRONOLOG (32) */
412 	CTL_SST_TS_LF,		/* REFCLK_DUMBCLOCK (33) */
413 	CTL_SST_TS_LF,		/* REFCLK_ULINK (34) */
414 	CTL_SST_TS_LF,		/* REFCLK_PCF (35) */
415 	CTL_SST_TS_HF,		/* REFCLK_WWV (36) */
416 	CTL_SST_TS_LF,		/* REFCLK_FG (37) */
417 	CTL_SST_TS_UHF, 	/* REFCLK_HOPF_SERIAL (38) */
418 	CTL_SST_TS_UHF,		/* REFCLK_HOPF_PCI (39) */
419 	CTL_SST_TS_LF,		/* REFCLK_JJY (40) */
420 	CTL_SST_TS_UHF,		/* REFCLK_TT560 (41) */
421 	CTL_SST_TS_UHF,		/* REFCLK_ZYFER (42) */
422 	CTL_SST_TS_UHF,		/* REFCLK_RIPENCC (43) */
423 	CTL_SST_TS_UHF,		/* REFCLK_NEOCLOCK4X (44) */
424 };
425 
426 
427 /*
428  * Keyid used for authenticating write requests.
429  */
430 keyid_t ctl_auth_keyid;
431 
432 /*
433  * We keep track of the last error reported by the system internally
434  */
435 static	u_char ctl_sys_last_event;
436 static	u_char ctl_sys_num_events;
437 
438 
439 /*
440  * Statistic counters to keep track of requests and responses.
441  */
442 u_long ctltimereset;		/* time stats reset */
443 u_long numctlreq;		/* number of requests we've received */
444 u_long numctlbadpkts;		/* number of bad control packets */
445 u_long numctlresponses; 	/* number of resp packets sent with data */
446 u_long numctlfrags; 		/* number of fragments sent */
447 u_long numctlerrors;		/* number of error responses sent */
448 u_long numctltooshort;		/* number of too short input packets */
449 u_long numctlinputresp; 	/* number of responses on input */
450 u_long numctlinputfrag; 	/* number of fragments on input */
451 u_long numctlinputerr;		/* number of input pkts with err bit set */
452 u_long numctlbadoffset; 	/* number of input pkts with nonzero offset */
453 u_long numctlbadversion;	/* number of input pkts with unknown version */
454 u_long numctldatatooshort;	/* data too short for count */
455 u_long numctlbadop; 		/* bad op code found in packet */
456 u_long numasyncmsgs;		/* number of async messages we've sent */
457 
458 /*
459  * Response packet used by these routines. Also some state information
460  * so that we can handle packet formatting within a common set of
461  * subroutines.  Note we try to enter data in place whenever possible,
462  * but the need to set the more bit correctly means we occasionally
463  * use the extra buffer and copy.
464  */
465 static struct ntp_control rpkt;
466 static u_char	res_version;
467 static u_char	res_opcode;
468 static associd_t res_associd;
469 static int	res_offset;
470 static u_char * datapt;
471 static u_char * dataend;
472 static int	datalinelen;
473 static int	datanotbinflag;
474 static sockaddr_u *rmt_addr;
475 static struct interface *lcl_inter;
476 
477 static u_char	res_authenticate;
478 static u_char	res_authokay;
479 static keyid_t	res_keyid;
480 
481 #define MAXDATALINELEN	(72)
482 
483 static u_char	res_async;	/* set to 1 if this is async trap response */
484 
485 /*
486  * Pointers for saving state when decoding request packets
487  */
488 static	char *reqpt;
489 static	char *reqend;
490 
491 /*
492  * init_control - initialize request data
493  */
494 void
495 init_control(void)
496 {
497 	int i;
498 
499 #ifdef HAVE_UNAME
500 	uname(&utsnamebuf);
501 #endif /* HAVE_UNAME */
502 
503 	ctl_clr_stats();
504 
505 	ctl_auth_keyid = 0;
506 	ctl_sys_last_event = EVNT_UNSPEC;
507 	ctl_sys_num_events = 0;
508 
509 	num_ctl_traps = 0;
510 	for (i = 0; i < CTL_MAXTRAPS; i++)
511 		ctl_trap[i].tr_flags = 0;
512 }
513 
514 
515 /*
516  * ctl_error - send an error response for the current request
517  */
518 static void
519 ctl_error(
520 	int errcode
521 	)
522 {
523 	DPRINTF(3, ("sending control error %d\n", errcode));
524 
525 	/*
526 	 * Fill in the fields. We assume rpkt.sequence and rpkt.associd
527 	 * have already been filled in.
528 	 */
529 	rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode &
530 							  CTL_OP_MASK));
531 	rpkt.status = htons((u_short) ((errcode & 0xff) << 8));
532 	rpkt.count = 0;
533 
534 	/*
535 	 * send packet and bump counters
536 	 */
537 	if (res_authenticate && sys_authenticate) {
538 		int maclen;
539 
540 		maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
541 				     CTL_HEADER_LEN);
542 		sendpkt(rmt_addr, lcl_inter, -2, (struct pkt *)&rpkt,
543 			CTL_HEADER_LEN + maclen);
544 	} else {
545 		sendpkt(rmt_addr, lcl_inter, -3, (struct pkt *)&rpkt,
546 			CTL_HEADER_LEN);
547 	}
548 	numctlerrors++;
549 }
550 
551 /*
552  * save_config - Implements ntpq -c "saveconfig <filename>"
553  *		 Writes current configuration including any runtime
554  *		 changes by ntpq's :config or config-from-file
555  */
556 void
557 save_config(
558 	struct recvbuf *rbufp,
559 	int restrict_mask
560 	)
561 {
562 	char reply[128];
563 #ifdef SAVECONFIG
564 	char filespec[128];
565 	char filename[128];
566 	char fullpath[512];
567 	const char savedconfig_eq[] = "savedconfig=";
568 	char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)];
569 	time_t now;
570 	int fd;
571 	FILE *fptr;
572 #endif
573 
574 	if (restrict_mask & RES_NOMODIFY) {
575 		snprintf(reply, sizeof(reply),
576 			 "saveconfig prohibited by restrict ... nomodify");
577 		ctl_putdata(reply, strlen(reply), 0);
578 		ctl_flushpkt(0);
579 		msyslog(LOG_NOTICE,
580 			"saveconfig from %s rejected due to nomodify restriction",
581 			stoa(&rbufp->recv_srcadr));
582 		return;
583 	}
584 
585 #ifdef SAVECONFIG
586 	if (NULL == saveconfigdir) {
587 		snprintf(reply, sizeof(reply),
588 			 "saveconfig prohibited, no saveconfigdir configured");
589 		ctl_putdata(reply, strlen(reply), 0);
590 		ctl_flushpkt(0);
591 		msyslog(LOG_NOTICE,
592 			"saveconfig from %s rejected, no saveconfigdir",
593 			stoa(&rbufp->recv_srcadr));
594 		return;
595 	}
596 
597 	if (0 == reqend - reqpt)
598 		return;
599 
600 	strncpy(filespec, reqpt, sizeof(filespec));
601 	filespec[sizeof(filespec) - 1] = '\0';
602 
603 	time(&now);
604 
605 	/*
606 	 * allow timestamping of the saved config filename with
607 	 * strftime() format such as:
608 	 *   ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf"
609 	 * XXX: Nice feature, but not too safe.
610 	 */
611 	if (0 == strftime(filename, sizeof(filename), filespec,
612 			       localtime(&now)))
613 		strncpy(filename, filespec, sizeof(filename));
614 
615 	filename[sizeof(filename) - 1] = '\0';
616 
617 	if (strchr(filename, '\\') || strchr(filename, '/')) {
618 		snprintf(reply, sizeof(reply),
619 			 "saveconfig does not allow directory in filename");
620 		ctl_putdata(reply, strlen(reply), 0);
621 		ctl_flushpkt(0);
622 		msyslog(LOG_NOTICE,
623 			"saveconfig with path from %s rejected",
624 			stoa(&rbufp->recv_srcadr));
625 		return;
626 	}
627 
628 	snprintf(fullpath, sizeof(fullpath), "%s%s",
629 		 saveconfigdir, filename);
630 
631 	fd = open(fullpath, O_CREAT | O_TRUNC | O_WRONLY,
632 		  S_IRUSR | S_IWUSR);
633 	if (-1 == fd)
634 		fptr = NULL;
635 	else
636 		fptr = fdopen(fd, "w");
637 
638 	if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) {
639 		snprintf(reply, sizeof(reply),
640 			 "Unable to save configuration to file %s",
641 			 filename);
642 		msyslog(LOG_ERR,
643 			"saveconfig %s from %s failed", filename,
644 			stoa(&rbufp->recv_srcadr));
645 	} else {
646 		snprintf(reply, sizeof(reply),
647 			 "Configuration saved to %s", filename);
648 		msyslog(LOG_NOTICE,
649 			"Configuration saved to %s (requested by %s)",
650 			fullpath, stoa(&rbufp->recv_srcadr));
651 		/*
652 		 * save the output filename in system variable
653 		 * savedconfig, retrieved with:
654 		 *   ntpq -c "rv 0 savedconfig"
655 		 */
656 		snprintf(savedconfig, sizeof(savedconfig), "%s%s",
657 			 savedconfig_eq, filename);
658 		set_sys_var(savedconfig, strlen(savedconfig) + 1, RO);
659 	}
660 
661 	if (NULL != fptr)
662 		fclose(fptr);
663 #else	/* !SAVECONFIG follows */
664 	snprintf(reply, sizeof(reply),
665 		 "saveconfig unavailable, configured with --disable-saveconfig");
666 #endif
667 
668 	ctl_putdata(reply, strlen(reply), 0);
669 	ctl_flushpkt(0);
670 }
671 
672 
673 /*
674  * process_control - process an incoming control message
675  */
676 void
677 process_control(
678 	struct recvbuf *rbufp,
679 	int restrict_mask
680 	)
681 {
682 	register struct ntp_control *pkt;
683 	register int req_count;
684 	register int req_data;
685 	register struct ctl_proc *cc;
686 	int properlen;
687 	size_t maclen;
688 
689 	DPRINTF(3, ("in process_control()\n"));
690 
691 	/*
692 	 * Save the addresses for error responses
693 	 */
694 	numctlreq++;
695 	rmt_addr = &rbufp->recv_srcadr;
696 	lcl_inter = rbufp->dstadr;
697 	pkt = (struct ntp_control *)&rbufp->recv_pkt;
698 
699 	/*
700 	 * If the length is less than required for the header, or
701 	 * it is a response or a fragment, ignore this.
702 	 */
703 	if (rbufp->recv_length < (int)CTL_HEADER_LEN
704 	    || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR)
705 	    || pkt->offset != 0) {
706 		DPRINTF(1, ("invalid format in control packet\n"));
707 		if (rbufp->recv_length < (int)CTL_HEADER_LEN)
708 			numctltooshort++;
709 		if (pkt->r_m_e_op & CTL_RESPONSE)
710 			numctlinputresp++;
711 		if (pkt->r_m_e_op & CTL_MORE)
712 			numctlinputfrag++;
713 		if (pkt->r_m_e_op & CTL_ERROR)
714 			numctlinputerr++;
715 		if (pkt->offset != 0)
716 			numctlbadoffset++;
717 		return;
718 	}
719 	res_version = PKT_VERSION(pkt->li_vn_mode);
720 	if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
721 		DPRINTF(1, ("unknown version %d in control packet\n",
722 			    res_version));
723 		numctlbadversion++;
724 		return;
725 	}
726 
727 	/*
728 	 * Pull enough data from the packet to make intelligent
729 	 * responses
730 	 */
731 	rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
732 					 MODE_CONTROL);
733 	res_opcode = pkt->r_m_e_op;
734 	rpkt.sequence = pkt->sequence;
735 	rpkt.associd = pkt->associd;
736 	rpkt.status = 0;
737 	res_offset = 0;
738 	res_associd = htons(pkt->associd);
739 	res_async = 0;
740 	res_authenticate = 0;
741 	res_keyid = 0;
742 	res_authokay = 0;
743 	req_count = (int)ntohs(pkt->count);
744 	datanotbinflag = 0;
745 	datalinelen = 0;
746 	datapt = rpkt.data;
747 	dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
748 
749 	if ((rbufp->recv_length & 0x3) != 0)
750 		DPRINTF(3, ("Control packet length %d unrounded\n",
751 			    rbufp->recv_length));
752 
753 	/*
754 	 * We're set up now. Make sure we've got at least enough
755 	 * incoming data space to match the count.
756 	 */
757 	req_data = rbufp->recv_length - CTL_HEADER_LEN;
758 	if (req_data < req_count || rbufp->recv_length & 0x3) {
759 		ctl_error(CERR_BADFMT);
760 		numctldatatooshort++;
761 		return;
762 	}
763 
764 	properlen = req_count + CTL_HEADER_LEN;
765 	/* round up proper len to a 8 octet boundary */
766 
767 	properlen = (properlen + 7) & ~7;
768 	maclen = rbufp->recv_length - properlen;
769 	if ((rbufp->recv_length & 3) == 0 &&
770 	    maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
771 	    sys_authenticate) {
772 		res_authenticate = 1;
773 		res_keyid = ntohl(*(u_int32 *)((u_char *)pkt +
774 					       properlen));
775 
776 		DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n",
777 			    rbufp->recv_length, properlen, res_keyid,
778 			    maclen));
779 
780 		if (!authistrusted(res_keyid))
781 			DPRINTF(3, ("invalid keyid %08x\n", res_keyid));
782 		else if (authdecrypt(res_keyid, (u_int32 *)pkt,
783 				     rbufp->recv_length - maclen,
784 				     maclen)) {
785 			DPRINTF(3, ("authenticated okay\n"));
786 			res_authokay = 1;
787 		} else {
788 			DPRINTF(3, ("authentication failed\n"));
789 			res_keyid = 0;
790 		}
791 	}
792 
793 	/*
794 	 * Set up translate pointers
795 	 */
796 	reqpt = (char *)pkt->data;
797 	reqend = reqpt + req_count;
798 
799 	/*
800 	 * Look for the opcode processor
801 	 */
802 	for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
803 		if (cc->control_code == res_opcode) {
804 			DPRINTF(3, ("opcode %d, found command handler\n",
805 				    res_opcode));
806 			if (cc->flags == AUTH
807 			    && (!res_authokay
808 				|| res_keyid != ctl_auth_keyid)) {
809 				ctl_error(CERR_PERMISSION);
810 				return;
811 			}
812 			(cc->handler)(rbufp, restrict_mask);
813 			return;
814 		}
815 	}
816 
817 	/*
818 	 * Can't find this one, return an error.
819 	 */
820 	numctlbadop++;
821 	ctl_error(CERR_BADOP);
822 	return;
823 }
824 
825 
826 /*
827  * ctlpeerstatus - return a status word for this peer
828  */
829 u_short
830 ctlpeerstatus(
831 	register struct peer *peer
832 	)
833 {
834 	u_short status;
835 
836 	status = peer->status;
837 	if (!(peer->flags & FLAG_PREEMPT))
838 		status |= CTL_PST_CONFIG;
839 	if (peer->keyid != 0)
840 		status |= CTL_PST_AUTHENABLE;
841 	if (peer->flags & FLAG_AUTHENTIC)
842 		status |= CTL_PST_AUTHENTIC;
843 	if (peer->reach != 0)
844 		status |= CTL_PST_REACH;
845 	if (peer->cast_flags & (MDF_BCAST | MDF_MCAST | MDF_ACAST))
846 		status |= CTL_PST_BCAST;
847 	return (u_short)CTL_PEER_STATUS(status, peer->num_events,
848 	    peer->last_event);
849 }
850 
851 
852 /*
853  * ctlclkstatus - return a status word for this clock
854  */
855 #ifdef REFCLOCK
856 static u_short
857 ctlclkstatus(
858 	struct refclockstat *this_clock
859 	)
860 {
861 	return (u_short)CTL_PEER_STATUS(0, this_clock->lastevent,
862 	    this_clock->currentstatus);
863 }
864 #endif
865 
866 
867 /*
868  * ctlsysstatus - return the system status word
869  */
870 u_short
871 ctlsysstatus(void)
872 {
873 	register u_char this_clock;
874 
875 	this_clock = CTL_SST_TS_UNSPEC;
876 #ifdef REFCLOCK
877 	if (sys_peer != 0) {
878 		if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC) {
879 			this_clock = sys_peer->sstclktype;
880 		} else {
881 			if (sys_peer->refclktype < sizeof(clocktypes))
882 				this_clock =
883 				    clocktypes[sys_peer->refclktype];
884 		}
885 	}
886 #else /* REFCLOCK */
887 	if (sys_peer != 0)
888 		this_clock = CTL_SST_TS_NTP;
889 #endif /* REFCLOCK */
890 	return (u_short)CTL_SYS_STATUS(sys_leap, this_clock,
891 	    ctl_sys_num_events, ctl_sys_last_event);
892 }
893 
894 
895 /*
896  * ctl_flushpkt - write out the current packet and prepare
897  *		  another if necessary.
898  */
899 static void
900 ctl_flushpkt(
901 	int more
902 	)
903 {
904 	int dlen;
905 	int sendlen;
906 
907 	if (!more && datanotbinflag) {
908 		/*
909 		 * Big hack, output a trailing \r\n
910 		 */
911 		*datapt++ = '\r';
912 		*datapt++ = '\n';
913 	}
914 	dlen = datapt - (u_char *)rpkt.data;
915 	sendlen = dlen + CTL_HEADER_LEN;
916 
917 	/*
918 	 * Pad to a multiple of 32 bits
919 	 */
920 	while (sendlen & 0x3) {
921 		*datapt++ = '\0';
922 		sendlen++;
923 	}
924 
925 	/*
926 	 * Fill in the packet with the current info
927 	 */
928 	rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode &
929 						    CTL_OP_MASK));
930 	rpkt.count = htons((u_short) dlen);
931 	rpkt.offset = htons( (u_short) res_offset);
932 	if (res_async) {
933 		register int i;
934 
935 		for (i = 0; i < CTL_MAXTRAPS; i++) {
936 			if (ctl_trap[i].tr_flags & TRAP_INUSE) {
937 				rpkt.li_vn_mode =
938 				    PKT_LI_VN_MODE(sys_leap,
939 						   ctl_trap[i].tr_version,
940 						   MODE_CONTROL);
941 				rpkt.sequence =
942 				    htons(ctl_trap[i].tr_sequence);
943 				sendpkt(&ctl_trap[i].tr_addr,
944 					ctl_trap[i].tr_localaddr, -4,
945 					(struct pkt *)&rpkt, sendlen);
946 				if (!more)
947 					ctl_trap[i].tr_sequence++;
948 				numasyncmsgs++;
949 			}
950 		}
951 	} else {
952 		if (res_authenticate && sys_authenticate) {
953 			int maclen;
954 			int totlen = sendlen;
955 			keyid_t keyid = htonl(res_keyid);
956 
957 			/*
958 			 * If we are going to authenticate, then there
959 			 * is an additional requirement that the MAC
960 			 * begin on a 64 bit boundary.
961 			 */
962 			while (totlen & 7) {
963 				*datapt++ = '\0';
964 				totlen++;
965 			}
966 			memcpy(datapt, &keyid, sizeof keyid);
967 			maclen = authencrypt(res_keyid,
968 					     (u_int32 *)&rpkt, totlen);
969 			sendpkt(rmt_addr, lcl_inter, -5,
970 				(struct pkt *)&rpkt, totlen + maclen);
971 		} else {
972 			sendpkt(rmt_addr, lcl_inter, -6,
973 				(struct pkt *)&rpkt, sendlen);
974 		}
975 		if (more)
976 			numctlfrags++;
977 		else
978 			numctlresponses++;
979 	}
980 
981 	/*
982 	 * Set us up for another go around.
983 	 */
984 	res_offset += dlen;
985 	datapt = (u_char *)rpkt.data;
986 }
987 
988 
989 /*
990  * ctl_putdata - write data into the packet, fragmenting and starting
991  * another if this one is full.
992  */
993 static void
994 ctl_putdata(
995 	const char *dp,
996 	unsigned int dlen,
997 	int bin 		/* set to 1 when data is binary */
998 	)
999 {
1000 	int overhead;
1001 
1002 	overhead = 0;
1003 	if (!bin) {
1004 		datanotbinflag = 1;
1005 		overhead = 3;
1006 		if (datapt != rpkt.data) {
1007 			*datapt++ = ',';
1008 			datalinelen++;
1009 			if ((dlen + datalinelen + 1) >= MAXDATALINELEN)
1010 			{
1011 				*datapt++ = '\r';
1012 				*datapt++ = '\n';
1013 				datalinelen = 0;
1014 			} else {
1015 				*datapt++ = ' ';
1016 				datalinelen++;
1017 			}
1018 		}
1019 	}
1020 
1021 	/*
1022 	 * Save room for trailing junk
1023 	 */
1024 	if (dlen + overhead + datapt > dataend) {
1025 		/*
1026 		 * Not enough room in this one, flush it out.
1027 		 */
1028 		ctl_flushpkt(CTL_MORE);
1029 	}
1030 	memmove((char *)datapt, dp, (unsigned)dlen);
1031 	datapt += dlen;
1032 	datalinelen += dlen;
1033 }
1034 
1035 
1036 /*
1037  * ctl_putstr - write a tagged string into the response packet
1038  */
1039 static void
1040 ctl_putstr(
1041 	const char *tag,
1042 	const char *data,
1043 	unsigned int len
1044 	)
1045 {
1046 	register char *cp;
1047 	register const char *cq;
1048 	char buffer[400];
1049 
1050 	cp = buffer;
1051 	cq = tag;
1052 	while (*cq != '\0')
1053 		*cp++ = *cq++;
1054 	if (len > 0) {
1055 		*cp++ = '=';
1056 		*cp++ = '"';
1057 		if (len > (sizeof(buffer) - (cp - buffer) - 1))
1058 			len = sizeof(buffer) - (cp - buffer) - 1;
1059 		memmove(cp, data, (unsigned)len);
1060 		cp += len;
1061 		*cp++ = '"';
1062 	}
1063 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1064 }
1065 
1066 
1067 /*
1068  * ctl_putdbl - write a tagged, signed double into the response packet
1069  */
1070 static void
1071 ctl_putdbl(
1072 	const char *tag,
1073 	double ts
1074 	)
1075 {
1076 	register char *cp;
1077 	register const char *cq;
1078 	char buffer[200];
1079 
1080 	cp = buffer;
1081 	cq = tag;
1082 	while (*cq != '\0')
1083 		*cp++ = *cq++;
1084 	*cp++ = '=';
1085 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1086 	snprintf(cp, sizeof(buffer) - (cp - buffer), "%.3f", ts);
1087 	cp += strlen(cp);
1088 	ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
1089 }
1090 
1091 /*
1092  * ctl_putuint - write a tagged unsigned integer into the response
1093  */
1094 static void
1095 ctl_putuint(
1096 	const char *tag,
1097 	u_long uval
1098 	)
1099 {
1100 	register char *cp;
1101 	register const char *cq;
1102 	char buffer[200];
1103 
1104 	cp = buffer;
1105 	cq = tag;
1106 	while (*cq != '\0')
1107 		*cp++ = *cq++;
1108 
1109 	*cp++ = '=';
1110 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1111 	snprintf(cp, sizeof(buffer) - (cp - buffer), "%lu", uval);
1112 	cp += strlen(cp);
1113 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1114 }
1115 
1116 /*
1117  * ctl_putfs - write a decoded filestamp into the response
1118  */
1119 static void
1120 ctl_putfs(
1121 	const char *tag,
1122 	tstamp_t uval
1123 	)
1124 {
1125 	register char *cp;
1126 	register const char *cq;
1127 	char buffer[200];
1128 	struct tm *tm = NULL;
1129 	time_t fstamp;
1130 
1131 	cp = buffer;
1132 	cq = tag;
1133 	while (*cq != '\0')
1134 		*cp++ = *cq++;
1135 
1136 	*cp++ = '=';
1137 	fstamp = uval - JAN_1970;
1138 	tm = gmtime(&fstamp);
1139 	if (NULL ==  tm)
1140 		return;
1141 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1142 	snprintf(cp, sizeof(buffer) - (cp - buffer),
1143 		 "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
1144 		 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
1145 	cp += strlen(cp);
1146 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1147 }
1148 
1149 
1150 /*
1151  * ctl_puthex - write a tagged unsigned integer, in hex, into the
1152  * response
1153  */
1154 static void
1155 ctl_puthex(
1156 	const char *tag,
1157 	u_long uval
1158 	)
1159 {
1160 	register char *cp;
1161 	register const char *cq;
1162 	char buffer[200];
1163 
1164 	cp = buffer;
1165 	cq = tag;
1166 	while (*cq != '\0')
1167 		*cp++ = *cq++;
1168 
1169 	*cp++ = '=';
1170 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1171 	snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%lx", uval);
1172 	cp += strlen(cp);
1173 	ctl_putdata(buffer,(unsigned)( cp - buffer ), 0);
1174 }
1175 
1176 
1177 /*
1178  * ctl_putint - write a tagged signed integer into the response
1179  */
1180 static void
1181 ctl_putint(
1182 	const char *tag,
1183 	long ival
1184 	)
1185 {
1186 	register char *cp;
1187 	register const char *cq;
1188 	char buffer[200];
1189 
1190 	cp = buffer;
1191 	cq = tag;
1192 	while (*cq != '\0')
1193 		*cp++ = *cq++;
1194 
1195 	*cp++ = '=';
1196 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1197 	snprintf(cp, sizeof(buffer) - (cp - buffer), "%ld", ival);
1198 	cp += strlen(cp);
1199 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1200 }
1201 
1202 
1203 /*
1204  * ctl_putts - write a tagged timestamp, in hex, into the response
1205  */
1206 static void
1207 ctl_putts(
1208 	const char *tag,
1209 	l_fp *ts
1210 	)
1211 {
1212 	register char *cp;
1213 	register const char *cq;
1214 	char buffer[200];
1215 
1216 	cp = buffer;
1217 	cq = tag;
1218 	while (*cq != '\0')
1219 		*cp++ = *cq++;
1220 
1221 	*cp++ = '=';
1222 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1223 	snprintf(cp, sizeof(buffer) - (cp - buffer), "0x%08lx.%08lx",
1224 		 ts->l_ui & 0xffffffffUL, ts->l_uf & 0xffffffffUL);
1225 	cp += strlen(cp);
1226 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1227 }
1228 
1229 
1230 /*
1231  * ctl_putadr - write an IP address into the response
1232  */
1233 static void
1234 ctl_putadr(
1235 	const char *tag,
1236 	u_int32 addr32,
1237 	sockaddr_u *addr
1238 	)
1239 {
1240 	register char *cp;
1241 	register const char *cq;
1242 	char buffer[200];
1243 
1244 	cp = buffer;
1245 	cq = tag;
1246 	while (*cq != '\0')
1247 		*cp++ = *cq++;
1248 
1249 	*cp++ = '=';
1250 	if (NULL == addr)
1251 		cq = numtoa(addr32);
1252 	else
1253 		cq = stoa(addr);
1254 	NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1255 	snprintf(cp, sizeof(buffer) - (cp - buffer), "%s", cq);
1256 	cp += strlen(cp);
1257 	ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
1258 }
1259 
1260 
1261 /*
1262  * ctl_putrefid - send a u_int32 refid as printable text
1263  */
1264 static void
1265 ctl_putrefid(
1266 	const char *	tag,
1267 	u_int32		refid
1268 	)
1269 {
1270 	char	output[16];
1271 	char *	optr;
1272 	char *	oplim;
1273 	char *	iptr;
1274 	char *	iplim;
1275 	char *	past_eq;
1276 
1277 	optr = output;
1278 	oplim = output + sizeof(output);
1279 	while (optr < oplim && '\0' != *tag)
1280 		*optr++ = *tag++;
1281 	if (optr < oplim) {
1282 		*optr++ = '=';
1283 		past_eq = optr;
1284 	}
1285 	if (!(optr < oplim))
1286 		return;
1287 	iptr = (char *)&refid;
1288 	iplim = iptr + sizeof(refid);
1289 	for ( ; optr < oplim && iptr < iplim && '\0' != *iptr;
1290 	     iptr++, optr++)
1291 		if (isprint((int)*iptr))
1292 			*optr = *iptr;
1293 		else
1294 			*optr = '.';
1295 	if (!(optr <= oplim))
1296 		optr = past_eq;
1297 	ctl_putdata(output, (u_int)(optr - output), FALSE);
1298 }
1299 
1300 
1301 /*
1302  * ctl_putarray - write a tagged eight element double array into the response
1303  */
1304 static void
1305 ctl_putarray(
1306 	const char *tag,
1307 	double *arr,
1308 	int start
1309 	)
1310 {
1311 	register char *cp;
1312 	register const char *cq;
1313 	char buffer[200];
1314 	int i;
1315 	cp = buffer;
1316 	cq = tag;
1317 	while (*cq != '\0')
1318 		*cp++ = *cq++;
1319 	i = start;
1320 	do {
1321 		if (i == 0)
1322 			i = NTP_SHIFT;
1323 		i--;
1324 		NTP_INSIST((cp - buffer) < (int)sizeof(buffer));
1325 		snprintf(cp, sizeof(buffer) - (cp - buffer),
1326 			 " %.2f", arr[i] * 1e3);
1327 		cp += strlen(cp);
1328 	} while(i != start);
1329 	ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
1330 }
1331 
1332 
1333 /*
1334  * ctl_putsys - output a system variable
1335  */
1336 static void
1337 ctl_putsys(
1338 	int varid
1339 	)
1340 {
1341 	l_fp tmp;
1342 	char str[256];
1343 #ifdef OPENSSL
1344 	struct cert_info *cp;
1345 	char cbuf[256];
1346 #endif /* OPENSSL */
1347 
1348 	switch (varid) {
1349 
1350 	    case CS_LEAP:
1351 		ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
1352 		break;
1353 
1354 	    case CS_STRATUM:
1355 		ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
1356 		break;
1357 
1358 	    case CS_PRECISION:
1359 		ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
1360 		break;
1361 
1362 	    case CS_ROOTDELAY:
1363 		ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
1364 			   1e3);
1365 		break;
1366 
1367 	    case CS_ROOTDISPERSION:
1368 		ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
1369 			   sys_rootdisp * 1e3);
1370 		break;
1371 
1372 	    case CS_REFID:
1373 		if (sys_stratum > 1 && sys_stratum < STRATUM_UNSPEC)
1374 			ctl_putadr(sys_var[varid].text, sys_refid, NULL);
1375 		else
1376 			ctl_putrefid(sys_var[varid].text, sys_refid);
1377 		break;
1378 
1379 	    case CS_REFTIME:
1380 		ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
1381 		break;
1382 
1383 	    case CS_POLL:
1384 		ctl_putuint(sys_var[CS_POLL].text, sys_poll);
1385 		break;
1386 
1387 	    case CS_PEERID:
1388 		if (sys_peer == NULL)
1389 			ctl_putuint(sys_var[CS_PEERID].text, 0);
1390 		else
1391 			ctl_putuint(sys_var[CS_PEERID].text,
1392 				    sys_peer->associd);
1393 		break;
1394 
1395 	    case CS_OFFSET:
1396 		ctl_putdbl(sys_var[CS_OFFSET].text, last_offset * 1e3);
1397 		break;
1398 
1399 	    case CS_DRIFT:
1400 		ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
1401 		break;
1402 
1403 	    case CS_JITTER:
1404 		ctl_putdbl(sys_var[CS_JITTER].text, sys_jitter * 1e3);
1405 		break;
1406 
1407 	    case CS_ERROR:
1408 		ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
1409 		break;
1410 
1411 	    case CS_CLOCK:
1412 		get_systime(&tmp);
1413 		ctl_putts(sys_var[CS_CLOCK].text, &tmp);
1414 		break;
1415 
1416 	    case CS_PROCESSOR:
1417 #ifndef HAVE_UNAME
1418 		ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
1419 			   sizeof(str_processor) - 1);
1420 #else
1421 		ctl_putstr(sys_var[CS_PROCESSOR].text,
1422 			   utsnamebuf.machine, strlen(utsnamebuf.machine));
1423 #endif /* HAVE_UNAME */
1424 		break;
1425 
1426 	    case CS_SYSTEM:
1427 #ifndef HAVE_UNAME
1428 		ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
1429 			   sizeof(str_system) - 1);
1430 #else
1431 		snprintf(str, sizeof(str), "%s/%s", utsnamebuf.sysname,
1432 			 utsnamebuf.release);
1433 		ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
1434 #endif /* HAVE_UNAME */
1435 		break;
1436 
1437 	    case CS_VERSION:
1438 		ctl_putstr(sys_var[CS_VERSION].text, Version,
1439 			   strlen(Version));
1440 		break;
1441 
1442 	    case CS_STABIL:
1443 		ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
1444 			   1e6);
1445 		break;
1446 
1447 	    case CS_VARLIST:
1448 	    {
1449 		    char buf[CTL_MAX_DATA_LEN];
1450 		    register char *s, *t, *be;
1451 		    register const char *ss;
1452 		    register int i;
1453 		    register struct ctl_var *k;
1454 
1455 		    s = buf;
1456 		    be = buf + sizeof(buf);
1457 		    if (s + strlen(sys_var[CS_VARLIST].text) + 4 > be)
1458 			    break;	/* really long var name */
1459 
1460 		    snprintf(s, sizeof(buf), "%s=\"",
1461 			sys_var[CS_VARLIST].text);
1462 		    s += strlen(s);
1463 		    t = s;
1464 		    for (k = sys_var; !(k->flags & EOV); k++) {
1465 			    if (k->flags & PADDING)
1466 				    continue;
1467 			    i = strlen(k->text);
1468 			    if (s+i+1 >= be)
1469 				    break;
1470 
1471 			    if (s != t)
1472 				    *s++ = ',';
1473 			    memcpy(s, k->text, i);
1474 			    s += i;
1475 		    }
1476 
1477 		    for (k = ext_sys_var; k && !(k->flags & EOV);
1478 			 k++) {
1479 			    if (k->flags & PADDING)
1480 				    continue;
1481 
1482 			    ss = k->text;
1483 			    if (!ss)
1484 				    continue;
1485 
1486 			    while (*ss && *ss != '=')
1487 				    ss++;
1488 			    i = ss - k->text;
1489 			    if (s + i + 1 >= be)
1490 				    break;
1491 
1492 			    if (s != t)
1493 				    *s++ = ',';
1494 			    memcpy(s, k->text,
1495 				    (unsigned)i);
1496 			    s += i;
1497 		    }
1498 		    if (s+2 >= be)
1499 			    break;
1500 
1501 		    *s++ = '"';
1502 		    *s = '\0';
1503 
1504 		    ctl_putdata(buf, (unsigned)( s - buf ),
1505 			0);
1506 	    }
1507 	    break;
1508 
1509 	    case CS_TAI:
1510 		if (sys_tai > 0)
1511 			ctl_putuint(sys_var[CS_TAI].text, sys_tai);
1512 		break;
1513 
1514 	    case CS_LEAPTAB:
1515 		if (leap_sec > 0)
1516 			ctl_putfs(sys_var[CS_LEAPTAB].text,
1517 			    leap_sec);
1518 		break;
1519 
1520 	    case CS_LEAPEND:
1521 		if (leap_expire > 0)
1522 			ctl_putfs(sys_var[CS_LEAPEND].text,
1523 			    leap_expire);
1524 		break;
1525 
1526 	    case CS_RATE:
1527 		ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll);
1528 		break;
1529 
1530 #ifdef OPENSSL
1531 	    case CS_FLAGS:
1532 		if (crypto_flags)
1533 			ctl_puthex(sys_var[CS_FLAGS].text,
1534 			    crypto_flags);
1535 		break;
1536 
1537 	    case CS_DIGEST:
1538 		if (crypto_flags) {
1539 			strcpy(str, OBJ_nid2ln(crypto_nid));
1540 			ctl_putstr(sys_var[CS_DIGEST].text, str,
1541 			    strlen(str));
1542 		}
1543 		break;
1544 
1545 	    case CS_SIGNATURE:
1546 		if (crypto_flags) {
1547 			const EVP_MD *dp;
1548 
1549 			dp = EVP_get_digestbynid(crypto_flags >> 16);
1550 			strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
1551 			ctl_putstr(sys_var[CS_SIGNATURE].text, str,
1552 			    strlen(str));
1553 		}
1554 		break;
1555 
1556 	    case CS_HOST:
1557 		if (sys_hostname != NULL)
1558 			ctl_putstr(sys_var[CS_HOST].text, sys_hostname,
1559 			    strlen(sys_hostname));
1560 		break;
1561 
1562 	    case CS_GROUP:
1563 		if (sys_groupname != NULL)
1564 			ctl_putstr(sys_var[CS_GROUP].text, sys_groupname,
1565 			    strlen(sys_groupname));
1566 		break;
1567 
1568 	    case CS_CERTIF:
1569 		for (cp = cinfo; cp != NULL; cp = cp->link) {
1570 			snprintf(cbuf, sizeof(cbuf), "%s %s 0x%x",
1571 			    cp->subject, cp->issuer, cp->flags);
1572 			ctl_putstr(sys_var[CS_CERTIF].text, cbuf,
1573 			    strlen(cbuf));
1574 			ctl_putfs(sys_var[CS_REVTIME].text, cp->last);
1575 		}
1576 		break;
1577 
1578 	    case CS_PUBLIC:
1579 		if (hostval.tstamp != 0)
1580 			ctl_putfs(sys_var[CS_PUBLIC].text,
1581 			    ntohl(hostval.tstamp));
1582 		break;
1583 #endif /* OPENSSL */
1584 	}
1585 }
1586 
1587 
1588 /*
1589  * ctl_putpeer - output a peer variable
1590  */
1591 static void
1592 ctl_putpeer(
1593 	int varid,
1594 	struct peer *peer
1595 	)
1596 {
1597 	int temp;
1598 #ifdef OPENSSL
1599 	char str[256];
1600 	struct autokey *ap;
1601 #endif /* OPENSSL */
1602 
1603 	switch (varid) {
1604 
1605 	    case CP_CONFIG:
1606 		ctl_putuint(peer_var[CP_CONFIG].text,
1607 		    (unsigned)((peer->flags & FLAG_PREEMPT) == 0));
1608 		break;
1609 
1610 	    case CP_AUTHENABLE:
1611 		ctl_putuint(peer_var[CP_AUTHENABLE].text,
1612 		    (unsigned)(peer->keyid != 0));
1613 		break;
1614 
1615 	    case CP_AUTHENTIC:
1616 		ctl_putuint(peer_var[CP_AUTHENTIC].text,
1617 		    (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0));
1618 		break;
1619 
1620 	    case CP_SRCADR:
1621 		ctl_putadr(peer_var[CP_SRCADR].text, 0,
1622 		    &peer->srcadr);
1623 		break;
1624 
1625 	    case CP_SRCPORT:
1626 		ctl_putuint(peer_var[CP_SRCPORT].text,
1627 		    ntohs(((struct sockaddr_in*)&peer->srcadr)->sin_port));
1628 		break;
1629 
1630 	    case CP_DSTADR:
1631 		if (peer->dstadr) {
1632 			ctl_putadr(peer_var[CP_DSTADR].text, 0,
1633 				   &(peer->dstadr->sin));
1634 		} else {
1635 			ctl_putadr(peer_var[CP_DSTADR].text, 0,
1636 				   NULL);
1637 		}
1638 		break;
1639 
1640 	    case CP_DSTPORT:
1641 		ctl_putuint(peer_var[CP_DSTPORT].text,
1642 		    (u_long)(peer->dstadr ?
1643 		    ntohs(((struct sockaddr_in*)&peer->dstadr->sin)->sin_port) : 0));
1644 		break;
1645 
1646 	    case CP_IN:
1647 		if (peer->r21 > 0)
1648 			ctl_putdbl(peer_var[CP_IN].text,
1649 				   peer->r21 / 1e3);
1650 		break;
1651 
1652 	    case CP_OUT:
1653 		if (peer->r34 >0)
1654 			ctl_putdbl(peer_var[CP_OUT].text,
1655 				   peer->r34 / 1e3);
1656 		break;
1657 
1658 	    case CP_RATE:
1659 		ctl_putuint(peer_var[CP_RATE].text, peer->throttle);
1660 		break;
1661 
1662 	    case CP_LEAP:
1663 		ctl_putuint(peer_var[CP_LEAP].text, peer->leap);
1664 		break;
1665 
1666 	    case CP_HMODE:
1667 		ctl_putuint(peer_var[CP_HMODE].text, peer->hmode);
1668 		break;
1669 
1670 	    case CP_STRATUM:
1671 		ctl_putuint(peer_var[CP_STRATUM].text, peer->stratum);
1672 		break;
1673 
1674 	    case CP_PPOLL:
1675 		ctl_putuint(peer_var[CP_PPOLL].text, peer->ppoll);
1676 		break;
1677 
1678 	    case CP_HPOLL:
1679 		ctl_putuint(peer_var[CP_HPOLL].text, peer->hpoll);
1680 		break;
1681 
1682 	    case CP_PRECISION:
1683 		ctl_putint(peer_var[CP_PRECISION].text,
1684 			peer->precision);
1685 		break;
1686 
1687 	    case CP_ROOTDELAY:
1688 		ctl_putdbl(peer_var[CP_ROOTDELAY].text,
1689 			   peer->rootdelay * 1e3);
1690 		break;
1691 
1692 	    case CP_ROOTDISPERSION:
1693 		ctl_putdbl(peer_var[CP_ROOTDISPERSION].text,
1694 			   peer->rootdisp * 1e3);
1695 		break;
1696 
1697 	    case CP_REFID:
1698 #ifdef REFCLOCK
1699 		if (peer->flags & FLAG_REFCLOCK) {
1700 			ctl_putrefid(peer_var[varid].text, peer->refid);
1701 			break;
1702 		}
1703 #endif
1704 		if (peer->stratum > 1 && peer->stratum < STRATUM_UNSPEC)
1705 			ctl_putadr(peer_var[varid].text, peer->refid,
1706 				   NULL);
1707 		else
1708 			ctl_putrefid(peer_var[varid].text, peer->refid);
1709 		break;
1710 
1711 	    case CP_REFTIME:
1712 		ctl_putts(peer_var[CP_REFTIME].text, &peer->reftime);
1713 		break;
1714 
1715 	    case CP_ORG:
1716 		ctl_putts(peer_var[CP_ORG].text, &peer->aorg);
1717 		break;
1718 
1719 	    case CP_REC:
1720 		ctl_putts(peer_var[CP_REC].text, &peer->dst);
1721 		break;
1722 
1723 	    case CP_XMT:
1724 		if (peer->xleave != 0)
1725 			ctl_putdbl(peer_var[CP_XMT].text, peer->xleave *
1726 			    1e3);
1727 		break;
1728 
1729 	    case CP_BIAS:
1730 		if (peer->bias != 0)
1731 			ctl_putdbl(peer_var[CP_BIAS].text, peer->bias *
1732 			    1e3);
1733 		break;
1734 
1735 	    case CP_REACH:
1736 		ctl_puthex(peer_var[CP_REACH].text, peer->reach);
1737 		break;
1738 
1739 	    case CP_FLASH:
1740 		temp = peer->flash;
1741 		ctl_puthex(peer_var[CP_FLASH].text, temp);
1742 		break;
1743 
1744 	    case CP_TTL:
1745 		if (peer->ttl > 0)
1746 			ctl_putint(peer_var[CP_TTL].text,
1747 			    sys_ttl[peer->ttl]);
1748 		break;
1749 
1750 	    case CP_UNREACH:
1751 		ctl_putuint(peer_var[CP_UNREACH].text, peer->unreach);
1752 		break;
1753 
1754 	    case CP_TIMER:
1755 		ctl_putuint(peer_var[CP_TIMER].text,
1756 		    peer->nextdate - current_time);
1757 		break;
1758 
1759 	    case CP_DELAY:
1760 		ctl_putdbl(peer_var[CP_DELAY].text, peer->delay * 1e3);
1761 		break;
1762 
1763 	    case CP_OFFSET:
1764 		ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset *
1765 		   1e3);
1766 		break;
1767 
1768 	    case CP_JITTER:
1769 		ctl_putdbl(peer_var[CP_JITTER].text, peer->jitter *
1770 		    1e3);
1771 		break;
1772 
1773 	    case CP_DISPERSION:
1774 		ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp *
1775 		   1e3);
1776 		break;
1777 
1778 	    case CP_KEYID:
1779 		if (peer->keyid > NTP_MAXKEY)
1780 			ctl_puthex(peer_var[CP_KEYID].text,
1781 			    peer->keyid);
1782 		else
1783 			ctl_putuint(peer_var[CP_KEYID].text,
1784 			    peer->keyid);
1785 		break;
1786 
1787 	    case CP_FILTDELAY:
1788 		ctl_putarray(peer_var[CP_FILTDELAY].text,
1789 		    peer->filter_delay, (int)peer->filter_nextpt);
1790 		break;
1791 
1792 	    case CP_FILTOFFSET:
1793 		ctl_putarray(peer_var[CP_FILTOFFSET].text,
1794 		    peer->filter_offset, (int)peer->filter_nextpt);
1795 		break;
1796 
1797 	    case CP_FILTERROR:
1798 		ctl_putarray(peer_var[CP_FILTERROR].text,
1799 		    peer->filter_disp, (int)peer->filter_nextpt);
1800 		break;
1801 
1802 	    case CP_PMODE:
1803 		ctl_putuint(peer_var[CP_PMODE].text, peer->pmode);
1804 		break;
1805 
1806 	    case CP_RECEIVED:
1807 		ctl_putuint(peer_var[CP_RECEIVED].text, peer->received);
1808 		break;
1809 
1810 	    case CP_SENT:
1811 		ctl_putuint(peer_var[CP_SENT].text, peer->sent);
1812 		break;
1813 
1814 	    case CP_VARLIST:
1815 	    {
1816 		    char buf[CTL_MAX_DATA_LEN];
1817 		    register char *s, *t, *be;
1818 		    register int i;
1819 		    register struct ctl_var *k;
1820 
1821 		    s = buf;
1822 		    be = buf + sizeof(buf);
1823 		    if (s + strlen(peer_var[CP_VARLIST].text) + 4 > be)
1824 			    break;	/* really long var name */
1825 
1826 		    snprintf(s, sizeof(buf), "%s=\"",
1827 			peer_var[CP_VARLIST].text);
1828 		    s += strlen(s);
1829 		    t = s;
1830 		    for (k = peer_var; !(k->flags & EOV); k++) {
1831 			    if (k->flags & PADDING)
1832 				    continue;
1833 
1834 			    i = strlen(k->text);
1835 			    if (s + i + 1 >= be)
1836 				    break;
1837 
1838 			    if (s != t)
1839 				    *s++ = ',';
1840 			    memcpy(s, k->text, i);
1841 			    s += i;
1842 		    }
1843 		    if (s+2 >= be)
1844 			    break;
1845 
1846 		    *s++ = '"';
1847 		    *s = '\0';
1848 		    ctl_putdata(buf, (unsigned)(s - buf), 0);
1849 	    }
1850 	    break;
1851 #ifdef OPENSSL
1852 	    case CP_FLAGS:
1853 		if (peer->crypto)
1854 			ctl_puthex(peer_var[CP_FLAGS].text, peer->crypto);
1855 		break;
1856 
1857 	    case CP_SIGNATURE:
1858 		if (peer->crypto) {
1859 			const EVP_MD *dp;
1860 
1861 			dp = EVP_get_digestbynid(peer->crypto >> 16);
1862 			strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
1863 			ctl_putstr(peer_var[CP_SIGNATURE].text, str,
1864 			    strlen(str));
1865 		}
1866 		break;
1867 
1868 	    case CP_HOST:
1869 		if (peer->subject != NULL)
1870 			ctl_putstr(peer_var[CP_HOST].text,
1871 			    peer->subject, strlen(peer->subject));
1872 		break;
1873 
1874 	    case CP_VALID:		/* not used */
1875 		break;
1876 
1877 	    case CP_INITSEQ:
1878 		if ((ap = (struct autokey *)peer->recval.ptr) == NULL)
1879 			break;
1880 
1881 		ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
1882 		ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
1883 		ctl_putfs(peer_var[CP_INITTSP].text,
1884 			  ntohl(peer->recval.tstamp));
1885 		break;
1886 #endif /* OPENSSL */
1887 	}
1888 }
1889 
1890 
1891 #ifdef REFCLOCK
1892 /*
1893  * ctl_putclock - output clock variables
1894  */
1895 static void
1896 ctl_putclock(
1897 	int varid,
1898 	struct refclockstat *clock_stat,
1899 	int mustput
1900 	)
1901 {
1902 	switch(varid) {
1903 
1904 	    case CC_TYPE:
1905 		if (mustput || clock_stat->clockdesc == NULL
1906 		    || *(clock_stat->clockdesc) == '\0') {
1907 			ctl_putuint(clock_var[CC_TYPE].text, clock_stat->type);
1908 		}
1909 		break;
1910 	    case CC_TIMECODE:
1911 		ctl_putstr(clock_var[CC_TIMECODE].text,
1912 			   clock_stat->p_lastcode,
1913 			   (unsigned)clock_stat->lencode);
1914 		break;
1915 
1916 	    case CC_POLL:
1917 		ctl_putuint(clock_var[CC_POLL].text, clock_stat->polls);
1918 		break;
1919 
1920 	    case CC_NOREPLY:
1921 		ctl_putuint(clock_var[CC_NOREPLY].text,
1922 			    clock_stat->noresponse);
1923 		break;
1924 
1925 	    case CC_BADFORMAT:
1926 		ctl_putuint(clock_var[CC_BADFORMAT].text,
1927 			    clock_stat->badformat);
1928 		break;
1929 
1930 	    case CC_BADDATA:
1931 		ctl_putuint(clock_var[CC_BADDATA].text,
1932 			    clock_stat->baddata);
1933 		break;
1934 
1935 	    case CC_FUDGETIME1:
1936 		if (mustput || (clock_stat->haveflags & CLK_HAVETIME1))
1937 			ctl_putdbl(clock_var[CC_FUDGETIME1].text,
1938 				   clock_stat->fudgetime1 * 1e3);
1939 		break;
1940 
1941 	    case CC_FUDGETIME2:
1942 		if (mustput || (clock_stat->haveflags & CLK_HAVETIME2))
1943 			ctl_putdbl(clock_var[CC_FUDGETIME2].text,
1944 				   clock_stat->fudgetime2 * 1e3);
1945 		break;
1946 
1947 	    case CC_FUDGEVAL1:
1948 		if (mustput || (clock_stat->haveflags & CLK_HAVEVAL1))
1949 			ctl_putint(clock_var[CC_FUDGEVAL1].text,
1950 				   clock_stat->fudgeval1);
1951 		break;
1952 
1953 	    case CC_FUDGEVAL2:
1954 		if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) {
1955 			if (clock_stat->fudgeval1 > 1)
1956 				ctl_putadr(clock_var[CC_FUDGEVAL2].text,
1957 					   clock_stat->fudgeval2, NULL);
1958 			else
1959 				ctl_putrefid(clock_var[CC_FUDGEVAL2].text,
1960 					     clock_stat->fudgeval2);
1961 		}
1962 		break;
1963 
1964 	    case CC_FLAGS:
1965 		if (mustput || (clock_stat->haveflags &	(CLK_HAVEFLAG1 |
1966 							 CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4)))
1967 			ctl_putuint(clock_var[CC_FLAGS].text,
1968 				    clock_stat->flags);
1969 		break;
1970 
1971 	    case CC_DEVICE:
1972 		if (clock_stat->clockdesc == NULL ||
1973 		    *(clock_stat->clockdesc) == '\0') {
1974 			if (mustput)
1975 				ctl_putstr(clock_var[CC_DEVICE].text,
1976 					   "", 0);
1977 		} else {
1978 			ctl_putstr(clock_var[CC_DEVICE].text,
1979 				   clock_stat->clockdesc,
1980 				   strlen(clock_stat->clockdesc));
1981 		}
1982 		break;
1983 
1984 	    case CC_VARLIST:
1985 	    {
1986 		    char buf[CTL_MAX_DATA_LEN];
1987 		    register char *s, *t, *be;
1988 		    register const char *ss;
1989 		    register int i;
1990 		    register struct ctl_var *k;
1991 
1992 		    s = buf;
1993 		    be = buf + sizeof(buf);
1994 		    if (s + strlen(clock_var[CC_VARLIST].text) + 4 >
1995 			be)
1996 			    break;	/* really long var name */
1997 
1998 		    snprintf(s, sizeof(buf), "%s=\"",
1999 		        clock_var[CC_VARLIST].text);
2000 		    s += strlen(s);
2001 		    t = s;
2002 
2003 		    for (k = clock_var; !(k->flags & EOV); k++) {
2004 			    if (k->flags & PADDING)
2005 				    continue;
2006 
2007 			    i = strlen(k->text);
2008 			    if (s + i + 1 >= be)
2009 				    break;
2010 
2011 			    if (s != t)
2012 				    *s++ = ',';
2013 			    memcpy(s, k->text, i);
2014 			    s += i;
2015 		    }
2016 
2017 		    for (k = clock_stat->kv_list; k && !(k->flags &
2018 							 EOV); k++) {
2019 			    if (k->flags & PADDING)
2020 				    continue;
2021 
2022 			    ss = k->text;
2023 			    if (!ss)
2024 				    continue;
2025 
2026 			    while (*ss && *ss != '=')
2027 				    ss++;
2028 			    i = ss - k->text;
2029 			    if (s+i+1 >= be)
2030 				    break;
2031 
2032 			    if (s != t)
2033 				    *s++ = ',';
2034 			    memcpy(s, k->text, (unsigned)i);
2035 			    s += i;
2036 			    *s = '\0';
2037 		    }
2038 		    if (s+2 >= be)
2039 			    break;
2040 
2041 		    *s++ = '"';
2042 		    *s = '\0';
2043 		    ctl_putdata(buf, (unsigned)( s - buf ), 0);
2044 	    }
2045 	    break;
2046 	}
2047 }
2048 #endif
2049 
2050 
2051 
2052 /*
2053  * ctl_getitem - get the next data item from the incoming packet
2054  */
2055 static struct ctl_var *
2056 ctl_getitem(
2057 	struct ctl_var *var_list,
2058 	char **data
2059 	)
2060 {
2061 	register struct ctl_var *v;
2062 	register char *cp, *dp;
2063 	register const char *tp;
2064 	static struct ctl_var eol = { 0, EOV, NULL };
2065 	static char buf[128];
2066 
2067 	/*
2068 	 * Delete leading commas and white space
2069 	 */
2070 	while (reqpt < reqend && (*reqpt == ',' ||
2071 				  isspace((unsigned char)*reqpt)))
2072 		reqpt++;
2073 	if (reqpt >= reqend)
2074 		return (0);
2075 
2076 	if (var_list == (struct ctl_var *)0)
2077 		return (&eol);
2078 
2079 	/*
2080 	 * Look for a first character match on the tag.  If we find
2081 	 * one, see if it is a full match.
2082 	 */
2083 	v = var_list;
2084 	cp = reqpt;
2085 	while (!(v->flags & EOV)) {
2086 		if (!(v->flags & PADDING) && *cp == *(v->text)) {
2087 			tp = v->text;
2088 			while (*tp != '\0' && *tp != '=' && cp <
2089 			       reqend && *cp == *tp) {
2090 				cp++;
2091 				tp++;
2092 			}
2093 			if ((*tp == '\0') || (*tp == '=')) {
2094 				while (cp < reqend && isspace((unsigned char)*cp))
2095 					cp++;
2096 				if (cp == reqend || *cp == ',') {
2097 					buf[0] = '\0';
2098 					*data = buf;
2099 					if (cp < reqend)
2100 						cp++;
2101 					reqpt = cp;
2102 					return v;
2103 				}
2104 				if (*cp == '=') {
2105 					cp++;
2106 					dp = buf;
2107 					while (cp < reqend && isspace((unsigned char)*cp))
2108 						cp++;
2109 					while (cp < reqend && *cp != ',') {
2110 						*dp++ = *cp++;
2111 						if (dp >= buf + sizeof(buf)) {
2112 							ctl_error(CERR_BADFMT);
2113 							numctlbadpkts++;
2114 #if 0	/* Avoid possible DOS attack */
2115 /* If we get a smarter msyslog we can re-enable this */
2116 							msyslog(LOG_WARNING,
2117 								"Possible 'ntpdx' exploit from %s:%d (possibly spoofed)\n",
2118 								stoa(rmt_addr), SRCPORT(rmt_addr)
2119 								);
2120 #endif
2121 							return (0);
2122 						}
2123 					}
2124 					if (cp < reqend)
2125 						cp++;
2126 					*dp-- = '\0';
2127 					while (dp >= buf) {
2128 						if (!isspace((unsigned int)(*dp)))
2129 							break;
2130 						*dp-- = '\0';
2131 					}
2132 					reqpt = cp;
2133 					*data = buf;
2134 					return (v);
2135 				}
2136 			}
2137 			cp = reqpt;
2138 		}
2139 		v++;
2140 	}
2141 	return v;
2142 }
2143 
2144 
2145 /*
2146  * control_unspec - response to an unspecified op-code
2147  */
2148 /*ARGSUSED*/
2149 static void
2150 control_unspec(
2151 	struct recvbuf *rbufp,
2152 	int restrict_mask
2153 	)
2154 {
2155 	struct peer *peer;
2156 
2157 	/*
2158 	 * What is an appropriate response to an unspecified op-code?
2159 	 * I return no errors and no data, unless a specified assocation
2160 	 * doesn't exist.
2161 	 */
2162 	if (res_associd != 0) {
2163 		if ((peer = findpeerbyassoc(res_associd)) == 0) {
2164 			ctl_error(CERR_BADASSOC);
2165 			return;
2166 		}
2167 		rpkt.status = htons(ctlpeerstatus(peer));
2168 	} else {
2169 		rpkt.status = htons(ctlsysstatus());
2170 	}
2171 	ctl_flushpkt(0);
2172 }
2173 
2174 
2175 /*
2176  * read_status - return either a list of associd's, or a particular
2177  * peer's status.
2178  */
2179 /*ARGSUSED*/
2180 static void
2181 read_status(
2182 	struct recvbuf *rbufp,
2183 	int restrict_mask
2184 	)
2185 {
2186 	register int i;
2187 	register struct peer *peer;
2188 	u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)];
2189 
2190 #ifdef DEBUG
2191 	if (debug > 2)
2192 		printf("read_status: ID %d\n", res_associd);
2193 #endif
2194 	/*
2195 	 * Two choices here. If the specified association ID is
2196 	 * zero we return all known assocation ID's.  Otherwise
2197 	 * we return a bunch of stuff about the particular peer.
2198 	 */
2199 	if (res_associd == 0) {
2200 		register int n;
2201 
2202 		n = 0;
2203 		rpkt.status = htons(ctlsysstatus());
2204 		for (i = 0; i < NTP_HASH_SIZE; i++) {
2205 			for (peer = assoc_hash[i]; peer != 0;
2206 			     peer = peer->ass_next) {
2207 				ass_stat[n++] = htons(peer->associd);
2208 				ass_stat[n++] =
2209 				    htons(ctlpeerstatus(peer));
2210 				if (n ==
2211 				    CTL_MAX_DATA_LEN/sizeof(u_short)) {
2212 					ctl_putdata((char *)ass_stat,
2213 						    n * sizeof(u_short), 1);
2214 					n = 0;
2215 				}
2216 			}
2217 		}
2218 
2219 		if (n != 0)
2220 			ctl_putdata((char *)ass_stat, n *
2221 				    sizeof(u_short), 1);
2222 		ctl_flushpkt(0);
2223 	} else {
2224 		peer = findpeerbyassoc(res_associd);
2225 		if (peer == 0) {
2226 			ctl_error(CERR_BADASSOC);
2227 		} else {
2228 			register u_char *cp;
2229 
2230 			rpkt.status = htons(ctlpeerstatus(peer));
2231 			if (res_authokay)
2232 				peer->num_events = 0;
2233 			/*
2234 			 * For now, output everything we know about the
2235 			 * peer. May be more selective later.
2236 			 */
2237 			for (cp = def_peer_var; *cp != 0; cp++)
2238 				ctl_putpeer((int)*cp, peer);
2239 			ctl_flushpkt(0);
2240 		}
2241 	}
2242 }
2243 
2244 
2245 /*
2246  * read_variables - return the variables the caller asks for
2247  */
2248 /*ARGSUSED*/
2249 static void
2250 read_variables(
2251 	struct recvbuf *rbufp,
2252 	int restrict_mask
2253 	)
2254 {
2255 	register struct ctl_var *v;
2256 	register int i;
2257 	char *valuep;
2258 	u_char *wants;
2259 	unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE +
2260 							   1) : (CP_MAXCODE + 1);
2261 	if (res_associd == 0) {
2262 		/*
2263 		 * Wants system variables. Figure out which he wants
2264 		 * and give them to him.
2265 		 */
2266 		rpkt.status = htons(ctlsysstatus());
2267 		if (res_authokay)
2268 			ctl_sys_num_events = 0;
2269 		gotvar += count_var(ext_sys_var);
2270 		wants = (u_char *)emalloc(gotvar);
2271 		memset((char *)wants, 0, gotvar);
2272 		gotvar = 0;
2273 		while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
2274 			if (v->flags & EOV) {
2275 				if ((v = ctl_getitem(ext_sys_var,
2276 						     &valuep)) != 0) {
2277 					if (v->flags & EOV) {
2278 						ctl_error(CERR_UNKNOWNVAR);
2279 						free((char *)wants);
2280 						return;
2281 					}
2282 					wants[CS_MAXCODE + 1 +
2283 					      v->code] = 1;
2284 					gotvar = 1;
2285 					continue;
2286 				} else {
2287 					break; /* shouldn't happen ! */
2288 				}
2289 			}
2290 			wants[v->code] = 1;
2291 			gotvar = 1;
2292 		}
2293 		if (gotvar) {
2294 			for (i = 1; i <= CS_MAXCODE; i++)
2295 				if (wants[i])
2296 					ctl_putsys(i);
2297 			for (i = 0; ext_sys_var &&
2298 				 !(ext_sys_var[i].flags & EOV); i++)
2299 				if (wants[i + CS_MAXCODE + 1])
2300 					ctl_putdata(ext_sys_var[i].text,
2301 						    strlen(ext_sys_var[i].text),
2302 						    0);
2303 		} else {
2304 			register u_char *cs;
2305 			register struct ctl_var *kv;
2306 
2307 			for (cs = def_sys_var; *cs != 0; cs++)
2308 				ctl_putsys((int)*cs);
2309 			for (kv = ext_sys_var; kv && !(kv->flags & EOV);
2310 			     kv++)
2311 				if (kv->flags & DEF)
2312 					ctl_putdata(kv->text,
2313 						    strlen(kv->text), 0);
2314 		}
2315 		free((char *)wants);
2316 	} else {
2317 		register struct peer *peer;
2318 
2319 		/*
2320 		 * Wants info for a particular peer. See if we know
2321 		 * the guy.
2322 		 */
2323 		peer = findpeerbyassoc(res_associd);
2324 		if (peer == 0) {
2325 			ctl_error(CERR_BADASSOC);
2326 			return;
2327 		}
2328 		rpkt.status = htons(ctlpeerstatus(peer));
2329 		if (res_authokay)
2330 			peer->num_events = 0;
2331 		wants = (u_char *)emalloc(gotvar);
2332 		memset((char*)wants, 0, gotvar);
2333 		gotvar = 0;
2334 		while ((v = ctl_getitem(peer_var, &valuep)) != 0) {
2335 			if (v->flags & EOV) {
2336 				ctl_error(CERR_UNKNOWNVAR);
2337 				free((char *)wants);
2338 				return;
2339 			}
2340 			wants[v->code] = 1;
2341 			gotvar = 1;
2342 		}
2343 		if (gotvar) {
2344 			for (i = 1; i <= CP_MAXCODE; i++)
2345 				if (wants[i])
2346 					ctl_putpeer(i, peer);
2347 		} else {
2348 			register u_char *cp;
2349 
2350 			for (cp = def_peer_var; *cp != 0; cp++)
2351 				ctl_putpeer((int)*cp, peer);
2352 		}
2353 		free((char *)wants);
2354 	}
2355 	ctl_flushpkt(0);
2356 }
2357 
2358 
2359 /*
2360  * write_variables - write into variables. We only allow leap bit
2361  * writing this way.
2362  */
2363 /*ARGSUSED*/
2364 static void
2365 write_variables(
2366 	struct recvbuf *rbufp,
2367 	int restrict_mask
2368 	)
2369 {
2370 	register struct ctl_var *v;
2371 	register int ext_var;
2372 	char *valuep;
2373 	long val = 0;
2374 
2375 	/*
2376 	 * If he's trying to write into a peer tell him no way
2377 	 */
2378 	if (res_associd != 0) {
2379 		ctl_error(CERR_PERMISSION);
2380 		return;
2381 	}
2382 
2383 	/*
2384 	 * Set status
2385 	 */
2386 	rpkt.status = htons(ctlsysstatus());
2387 
2388 	/*
2389 	 * Look through the variables. Dump out at the first sign of
2390 	 * trouble.
2391 	 */
2392 	while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
2393 		ext_var = 0;
2394 		if (v->flags & EOV) {
2395 			if ((v = ctl_getitem(ext_sys_var, &valuep)) !=
2396 			    0) {
2397 				if (v->flags & EOV) {
2398 					ctl_error(CERR_UNKNOWNVAR);
2399 					return;
2400 				}
2401 				ext_var = 1;
2402 			} else {
2403 				break;
2404 			}
2405 		}
2406 		if (!(v->flags & CAN_WRITE)) {
2407 			ctl_error(CERR_PERMISSION);
2408 			return;
2409 		}
2410 		if (!ext_var && (*valuep == '\0' || !atoint(valuep,
2411 							    &val))) {
2412 			ctl_error(CERR_BADFMT);
2413 			return;
2414 		}
2415 		if (!ext_var && (val & ~LEAP_NOTINSYNC) != 0) {
2416 			ctl_error(CERR_BADVALUE);
2417 			return;
2418 		}
2419 
2420 		if (ext_var) {
2421 			char *s = (char *)emalloc(strlen(v->text) +
2422 						  strlen(valuep) + 2);
2423 			const char *t;
2424 			char *tt = s;
2425 
2426 			t = v->text;
2427 			while (*t && *t != '=')
2428 				*tt++ = *t++;
2429 
2430 			*tt++ = '=';
2431 			strcat(tt, valuep);
2432 			set_sys_var(s, strlen(s)+1, v->flags);
2433 			free(s);
2434 		} else {
2435 			/*
2436 			 * This one seems sane. Save it.
2437 			 */
2438 			switch(v->code) {
2439 
2440 			    case CS_LEAP:
2441 			    default:
2442 				ctl_error(CERR_UNSPEC); /* really */
2443 				return;
2444 			}
2445 		}
2446 	}
2447 
2448 	/*
2449 	 * If we got anything, do it. xxx nothing to do ***
2450 	 */
2451 	/*
2452 	  if (leapind != ~0 || leapwarn != ~0) {
2453 	  if (!leap_setleap((int)leapind, (int)leapwarn)) {
2454 	  ctl_error(CERR_PERMISSION);
2455 	  return;
2456 	  }
2457 	  }
2458 	*/
2459 	ctl_flushpkt(0);
2460 }
2461 
2462 /*
2463  * configure() processes ntpq :config/config-from-file, allowing
2464  *		generic runtime reconfiguration.
2465  */
2466 static void configure(
2467 	struct recvbuf *rbufp,
2468 	int restrict_mask
2469 	)
2470 {
2471 	size_t data_count;
2472 	int retval;
2473 	int replace_nl;
2474 
2475 	/* I haven't yet implemented changes to an existing association.
2476 	 * Hence check if the association id is 0
2477 	 */
2478 	if (res_associd != 0) {
2479 		ctl_error(CERR_BADVALUE);
2480 		return;
2481 	}
2482 
2483 	if (restrict_mask & RES_NOMODIFY) {
2484 		snprintf(remote_config.err_msg,
2485 			 sizeof(remote_config.err_msg),
2486 			 "runtime configuration prohibited by restrict ... nomodify");
2487 		ctl_putdata(remote_config.err_msg,
2488 			    strlen(remote_config.err_msg), 0);
2489 		ctl_flushpkt(0);
2490 		msyslog(LOG_NOTICE,
2491 			"runtime config from %s rejected due to nomodify restriction",
2492 			stoa(&rbufp->recv_srcadr));
2493 		return;
2494 	}
2495 
2496 	/* Initialize the remote config buffer */
2497 	data_count = reqend - reqpt;
2498 	memcpy(remote_config.buffer, reqpt, data_count);
2499 	if (data_count > 0
2500 	    && '\n' != remote_config.buffer[data_count - 1])
2501 		remote_config.buffer[data_count++] = '\n';
2502 	remote_config.buffer[data_count] = '\0';
2503 	remote_config.pos = 0;
2504 	remote_config.err_pos = 0;
2505 	remote_config.no_errors = 0;
2506 
2507 	/* do not include terminating newline in log */
2508 	if (data_count > 0
2509 	    && '\n' == remote_config.buffer[data_count - 1]) {
2510 		remote_config.buffer[data_count - 1] = '\0';
2511 		replace_nl = 1;
2512 	} else
2513 		replace_nl = 0;
2514 
2515 	DPRINTF(1, ("Got Remote Configuration Command: %s\n",
2516 		remote_config.buffer));
2517 	msyslog(LOG_NOTICE, "%s config: %s",
2518 		stoa(&rbufp->recv_srcadr),
2519 		remote_config.buffer);
2520 
2521 	if (replace_nl)
2522 		remote_config.buffer[data_count - 1] = '\n';
2523 
2524 	config_remotely(&rbufp->recv_srcadr);
2525 
2526 	/*
2527 	 * Check if errors were reported. If not, output 'Config
2528 	 * Succeeded'.  Else output the error count.  It would be nice
2529 	 * to output any parser error messages.
2530 	 */
2531 	if (0 == remote_config.no_errors) {
2532 		retval = snprintf(remote_config.err_msg,
2533 				  sizeof(remote_config.err_msg),
2534 				  "Config Succeeded");
2535 		if (retval > 0)
2536 			remote_config.err_pos += retval;
2537 	}
2538 
2539 	ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0);
2540 	ctl_flushpkt(0);
2541 
2542 	DPRINTF(1, ("Reply: %s\n", remote_config.err_msg));
2543 
2544 	if (remote_config.no_errors > 0)
2545 		msyslog(LOG_NOTICE, "%d error in %s config",
2546 			remote_config.no_errors,
2547 			stoa(&rbufp->recv_srcadr));
2548 }
2549 
2550 
2551 /*
2552  * read_clock_status - return clock radio status
2553  */
2554 /*ARGSUSED*/
2555 static void
2556 read_clock_status(
2557 	struct recvbuf *rbufp,
2558 	int restrict_mask
2559 	)
2560 {
2561 #ifndef REFCLOCK
2562 	/*
2563 	 * If no refclock support, no data to return
2564 	 */
2565 	ctl_error(CERR_BADASSOC);
2566 #else
2567 	register struct ctl_var *v;
2568 	register int i;
2569 	register struct peer *peer;
2570 	char *valuep;
2571 	u_char *wants;
2572 	unsigned int gotvar;
2573 	struct refclockstat clock_stat;
2574 
2575 	if (res_associd == 0) {
2576 
2577 		/*
2578 		 * Find a clock for this jerk.	If the system peer
2579 		 * is a clock use it, else search the hash tables
2580 		 * for one.
2581 		 */
2582 		if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK))
2583 		{
2584 			peer = sys_peer;
2585 		} else {
2586 			peer = 0;
2587 			for (i = 0; peer == 0 && i < NTP_HASH_SIZE; i++) {
2588 				for (peer = assoc_hash[i]; peer != 0;
2589 				     peer = peer->ass_next) {
2590 					if (peer->flags & FLAG_REFCLOCK)
2591 						break;
2592 				}
2593 			}
2594 			if (peer == 0) {
2595 				ctl_error(CERR_BADASSOC);
2596 				return;
2597 			}
2598 		}
2599 	} else {
2600 		peer = findpeerbyassoc(res_associd);
2601 		if (peer == 0 || !(peer->flags & FLAG_REFCLOCK)) {
2602 			ctl_error(CERR_BADASSOC);
2603 			return;
2604 		}
2605 	}
2606 
2607 	/*
2608 	 * If we got here we have a peer which is a clock. Get his
2609 	 * status.
2610 	 */
2611 	clock_stat.kv_list = (struct ctl_var *)0;
2612 	refclock_control(&peer->srcadr, (struct refclockstat *)0,
2613 			 &clock_stat);
2614 
2615 	/*
2616 	 * Look for variables in the packet.
2617 	 */
2618 	rpkt.status = htons(ctlclkstatus(&clock_stat));
2619 	gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list);
2620 	wants = (u_char *)emalloc(gotvar);
2621 	memset((char*)wants, 0, gotvar);
2622 	gotvar = 0;
2623 	while ((v = ctl_getitem(clock_var, &valuep)) != 0) {
2624 		if (v->flags & EOV) {
2625 			if ((v = ctl_getitem(clock_stat.kv_list,
2626 					     &valuep)) != 0) {
2627 				if (v->flags & EOV) {
2628 					ctl_error(CERR_UNKNOWNVAR);
2629 					free((char*)wants);
2630 					free_varlist(clock_stat.kv_list);
2631 					return;
2632 				}
2633 				wants[CC_MAXCODE + 1 + v->code] = 1;
2634 				gotvar = 1;
2635 				continue;
2636 			} else {
2637 				break; /* shouldn't happen ! */
2638 			}
2639 		}
2640 		wants[v->code] = 1;
2641 		gotvar = 1;
2642 	}
2643 
2644 	if (gotvar) {
2645 		for (i = 1; i <= CC_MAXCODE; i++)
2646 			if (wants[i])
2647 				ctl_putclock(i, &clock_stat, 1);
2648 		for (i = 0; clock_stat.kv_list &&
2649 			 !(clock_stat.kv_list[i].flags & EOV); i++)
2650 			if (wants[i + CC_MAXCODE + 1])
2651 				ctl_putdata(clock_stat.kv_list[i].text,
2652 					    strlen(clock_stat.kv_list[i].text),
2653 					    0);
2654 	} else {
2655 		register u_char *cc;
2656 		register struct ctl_var *kv;
2657 
2658 		for (cc = def_clock_var; *cc != 0; cc++)
2659 			ctl_putclock((int)*cc, &clock_stat, 0);
2660 		for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV);
2661 		     kv++)
2662 			if (kv->flags & DEF)
2663 				ctl_putdata(kv->text, strlen(kv->text),
2664 					    0);
2665 	}
2666 
2667 	free((char*)wants);
2668 	free_varlist(clock_stat.kv_list);
2669 
2670 	ctl_flushpkt(0);
2671 #endif
2672 }
2673 
2674 
2675 /*
2676  * write_clock_status - we don't do this
2677  */
2678 /*ARGSUSED*/
2679 static void
2680 write_clock_status(
2681 	struct recvbuf *rbufp,
2682 	int restrict_mask
2683 	)
2684 {
2685 	ctl_error(CERR_PERMISSION);
2686 }
2687 
2688 /*
2689  * Trap support from here on down. We send async trap messages when the
2690  * upper levels report trouble. Traps can by set either by control
2691  * messages or by configuration.
2692  */
2693 /*
2694  * set_trap - set a trap in response to a control message
2695  */
2696 static void
2697 set_trap(
2698 	struct recvbuf *rbufp,
2699 	int restrict_mask
2700 	)
2701 {
2702 	int traptype;
2703 
2704 	/*
2705 	 * See if this guy is allowed
2706 	 */
2707 	if (restrict_mask & RES_NOTRAP) {
2708 		ctl_error(CERR_PERMISSION);
2709 		return;
2710 	}
2711 
2712 	/*
2713 	 * Determine his allowed trap type.
2714 	 */
2715 	traptype = TRAP_TYPE_PRIO;
2716 	if (restrict_mask & RES_LPTRAP)
2717 		traptype = TRAP_TYPE_NONPRIO;
2718 
2719 	/*
2720 	 * Call ctlsettrap() to do the work.  Return
2721 	 * an error if it can't assign the trap.
2722 	 */
2723 	if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
2724 			(int)res_version))
2725 		ctl_error(CERR_NORESOURCE);
2726 	ctl_flushpkt(0);
2727 }
2728 
2729 
2730 /*
2731  * unset_trap - unset a trap in response to a control message
2732  */
2733 static void
2734 unset_trap(
2735 	struct recvbuf *rbufp,
2736 	int restrict_mask
2737 	)
2738 {
2739 	int traptype;
2740 
2741 	/*
2742 	 * We don't prevent anyone from removing his own trap unless the
2743 	 * trap is configured. Note we also must be aware of the
2744 	 * possibility that restriction flags were changed since this
2745 	 * guy last set his trap. Set the trap type based on this.
2746 	 */
2747 	traptype = TRAP_TYPE_PRIO;
2748 	if (restrict_mask & RES_LPTRAP)
2749 		traptype = TRAP_TYPE_NONPRIO;
2750 
2751 	/*
2752 	 * Call ctlclrtrap() to clear this out.
2753 	 */
2754 	if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
2755 		ctl_error(CERR_BADASSOC);
2756 	ctl_flushpkt(0);
2757 }
2758 
2759 
2760 /*
2761  * ctlsettrap - called to set a trap
2762  */
2763 int
2764 ctlsettrap(
2765 	sockaddr_u *raddr,
2766 	struct interface *linter,
2767 	int traptype,
2768 	int version
2769 	)
2770 {
2771 	register struct ctl_trap *tp;
2772 	register struct ctl_trap *tptouse;
2773 
2774 	/*
2775 	 * See if we can find this trap.  If so, we only need update
2776 	 * the flags and the time.
2777 	 */
2778 	if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
2779 		switch (traptype) {
2780 
2781 		    case TRAP_TYPE_CONFIG:
2782 			tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
2783 			break;
2784 
2785 		    case TRAP_TYPE_PRIO:
2786 			if (tp->tr_flags & TRAP_CONFIGURED)
2787 				return (1); /* don't change anything */
2788 			tp->tr_flags = TRAP_INUSE;
2789 			break;
2790 
2791 		    case TRAP_TYPE_NONPRIO:
2792 			if (tp->tr_flags & TRAP_CONFIGURED)
2793 				return (1); /* don't change anything */
2794 			tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
2795 			break;
2796 		}
2797 		tp->tr_settime = current_time;
2798 		tp->tr_resets++;
2799 		return (1);
2800 	}
2801 
2802 	/*
2803 	 * First we heard of this guy.	Try to find a trap structure
2804 	 * for him to use, clearing out lesser priority guys if we
2805 	 * have to. Clear out anyone who's expired while we're at it.
2806 	 */
2807 	tptouse = NULL;
2808 	for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
2809 		if ((tp->tr_flags & TRAP_INUSE) &&
2810 		    !(tp->tr_flags & TRAP_CONFIGURED) &&
2811 		    ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
2812 			tp->tr_flags = 0;
2813 			num_ctl_traps--;
2814 		}
2815 		if (!(tp->tr_flags & TRAP_INUSE)) {
2816 			tptouse = tp;
2817 		} else if (!(tp->tr_flags & TRAP_CONFIGURED)) {
2818 			switch (traptype) {
2819 
2820 			    case TRAP_TYPE_CONFIG:
2821 				if (tptouse == NULL) {
2822 					tptouse = tp;
2823 					break;
2824 				}
2825 				if (tptouse->tr_flags & TRAP_NONPRIO &&
2826 				    !(tp->tr_flags & TRAP_NONPRIO))
2827 					break;
2828 
2829 				if (!(tptouse->tr_flags & TRAP_NONPRIO)
2830 				    && tp->tr_flags & TRAP_NONPRIO) {
2831 					tptouse = tp;
2832 					break;
2833 				}
2834 				if (tptouse->tr_origtime <
2835 				    tp->tr_origtime)
2836 					tptouse = tp;
2837 				break;
2838 
2839 			    case TRAP_TYPE_PRIO:
2840 				if (tp->tr_flags & TRAP_NONPRIO) {
2841 					if (tptouse == NULL ||
2842 					    (tptouse->tr_flags &
2843 					     TRAP_INUSE &&
2844 					     tptouse->tr_origtime <
2845 					     tp->tr_origtime))
2846 						tptouse = tp;
2847 				}
2848 				break;
2849 
2850 			    case TRAP_TYPE_NONPRIO:
2851 				break;
2852 			}
2853 		}
2854 	}
2855 
2856 	/*
2857 	 * If we don't have room for him return an error.
2858 	 */
2859 	if (tptouse == NULL)
2860 		return (0);
2861 
2862 	/*
2863 	 * Set up this structure for him.
2864 	 */
2865 	tptouse->tr_settime = tptouse->tr_origtime = current_time;
2866 	tptouse->tr_count = tptouse->tr_resets = 0;
2867 	tptouse->tr_sequence = 1;
2868 	tptouse->tr_addr = *raddr;
2869 	tptouse->tr_localaddr = linter;
2870 	tptouse->tr_version = (u_char) version;
2871 	tptouse->tr_flags = TRAP_INUSE;
2872 	if (traptype == TRAP_TYPE_CONFIG)
2873 		tptouse->tr_flags |= TRAP_CONFIGURED;
2874 	else if (traptype == TRAP_TYPE_NONPRIO)
2875 		tptouse->tr_flags |= TRAP_NONPRIO;
2876 	num_ctl_traps++;
2877 	return (1);
2878 }
2879 
2880 
2881 /*
2882  * ctlclrtrap - called to clear a trap
2883  */
2884 int
2885 ctlclrtrap(
2886 	sockaddr_u *raddr,
2887 	struct interface *linter,
2888 	int traptype
2889 	)
2890 {
2891 	register struct ctl_trap *tp;
2892 
2893 	if ((tp = ctlfindtrap(raddr, linter)) == NULL)
2894 		return (0);
2895 
2896 	if (tp->tr_flags & TRAP_CONFIGURED
2897 	    && traptype != TRAP_TYPE_CONFIG)
2898 		return (0);
2899 
2900 	tp->tr_flags = 0;
2901 	num_ctl_traps--;
2902 	return (1);
2903 }
2904 
2905 
2906 /*
2907  * ctlfindtrap - find a trap given the remote and local addresses
2908  */
2909 static struct ctl_trap *
2910 ctlfindtrap(
2911 	sockaddr_u *raddr,
2912 	struct interface *linter
2913 	)
2914 {
2915 	register struct ctl_trap *tp;
2916 
2917 	for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
2918 		if ((tp->tr_flags & TRAP_INUSE)
2919 		    && (NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr))
2920 		    && SOCK_EQ(raddr, &tp->tr_addr)
2921 	 	    && (linter == tp->tr_localaddr) )
2922 			return (tp);
2923 	}
2924 	return (struct ctl_trap *)NULL;
2925 }
2926 
2927 
2928 /*
2929  * report_event - report an event to the trappers
2930  */
2931 void
2932 report_event(
2933 	int	err,		/* error code */
2934 	struct peer *peer,	/* peer structure pointer */
2935 	const char *str		/* protostats string */
2936 	)
2937 {
2938 	char	statstr[NTP_MAXSTRLEN];
2939 	int	i;
2940 	size_t	len;
2941 
2942 	/*
2943 	 * Report the error to the protostats file, system log and
2944 	 * trappers.
2945 	 */
2946 	if (peer == NULL) {
2947 
2948 		/*
2949 		 * Discard a system report if the number of reports of
2950 		 * the same type exceeds the maximum.
2951 		 */
2952 		if (ctl_sys_last_event != (u_char)err)
2953 			ctl_sys_num_events= 0;
2954 		if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS)
2955 			return;
2956 
2957 		ctl_sys_last_event = (u_char)err;
2958 		ctl_sys_num_events++;
2959 		snprintf(statstr, NTP_MAXSTRLEN,
2960 		    "0.0.0.0 %04x %02x %s",
2961 		    ctlsysstatus(), err, eventstr(err));
2962 		if (str != NULL) {
2963 			len = strlen(statstr);
2964 			snprintf(statstr + len, sizeof(statstr) - len,
2965 			    " %s", str);
2966 		}
2967 		NLOG(NLOG_SYSEVENT)
2968 		    msyslog(LOG_INFO, "%s", statstr);
2969 	} else {
2970 
2971 		/*
2972 		 * Discard a peer report if the number of reports of
2973 		 * the same type exceeds the maximum for that peer.
2974 		 */
2975 		char	*src;
2976 		u_char	errlast;
2977 
2978 		errlast = (u_char)err & ~PEER_EVENT;
2979 		if (peer->last_event == errlast)
2980 			peer->num_events = 0;
2981 		if (peer->num_events >= CTL_PEER_MAXEVENTS)
2982 			return;
2983 
2984 		peer->last_event = errlast;
2985 		peer->num_events++;
2986 		if (ISREFCLOCKADR(&peer->srcadr))
2987 			src = refnumtoa(&peer->srcadr);
2988 		else
2989 			src = stoa(&peer->srcadr);
2990 
2991 		snprintf(statstr, NTP_MAXSTRLEN,
2992 		    "%s %04x %02x %s", src,
2993 		    ctlpeerstatus(peer), err, eventstr(err));
2994 		if (str != NULL) {
2995 			len = strlen(statstr);
2996 			snprintf(statstr + len, sizeof(statstr) - len,
2997 			    " %s", str);
2998 		}
2999 		NLOG(NLOG_PEEREVENT)
3000 		    msyslog(LOG_INFO, "%s", statstr);
3001 	}
3002 	record_proto_stats(statstr);
3003 #if DEBUG
3004 	if (debug)
3005 		printf("event at %lu %s\n", current_time, statstr);
3006 #endif
3007 
3008 	/*
3009 	 * If no trappers, return.
3010 	 */
3011 	if (num_ctl_traps <= 0)
3012 		return;
3013 
3014 	/*
3015 	 * Set up the outgoing packet variables
3016 	 */
3017 	res_opcode = CTL_OP_ASYNCMSG;
3018 	res_offset = 0;
3019 	res_async = 1;
3020 	res_authenticate = 0;
3021 	datapt = rpkt.data;
3022 	dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
3023 	if (!(err & PEER_EVENT)) {
3024 		rpkt.associd = 0;
3025 		rpkt.status = htons(ctlsysstatus());
3026 
3027 		/*
3028 		 * For now, put everything we know about system
3029 		 * variables. Don't send crypto strings.
3030 		 */
3031 		for (i = 1; i <= CS_MAXCODE; i++) {
3032 #ifdef OPENSSL
3033 			if (i > CS_VARLIST)
3034 				continue;
3035 #endif /* OPENSSL */
3036 			ctl_putsys(i);
3037 		}
3038 	} else {
3039 		NTP_INSIST(peer != NULL);
3040 		rpkt.associd = htons(peer->associd);
3041 		rpkt.status = htons(ctlpeerstatus(peer));
3042 
3043 		/*
3044 		 * Dump it all. Later, maybe less.
3045 		 */
3046 		for (i = 1; i <= CP_MAXCODE; i++) {
3047 #ifdef OPENSSL
3048 			if (i > CP_VARLIST)
3049 				continue;
3050 #endif /* OPENSSL */
3051 			ctl_putpeer(i, peer);
3052 		}
3053 #ifdef REFCLOCK
3054 		/*
3055 		 * for clock exception events: add clock variables to
3056 		 * reflect info on exception
3057 		 */
3058 		if (err == PEVNT_CLOCK) {
3059 			struct refclockstat clock_stat;
3060 			struct ctl_var *kv;
3061 
3062 			clock_stat.kv_list = (struct ctl_var *)0;
3063 			refclock_control(&peer->srcadr,
3064 					 (struct refclockstat *)0, &clock_stat);
3065 
3066 			ctl_puthex("refclockstatus",
3067 				   ctlclkstatus(&clock_stat));
3068 
3069 			for (i = 1; i <= CC_MAXCODE; i++)
3070 				ctl_putclock(i, &clock_stat, 0);
3071 			for (kv = clock_stat.kv_list; kv &&
3072 				 !(kv->flags & EOV); kv++)
3073 				if (kv->flags & DEF)
3074 					ctl_putdata(kv->text,
3075 						    strlen(kv->text), 0);
3076 			free_varlist(clock_stat.kv_list);
3077 		}
3078 #endif /* REFCLOCK */
3079 	}
3080 
3081 	/*
3082 	 * We're done, return.
3083 	 */
3084 	ctl_flushpkt(0);
3085 }
3086 
3087 
3088 /*
3089  * ctl_clr_stats - clear stat counters
3090  */
3091 void
3092 ctl_clr_stats(void)
3093 {
3094 	ctltimereset = current_time;
3095 	numctlreq = 0;
3096 	numctlbadpkts = 0;
3097 	numctlresponses = 0;
3098 	numctlfrags = 0;
3099 	numctlerrors = 0;
3100 	numctlfrags = 0;
3101 	numctltooshort = 0;
3102 	numctlinputresp = 0;
3103 	numctlinputfrag = 0;
3104 	numctlinputerr = 0;
3105 	numctlbadoffset = 0;
3106 	numctlbadversion = 0;
3107 	numctldatatooshort = 0;
3108 	numctlbadop = 0;
3109 	numasyncmsgs = 0;
3110 }
3111 
3112 static u_long
3113 count_var(
3114 	struct ctl_var *k
3115 	)
3116 {
3117 	register u_long c;
3118 
3119 	if (!k)
3120 		return (0);
3121 
3122 	c = 0;
3123 	while (!(k++->flags & EOV))
3124 		c++;
3125 	return (c);
3126 }
3127 
3128 char *
3129 add_var(
3130 	struct ctl_var **kv,
3131 	u_long size,
3132 	u_short def
3133 	)
3134 {
3135 	register u_long c;
3136 	register struct ctl_var *k;
3137 
3138 	c = count_var(*kv);
3139 
3140 	k = *kv;
3141 	*kv  = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var));
3142 	if (k) {
3143 		memmove((char *)*kv, (char *)k,
3144 			sizeof(struct ctl_var)*c);
3145 		free((char *)k);
3146 	}
3147 	(*kv)[c].code  = (u_short) c;
3148 	(*kv)[c].text  = (char *)emalloc(size);
3149 	(*kv)[c].flags = def;
3150 	(*kv)[c+1].code  = 0;
3151 	(*kv)[c+1].text  = (char *)0;
3152 	(*kv)[c+1].flags = EOV;
3153 	return (char *)(intptr_t)(*kv)[c].text;
3154 }
3155 
3156 void
3157 set_var(
3158 	struct ctl_var **kv,
3159 	const char *data,
3160 	u_long size,
3161 	u_short def
3162 	)
3163 {
3164 	register struct ctl_var *k;
3165 	register const char *s;
3166 	register const char *t;
3167 	char *td;
3168 
3169 	if (!data || !size)
3170 		return;
3171 
3172 	k = *kv;
3173 	if (k != NULL) {
3174 		while (!(k->flags & EOV)) {
3175 			s = data;
3176 			t = k->text;
3177 			if (t)	{
3178 				while (*t != '=' && *s - *t == 0) {
3179 					s++;
3180 					t++;
3181 				}
3182 				if (*s == *t && ((*t == '=') || !*t)) {
3183 					free((void *)(intptr_t)k->text);
3184 					td = (char *)emalloc(size);
3185 					memmove(td, data, size);
3186 					k->text =td;
3187 					k->flags = def;
3188 					return;
3189 				}
3190 			} else {
3191 				td = (char *)emalloc(size);
3192 				memmove(td, data, size);
3193 				k->text = td;
3194 				k->flags = def;
3195 				return;
3196 			}
3197 			k++;
3198 		}
3199 	}
3200 	td = add_var(kv, size, def);
3201 	memmove(td, data, size);
3202 }
3203 
3204 void
3205 set_sys_var(
3206 	const char *data,
3207 	u_long size,
3208 	u_short def
3209 	)
3210 {
3211 	set_var(&ext_sys_var, data, size, def);
3212 }
3213 
3214 void
3215 free_varlist(
3216 	struct ctl_var *kv
3217 	)
3218 {
3219 	struct ctl_var *k;
3220 	if (kv) {
3221 		for (k = kv; !(k->flags & EOV); k++)
3222 			free((void *)(intptr_t)k->text);
3223 		free((void *)kv);
3224 	}
3225 }
3226