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